forked from ku-eecs-capstone/lab2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.js
401 lines (346 loc) · 12 KB
/
server.js
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
express = require('express.io');
app = express();
app.http().io();
cookieParser = require('cookie-parser')
app.use(cookieParser())
var fs = require('fs');
var userFile = __dirname + '/test.json';
var campusFile = __dirname + '/campus.json';
fs.readFile(userFile, 'utf8', function (err, data) {
if (err) {
console.log('Error: ' + err);
return;
}
users = JSON.parse(data);
// remove the basketball from the user inventory if it was there.
for(var i in users){
for(var j in users[i].inventory){
if(users[i].inventory[j] == "basketball"){
users[i].inventory.splice(j, 1);
return;
}
}
}
});
fs.readFile(campusFile, 'utf8', function (err, data) {
if (err) {
console.log('Error: ' + err);
return;
}
campus = JSON.parse(data);
campus["allen-fieldhouse"].text = "Rock Chalk! You're at the field house.";
// check to see if basketball is at a location.
for(var i in campus){
for(var j in campus[i].what){
if(campus[i].what[j] == "basketball"){
return;
}
}
}
// put basketball back at fraser
campus["outside-fraser"].what.push("basketball");
});
function writeToFile(file, data){
var stream = fs.createWriteStream(file);
stream.once('open', function(fd) {
stream.write(JSON.stringify(data, null, "\t"));
stream.end();
});
}
/*
* SUMMARY: Saves the users' information and the campus' information into the files.
*/
function saveState(){
writeToFile(userFile, users);
writeToFile(campusFile, campus);
}
/*
* SUMMARY: Creates a new user with the userid and the default inventory and roomid.
*/
function createUser(userid){
users[userid] = { "userid": userid.toString(), "inventory": ["laptop"], "roomid": "strong-hall"};
saveState();
}
/*
* SUMMARY: Checks if the request has a userid cookie.
* It will create a new userid cookie and user within are system if not.
* PARA: (next): This is the next function/call that the current request matches in this app.
*/
function createCookieAndUser(req, res, next){
req.userid = req.cookies.userid;
if(req.userid == undefined){
req.userid = new Date().getTime() + Object.keys(users).length.toString();
}
if(users[req.userid] == undefined){
res.cookie("userid", req.userid, {maxAge: 1000*60*60*24*365})
createUser(req.userid);
}
next();
}
/*
* SUMMARY: will find other users that are currently at the roomid,
* which are not the same as the userid passed in.
* PARA: (roomid): The roomid of the room that needs the users from.
* PARA: (userid): The userid that needs to be ignored in the list.
* RETURN: Returns a list of other userid's at the roomid.
*/
function getOtherUsersAt(roomid, userid) {
var otherUsers = [];
for (var i in users) {
if (users[i].roomid == roomid && i != userid) {
otherUsers.push(users[i]);
}
}
return otherUsers;
}
/*
* SUMMARY: Any call to the app this function will be called first.
* This will ensure that the user always has a userid.
*/
app.use(createCookieAndUser);
app.get('/', function(req, res){
res.status(200);
res.sendfile(__dirname + "/index.html");
})
/*
* SUMMARY: Gets the information about the user.
* Will contain the users' inventory, userid, and location.
*/
app.get('/me', function(req, res){
if(users[req.userid] != undefined){
res.status(200);
res.send(users[req.userid]);
}
else {
res.status(404);
res.send('Failed to find the user');
}
})
/*
* SUMMARY: Gets a list of other users' at the same location as the user that is making the request.
*/
app.get('/otherUsers', function(req, res){
if(users[req.userid] != undefined){
res.status(200);
res.send(getOtherUsersAt(users[req.userid].roomid, req.userid));
}
else {
res.status(404);
res.send('Failed to find the user');
}
})
/*
* SUMMARY: Gets the users' inventory.
*/
app.get('/my-inventory', function(req, res){
if(users[req.userid] != undefined){
res.set({'Content-Type': 'application/json'});
res.status(200);
res.send(users[req.userid].inventory);
return;
}
else{
res.status(404);
res.send('Failed to find the user.');
}
})
/*
* SUMMARY: Gets the room information for the room with id passed in.
*/
app.get('/:room', function(req, res){
if(campus[req.params.room] != undefined){
res.set({'Content-Type': 'application/json'});
res.status(200);
res.send(campus[req.params.room]);
}
else{
res.status(404);
res.send('Failed to find the campus location');
}
})
/*
* SUMMARY: Gets the image file for room with name passed in.
*/
app.get('/images/:name', function(req, res){
res.status(200);
res.sendfile(__dirname + "/" + req.params.name);
});
/*
* SUMMARY: Will take the item from the room and place in in the users' inventory.
* PARA: (room): The room id that the item needs to be taken from.
* PARA: (item): The item that needs to be taken from the room.
*/
app.delete('/:room/:item', function(req, res){
if(campus[req.params.room] != undefined){
res.set({'Content-Type': 'application/json'});
var ix = -1;
if (campus[req.params.room].what != undefined) {
ix = campus[req.params.room].what.indexOf(req.params.item);
}
if (ix >= 0) {
res.status(200);
users[req.userid].inventory.push(campus[req.params.room].what[ix]); // stash
res.send(users[req.userid].inventory);
campus[req.params.room].what.splice(ix, 1); // room no longer has this
saveState();
return;
}
res.status(200);
res.send([]);
return;
}
res.status(404);
res.send("location not found");
})
/*
* SUMMARY: Will take the item from the fromUserid's inventory and place it in toUserid's inventory.
* PARA: (item) : Item that was being taken.
* PARA: (fromUserid): The userid of the user that the item was taken from.
* PARA: (toUserid)i : The userid of the user that the item is going to.
*/
app.delete('/:id/:item/:fromUserid/:toUserid', function(req, res){
if(users[req.params.fromUserid] == undefined || users[req.params.toUserid] == undefined){
res.status(404);
res.send("User couldn't be found");
return;
}
else {
var itemid = users[req.params.fromUserid].inventory.indexOf(req.params.item);
users[req.params.fromUserid].inventory.splice(itemid, 1);
users[req.params.toUserid].inventory.push(req.params.item);
saveState();
res.status(200);
res.send([]);
return;
}
});
/*
* SUMMARY: Will drop the item from this users' inventory and place in it this users' location.
*/
app.put('/drop/:item', function(req, res){
var room = users[req.userid].roomid;
if(campus[room]){
// Check you have this
var ix = users[req.userid].inventory.indexOf(req.params.item)
if (ix >= 0) {
dropbox(ix,campus[room], req.userid);
res.set({'Content-Type': 'application/json'});
saveState();
res.status(200);
res.send([]);
}
else {
res.status(404);
res.send("you do not have this");
}
return;
}
res.status(404);
res.send("location not found");
})
app.listen(3000);
var dropbox = function(ix,room, userid) {
var item = users[userid].inventory[ix];
users[userid].inventory.splice(ix, 1); // remove from inventory
if (room.id == 'allen-fieldhouse' && item == "basketball") {
room.text += " Someone found the ball so there is a game going on!";
return;
}
if (room.what == undefined) {
room.what = [];
}
room.what.push(item);
}
/*
* SUMMARY: Will change the roomid of the user with the userid passed in.
*/
function changeUserRoom(userid, room_name){
users[userid].roomid = room_name;
saveState();
}
/******************************************************************************
* SUMMARY: io events here are what handle the dynamic changing of the webpage.
*****************************************************************************/
/* SUMMARY:
* Will listen for the join-room event from the clients.
* Will remove the user from the room their at currently and put the user into the room specified.
* Will then broadcast to all users within both rooms that the room has changed and it will force the page to update.
*/
app.io.route('join-room', function(req){
if(users[req.data.userid] != undefined){
// Makes sure to not broadcast to the same room twice.
if(req.data.room != users[req.data.userid].roomid){
req.io.leave(users[req.data.userid].roomid);
app.io.room(users[req.data.userid].roomid).broadcast('myroom', 'Room has change. You should update.');
}
req.io.join(req.data.room);
changeUserRoom(req.data.userid, req.data.room);
app.io.room(req.data.room).broadcast('myroom', 'Room has changed. You should update.');
}
})
/* SUMMARY:
* Will listen for a room-change event from the clients.
* This function will broadcast to all other clients within the room to force it to update the page.
*/
app.io.route('room-change', function(req){
app.io.room(req.data.room).broadcast('myroom', 'Room has changed. You should update.');
})
// Users in the system.
var users = {};
// Campus information about each location (room).
var campus = {
"lied-center": { "id": "lied-center",
"where": "LiedCenter.jpg",
"next": {"east": "eaton-hall", "south": "dole-institute"},
"text": "You are outside the Lied Center."
},
"dole-institute": { "id": "dole-institute",
"where": "DoleInstituteofPolitics.jpg",
"next": {"east": "allen-fieldhouse", "north": "lied-center"},
"text": "You take in the view of the Dole Institute of Politics. This is the best part of your walk to Nichols Hall."
},
"eaton-hall": { "id": "eaton-hall",
"where": "EatonHall.jpg",
"next": {"east": "snow-hall", "south": "allen-fieldhouse", "west": "lied-center"},
"text": "You are outside Eaton Hall. You should recognize here."
},
"snow-hall": { "id": "snow-hall",
"where": "SnowHall.jpg",
"next": {"east": "strong-hall", "south": "ambler-recreation", "west": "eaton-hall"},
"text": "You are outside Snow Hall. Math class? Waiting for the bus?"
},
"strong-hall": { "id": "strong-hall",
"where": "StrongHall.jpg",
"next": {"east": "outside-fraser", "north": "memorial-stadium", "west": "snow-hall"},
"what": ["coffee"],
"text": "You are outside Stong Hall."
},
"ambler-recreation": { "id": "ambler-recreation",
"where": "AmblerRecreation.jpg",
"next": {"west": "allen-fieldhouse", "north": "snow-hall"},
"text": "It's the starting of the semester, and you feel motivated to be at the Gym. Let's see about that in 3 weeks."
},
"outside-fraser": { "id": "outside-fraser",
"where": "OutsideFraserHall.jpg",
"next": {"west": "strong-hall","north":"spencer-museum"},
"what": ["basketball"],
"text": "On your walk to the Kansas Union, you wish you had class outside."
},
"spencer-museum": { "id": "spencer-museum",
"where": "SpencerMuseum.jpg",
"next": {"south": "outside-fraser","west":"memorial-stadium"},
"what": ["art"],
"text": "You are at the Spencer Museum of Art."
},
"memorial-stadium": { "id": "memorial-stadium",
"where": "MemorialStadium.jpg",
"next": {"south": "strong-hall","east":"spencer-museum"},
"what": ["ku flag"],
"text": "Half the crowd is wearing KU Basketball gear at the football game."
},
"allen-fieldhouse": { "id": "allen-fieldhouse",
"where": "AllenFieldhouse.jpg",
"next": {"north": "eaton-hall","east": "ambler-recreation","west": "dole-institute"},
"text": "Rock Chalk! You're at the field house."
}
}