OSDN Git Service

mysql_poolクラスを別のファイルに分離した
[webchat/WebChat.git] / chat.js
1 $max_room_number = 3;        //最大ルーム数\r
2 $spilt_size = 1024 * 512;       //分割するサイズ\r
3 $reset_password_diff = 1000 * 60 * 60;  //ルームパスワードをリセットする間隔\r
4 $gc_time_interval = 1000 * 60 * 60;     //ゴミ掃除を行う間隔\r
5 $invaild_token_message = "トークンが一致しませんでした";\r
6 $block_message = "メッセージの送信に失敗しました";       //ブロック時のメッセージ\r
7 $not_match_password = "パスワードが一致しませんでした";  //パスワードが一致しない場合に表示されるメッセージ\r
8 $password_setted_message = "パスワードを設定しました";      //パスワードが設定されたときに表示されるメッセージ\r
9 $password_resetted_message = "パスワードをリセットしました";      //パスワードが再設定されたときに表示されるメッセージ\r
10 $failed_set_password_message = "パスワードの設定に失敗しました"; //パスワードが再設定されたときに表示されるメッセージ\r
11 $ip_ban_list_file_name = "ipbanlist.txt";       //アクセスを禁止するIPが記録されているファイル\r
12 $room_configure_file_name = "roomlist.txt";     //ルームの設定が記録されているファイル\r
13 $username = "admin";    //管理者用のページにアクセスできるユーザ名\r
14 $password = "admin";    //管理者用のページにアクセスするのに必要なパスワード\r
15 $system_name = "system";        //システム発言を表す名前\r
16 $log_directory = "log"; //ログファイルを置くフォルダー\r
17 $log_file_name = "logfile%d.txt";       //ログファイル名(%dはそのままにしておくこと)\r
18 $splited_log_file_name = "logfile%d_%s.txt"     //分割後のファイル名(%dと%sはそのままにしておくこと)\r
19 $pastlogfile_pattern = "logfile%d(_+.*)?\.txt"; //過去ログと判定する正規表現\r
20 \r
21 var lazy = require("./lazy.js");\r
22 var security = require("./security.js");\r
23 var fs = require("fs");\r
24 var async = require("async");\r
25 var path = require("path");\r
26 var util = require("util");\r
27 var cookie = require("express/node_modules/cookie");\r
28 var connectUtils = require("express/node_modules/connect/lib/utils");\r
29 \r
30 var clients = new Array();\r
31 \r
32 var sessionStore;\r
33 \r
34 module.exports = function(app,server,express,session){\r
35         sessionStore = session;\r
36         app.get("/chat", chat_proc);\r
37         app.all("/log/*",express.basicAuth(auth_proc));\r
38         app.get("/log/*",log_proc);\r
39         app.all("/admin_chat",express.basicAuth(auth_proc));\r
40         app.get("/admin_chat", adminchat_proc);\r
41         app.all("/admin",express.basicAuth(auth_proc));\r
42         app.get("/admin", admin_proc);\r
43         app.post("/admin",admin_postproc);\r
44 \r
45         var io = require("socket.io").listen(server);\r
46         io.configure("production", function(){\r
47                 io.enable("browser client minification");  // minified されたクライアントファイルを送信する\r
48         io.enable("browser client etag");          // バージョンによって etag によるキャッシングを有効にする\r
49         io.set("log level", 1);                    // ログレベルを設定(デフォルトより下げている)\r
50         });\r
51 \r
52         for(var i = 0; i < $max_room_number; i++)\r
53         {\r
54                 clients[i] =io\r
55                 .of(GetNameFromRoomNumber(i))\r
56                 .authorization(ParseAuthorization)\r
57                 .on("connection",ParseConnect);\r
58         }\r
59 };\r
60 \r
61 function chat_proc(req, res){\r
62         var info = new security.SessionInfomation(false);\r
63         req.session.items = info;\r
64 \r
65         var room_number = 0;\r
66         if(typeof(req.query.rno) != "undefined")\r
67                 room_number = req.query.rno;\r
68         res.render("chat",{rno:room_number,token:info.token});\r
69 }\r
70 \r
71 function auth_proc(user, pass) {\r
72         return user === $username && pass === $password;\r
73 }\r
74 \r
75 function log_proc(req, res) {\r
76         res.sendfile(__dirname + req.url);\r
77 }\r
78 \r
79 function adminchat_proc(req, res){\r
80         var info = new security.SessionInfomation(true);\r
81         req.session.items = info;\r
82 \r
83         var room_number = 0;\r
84         if(typeof(req.query.rno) != "undefined")\r
85                 room_number = req.query.rno;\r
86         res.render("chat",{rno:room_number,token:info.token});\r
87 }\r
88 \r
89 function admin_postproc(req,res){\r
90         if(req.session.items.token != req.body.token)\r
91         {\r
92                 res.send($invaild_token_message);\r
93                 return;\r
94         }\r
95         if(typeof(req.body.erase) != "undefined")\r
96         {\r
97                 removeLog(req.body.file,function(){\r
98                         res.redirect("/admin");\r
99                 });\r
100         }\r
101         if(typeof(req.body.registor) != "undefined")\r
102         {\r
103                 ipbanlist.Update(req.body.newbanlist,function(){\r
104                         res.redirect("/admin");\r
105                 });\r
106         }\r
107         if(typeof(req.body.updateroom) != "undefined")\r
108         {\r
109                 $rooms.Update(req.body.newroomlist,function(){\r
110                         res.redirect("/admin");\r
111                 });\r
112         }\r
113 }\r
114 \r
115 function admin_proc(req,res)\r
116 {\r
117         var info = new security.SessionInfomation(true);\r
118         req.session.items = info;\r
119         var iplist = ipbanlist.GetText();\r
120 \r
121         fs.readdir($log_directory,function(err,list){\r
122                 res.render("admin", {\r
123                         files: list,\r
124                         log_directory:$log_directory,\r
125                         ipbanlist:iplist,\r
126                         token:info.token,\r
127                         roomlist:$rooms.GetString()\r
128                 });\r
129         });\r
130 }\r
131 \r
132 function removeLog(files,callback)\r
133 {\r
134         if(typeof(files) == "undefined")\r
135         {\r
136                 if(typeof(callback) == "function")\r
137                         callback();\r
138                 return;\r
139         }\r
140 \r
141         async.map(files,\r
142         function(item,callback){\r
143                 fs.unlink($log_directory + "/" + item,callback);\r
144         },\r
145         function(err,results){\r
146                 if(typeof(callback) == "function")\r
147                         callback();\r
148         });\r
149 }\r
150 \r
151 //RoomInfomationCollecionクラス\r
152 function RoomInfomationCollection()\r
153 {\r
154         var collection = {};\r
155         this.Get = function(rno){\r
156                 return collection[rno];\r
157         }\r
158         this.IsContains = function(rno){\r
159                 return rno in collection;\r
160         };\r
161         this.GetString = function(){\r
162                 var retval = "";\r
163                 for(var rno in collection)\r
164                 {\r
165                         if($rooms.Get(rno).IsVolatile())\r
166                                 continue;\r
167                         var pass = collection[rno].password;\r
168                         if(pass == null)\r
169                                 pass = "";\r
170                         var hiddenlog = collection[rno].hiddenlog;\r
171                         retval += rno + ":" + pass + ":" + hiddenlog + "\r\n";\r
172                 }\r
173                 return retval;\r
174         };\r
175         this.GetKeys = function(){\r
176                 var retval = {};\r
177                 for(var rno in collection)\r
178                 {\r
179                         retval[rno] = {};\r
180                 }\r
181                 return retval;\r
182         }\r
183         this.Update = function(text,callfunc){\r
184                 async.waterfall([\r
185                         function(callback){\r
186                                 fs.open($room_configure_file_name,"w",callback);\r
187                         },\r
188                         function(fd,callback){\r
189                                 var buf = new Buffer(text);\r
190                                 fs.write(fd,buf,0,Buffer.byteLength(text),null,function(){\r
191                                         callback(null,fd);\r
192                                 });\r
193                         },\r
194                         function(fd,callback){\r
195                                 fs.close(fd,function(){\r
196                                         GetRoomList(callfunc);\r
197                                 });\r
198                         }\r
199                 ]);\r
200         }\r
201         function GetRoomList(callback){\r
202                 Clear();\r
203                 fs.exists($room_configure_file_name,function(exists){\r
204                         if(exists == false)\r
205                         {\r
206                                 if(typeof(callback) == "function")\r
207                                         callback();\r
208                                 return;\r
209                         }\r
210                         var stream = fs.createReadStream($room_configure_file_name);\r
211                         new lazy(stream)\r
212                                 .lines\r
213                                 .forEach(function(line){\r
214                                         var token = line.toString().replace(/(\r|\n|\r\n)/gm, "").split(":");\r
215                                         if(token.length == 1)\r
216                                         {\r
217                                                 Add(token[0],null,false);\r
218                                         }\r
219                                         else if(token.length == 2)\r
220                                         {\r
221                                                 var rno = token[0];\r
222                                                 var pass = token[1];\r
223                                                 if(pass == "")\r
224                                                         pass = null;\r
225                                                 Add(rno, pass,false);\r
226                                         }\r
227                                         else if(token.length == 3)\r
228                                         {\r
229                                                 var rno = token[0];\r
230                                                 var pass = token[1];\r
231                                                 if(pass == "")\r
232                                                         pass = null;\r
233                                                 var hiddenlog = false;\r
234                                                 if(token[2] == "true")\r
235                                                         hiddenlog = true;\r
236                                                 Add(rno, pass,hiddenlog);\r
237                                         }\r
238                                 })\r
239                                 .join(function(){\r
240                                         if(typeof(callback) == "function")\r
241                                                 callback();\r
242                                 });\r
243                 });\r
244         }\r
245         function Clear(){\r
246                 collection = {};\r
247                 for(var i = 0; i < $max_room_number; i++)\r
248                         Add(i,null,null);\r
249         };\r
250         function Add(rno,pass,hiddenlogflag){\r
251                 collection[rno] = new RoomInfomation(pass,hiddenlogflag);\r
252                 if(pass != null)\r
253                         collection[rno].owner = $system_name;\r
254         };\r
255         var $gc_interval_id = setInterval(function(){\r
256                 for(var rno in this.rom_list)\r
257                         collection[rno].GCRomList();\r
258         },$gc_time_interval);\r
259         GetRoomList();\r
260 }\r
261 \r
262 //RoomInfomationクラス\r
263 function RoomInfomation(pass,hiddenlogflag)\r
264 {\r
265         this.password = pass;\r
266         this.rom_list = {};\r
267         this.authed_list = {};\r
268         this.owner = null;\r
269         this.time = null;\r
270         this.hiddenlog = hiddenlogflag;\r
271         this.GetConfig = function(){\r
272                 var roomconfig = {};\r
273                 if(this.IsVolatile() == false)\r
274                 {\r
275                         if(this.IsFixedPassword())\r
276                                 roomconfig.type = 2;\r
277                         else if(this.IsHiddenLogFromRom())\r
278                                 roomconfig.type = 3;\r
279                         else\r
280                                 roomconfig.type = 1;\r
281                         roomconfig.IsOwned = !this.IsFirstAuth();\r
282                 }else{\r
283                         roomconfig.type = 0;\r
284                 }\r
285                 return roomconfig;\r
286         }\r
287         this.IsVolatile = function(){\r
288                 return this.owner == null &&\r
289                         this.password == null &&\r
290                         this.time == null &&\r
291                         this.hiddenlog == null;\r
292         }\r
293         this.GetRomCount = function(){\r
294                 var count = 0;\r
295                 for(var key in this.rom_list)\r
296                         count++;\r
297                 return count;\r
298         };\r
299         this.AddRom = function(ip){\r
300                 var date = new Date();\r
301                 this.rom_list[ip] = {time:date.getTime()};\r
302         };\r
303         this.RemoveRom = function(ip){\r
304                 delete this.rom_list[ip];\r
305         };\r
306         this.Reset = function(owner){\r
307                 var date = new Date();\r
308                 var time = date.getTime();\r
309                 this.password = null;\r
310                 this.authed_list = {};\r
311                 this.owner = owner;\r
312                 this.time = time;\r
313         };\r
314         this.IsFirstAuth = function(){\r
315                 return this.owner == null;\r
316         };\r
317         this.IsAuthed = function(name){\r
318                 return name == this.owner ||\r
319                         name in this.authed_list;\r
320         };\r
321         this.IsHiddenLogFromRom = function(){\r
322                 return this.hiddenlog;\r
323         };\r
324         this.IsFixedPassword = function(){\r
325                 return this.owner == $system_name;\r
326         };\r
327         this.IsOwner = function(name){\r
328                 return this.owner == name;\r
329         };\r
330         this.IsTimeout = function(){\r
331                 var date = new Date();\r
332                 var current_time = date.getTime();\r
333                 return !this.IsFixedPassword() &&\r
334                         current_time - this.time >= $reset_password_diff;\r
335         };\r
336         this.RemoveAuth = function(name)\r
337         {\r
338                 delete this.authed_list[name];\r
339         };\r
340         this.Auth = function(name,password){\r
341                 if(this.password != password)\r
342                         return false;\r
343                 var date = new Date();\r
344                 var time = date.getTime();\r
345                 this.time = time;\r
346                 this.authed_list[name] = "";\r
347                 return true;\r
348         };\r
349         this.SetPassword = function(owner,password){\r
350                 if(owner == this.owner &&\r
351                         !this.IsFixedPassword() &&\r
352                         !this.IsHiddenLogFromRom())\r
353                 {\r
354                         var date = new Date();\r
355                         this.time = date.getTime();\r
356                         this.password = password;\r
357                         return true;\r
358                 }\r
359                 return false;\r
360         };\r
361         this.GCRomList = function(){\r
362                 var date = new Date();\r
363                 var current_time = date.getTime();\r
364                 for(var ip in this.rom_list)\r
365                 {\r
366                         if(current_time - this.rom_list[ip].time >= $gc_time_interval)\r
367                                 delete this.rom_list[ip];\r
368                 }\r
369         };\r
370 }\r
371 \r
372 //IPBANクラス\r
373 function IpBanCollecion()\r
374 {\r
375         var collection = {};\r
376         this.IsBaned = function(ip){\r
377                 return collection[ip] == "r";\r
378         }\r
379         this.IsBlockedToWrite = function(ip){\r
380                 return ip in collection;\r
381         }\r
382         this.GetText = function(){\r
383                 var text = "";\r
384                 for(var key in collection)\r
385                 {\r
386                         if(collection[key] == "")\r
387                                 text += key + "\r\n";\r
388                         else\r
389                                 text += key + ":" + collection[key] + "\r\n";\r
390                 }\r
391                 return text;\r
392         }\r
393         this.Update = function(text,callfunc){\r
394                 async.waterfall([\r
395                         function(callback){\r
396                                 fs.open($ip_ban_list_file_name,"w",callback);\r
397                         },\r
398                         function(fd,callback){\r
399                                 var buf = new Buffer(text);\r
400                                 fs.write(fd,buf,0,Buffer.byteLength(text),null,function(){\r
401                                         callback(null,fd);\r
402                                 });\r
403                         },\r
404                         function(fd,callback){\r
405                                 fs.close(fd,function(){\r
406                                         GetIpBanList(callfunc);\r
407                                 });\r
408                         }\r
409                 ]);\r
410         }\r
411         function GetIpBanList(callback)\r
412         {\r
413                 collection = {};\r
414                 fs.exists($ip_ban_list_file_name,function(exists){\r
415                         if(exists == false)\r
416                         {\r
417                                 if(typeof(callback) == "function")\r
418                                         callback();\r
419                                 return;\r
420                         }\r
421                         var stream = fs.createReadStream($ip_ban_list_file_name);\r
422                         new lazy(stream)\r
423                                 .lines\r
424                                 .forEach(function(line){\r
425                                         var token = line.toString().replace(/(\r|\n|\r\n)/gm, "").split(":");\r
426                                         var ip = token[0];\r
427                                         if(token.length == 1)\r
428                                                 collection[ip] = "";\r
429                                         else\r
430                                                 collection[ip] = token[1];\r
431                                 })\r
432                                 .join(function(){\r
433                                         if(typeof(callback) == "function")\r
434                                                 callback();\r
435                                 });\r
436                 });\r
437         }\r
438         GetIpBanList();\r
439 }\r
440 \r
441 var ipbanlist = new IpBanCollecion();\r
442 var $rooms = new RoomInfomationCollection();\r
443 \r
444 createLogDirectory();\r
445 \r
446 function createLogDirectory()\r
447 {\r
448         fs.exists($log_directory,function(exists){\r
449                 if(exists == false)\r
450                         fs.mkdirSync($log_directory);\r
451         });\r
452 }\r
453 \r
454 function ParseConnect(socket)\r
455 {\r
456         var ip = GetClientIPAdress(socket);\r
457         console.log("connected from %s",ip);\r
458 \r
459         var rno = GetRoomNumberFromName(socket.namespace.name);\r
460 \r
461         var room = $rooms.Get(rno);\r
462 \r
463         room.AddRom(ip);\r
464 \r
465         var roomconfig = room.GetConfig();\r
466         roomconfig.admin = socket.handshake.admin;\r
467         socket.json.emit("send roominfo",roomconfig);\r
468 \r
469         var romcount = room.GetRomCount();\r
470         socket.json.emit("send romcount",romcount);\r
471         socket.json.broadcast.emit("send romcount",romcount);\r
472 \r
473         socket.on("get pastLogList", function (msg) {\r
474                 ParseGetPastLogList(socket,msg);\r
475         });\r
476         socket.on("get pastLog", function (msg) {\r
477                 ParseGetPastLog(socket,msg);\r
478         });\r
479         socket.on("join",function(msg){\r
480                 ParseJoin(socket,msg);\r
481         });\r
482         socket.on("quit",function(msg){\r
483                 ParseQuit(socket,msg);\r
484         });\r
485         socket.on("set password",function(msg){\r
486                 ParseSetPassword(socket,msg);\r
487         });\r
488         socket.on("send msg", function (msg) {\r
489                 ParseSendMsg(socket,msg);\r
490         });\r
491         socket.on("disconnect", function (msg) {\r
492                 ParseDisconnect(socket,msg);\r
493         });\r
494 }\r
495 \r
496 function ParseAuthorization(handshakeData, callback)\r
497 {\r
498         if(handshakeData.headers.cookie) {\r
499                 var signedCookie = cookie.parse(handshakeData.headers.cookie);\r
500                 var sessionID = connectUtils.parseSignedCookies(signedCookie, $secret)["connect.sid"];\r
501                 sessionStore.get(sessionID, function (err, session) {\r
502                         var result = null;\r
503                         if (ipbanlist.IsBaned(handshakeData.address.address))\r
504                                 result = "failed get from session store";\r
505                         else if(err)\r
506                                 result = err;\r
507                         else if(handshakeData.query.token != session.items.token)\r
508                                 result = "invaild token";\r
509                         if(typeof(session) != "undefined" && result == null)\r
510                         {\r
511                                 handshakeData.admin = session.items.admin;\r
512                                 handshakeData.sessionID = sessionID;\r
513                         }\r
514                         callback(result,result == null && !err);\r
515                 });\r
516         } else {\r
517                 return callback("failed get cookie", false);\r
518         }\r
519 }\r
520 \r
521 function ParseDisconnect(socket,msg)\r
522 {\r
523         var ip = GetClientIPAdress(socket);\r
524         var rno = GetRoomNumberFromName(socket.namespace.name);\r
525         $rooms.Get(rno).RemoveRom(ip);\r
526 \r
527         var romcount = $rooms.Get(rno).GetRomCount();\r
528         socket.json.emit("send romcount",romcount);\r
529         socket.json.broadcast.emit("send romcount",romcount);\r
530 \r
531         console.log("disconnected");\r
532 }\r
533 \r
534 function ParseSetPassword(socket,msg)\r
535 {\r
536         var rno = GetRoomNumberFromName(socket.namespace.name);\r
537         var newMeg = {\r
538                 name:$system_name,\r
539                 message:null,\r
540         };\r
541         if($rooms.Get(rno).IsVolatile() == false && $rooms.Get(rno).SetPassword(msg.owner,msg.password))\r
542                 newMeg.message = $password_setted_message;\r
543         else\r
544                 newMeg.message = $failed_set_password_message;\r
545         ParseSendMsg(socket,newMeg);\r
546 }\r
547 \r
548 function ParseJoin(socket,msg)\r
549 {\r
550         var ip = GetClientIPAdress(socket);\r
551 \r
552         if(ipbanlist.IsBlockedToWrite(ip))\r
553         {\r
554                 socket.emit("error",$block_message);\r
555                 return;\r
556         }\r
557 \r
558         var rno = GetRoomNumberFromName(socket.namespace.name);\r
559 \r
560         $rooms.Get(rno).RemoveRom(ip);\r
561         \r
562         var romcount = $rooms.Get(rno).GetRomCount();\r
563         socket.json.emit("send romcount",romcount);\r
564         socket.json.broadcast.emit("send romcount",romcount);\r
565 \r
566         if($rooms.Get(rno).IsVolatile() == false)\r
567         {\r
568                 if($rooms.Get(rno).IsTimeout() ||\r
569                         $rooms.Get(rno).IsFirstAuth())\r
570                 {\r
571                         $rooms.Get(rno).Reset(msg.name);\r
572                         ParseGetPastLog(socket,util.format($log_file_name,rno));\r
573                 }\r
574                 else if($rooms.Get(rno).Auth(msg.name,msg.password))\r
575                 {\r
576                         ParseGetPastLog(socket,util.format($log_file_name,rno));\r
577                 }\r
578                 else\r
579                 {\r
580                         socket.emit("error",$not_match_password);\r
581                         return;\r
582                 }\r
583         }\r
584 \r
585         var newMeg = {\r
586                 name:$system_name,\r
587                 message:util.format("/enteredby %s %s %s",msg.name,msg.color,msg.mailto),\r
588         };\r
589         ParseSendMsg(socket,newMeg);\r
590 }\r
591 \r
592 function ParseQuit(socket,msg)\r
593 {\r
594         var ip = GetClientIPAdress(socket);\r
595 \r
596         if(ipbanlist.IsBlockedToWrite(ip))\r
597         {\r
598                 socket.emit("error",$block_message);\r
599                 return;\r
600         }\r
601 \r
602         var rno = GetRoomNumberFromName(socket.namespace.name);\r
603 \r
604         var newMeg = {\r
605                 name:$system_name,\r
606                 message:$password_resetted_message,\r
607         };\r
608 \r
609         $rooms.Get(rno).AddRom(ip);\r
610 \r
611         var romcount = $rooms.Get(rno).GetRomCount();\r
612         socket.json.emit("send romcount",romcount);\r
613         socket.json.broadcast.emit("send romcount",romcount);\r
614 \r
615         if($rooms.Get(rno).IsVolatile() == false)\r
616         {\r
617                 if($rooms.Get(rno).IsOwner(msg.name))\r
618                 {\r
619                         $rooms.Get(rno).Reset(null);\r
620                         ParseSendMsg(socket,newMeg);\r
621                 }\r
622                 if(!$rooms.Get(rno).IsFirstAuth() &&\r
623                         !$rooms.Get(rno).IsAuthed(msg.name))\r
624                         return;\r
625                 else\r
626                         $rooms.Get(rno).RemoveAuth(msg.name);\r
627         }\r
628 \r
629         newMeg.message = util.format("/quitedby %s",msg.name);\r
630         ParseSendMsg(socket,newMeg);\r
631 }\r
632 \r
633 //socket 接続中のソケット\r
634 //msg msgクラス\r
635 function ParseSendMsg(socket,msg)\r
636 {\r
637         var ip = GetClientIPAdress(socket);\r
638 \r
639         if(ip in ipbanlist)\r
640         {\r
641                 socket.emit("error",$block_message);\r
642                 return;\r
643         }\r
644 \r
645         var rno = GetRoomNumberFromName(socket.namespace.name);\r
646 \r
647         if(msg.name != $system_name && \r
648                 $rooms.Get(rno).IsVolatile() == false &&\r
649                 !$rooms.Get(rno).IsAuthed(msg.name) &&\r
650                 !$rooms.Get(rno).IsOwner(rno,msg.name))\r
651         {\r
652                 return;\r
653         }\r
654 \r
655         var date = new Date();\r
656 \r
657         var repacked_msg = CreateMessage(msg.name,date,msg.message);\r
658 \r
659         if(socket.handshake.admin)\r
660                 repacked_msg.ip = ip;\r
661 \r
662         socket.json.emit("req msg", repacked_msg);\r
663 \r
664         socket.json.broadcast.emit("req msg", repacked_msg);\r
665 \r
666         var path = $log_directory + "/" + util.format($log_file_name,rno);\r
667         var log = new ChatLog(path);\r
668         log.Save(repacked_msg,ip,rno);\r
669 }\r
670 \r
671 function GetNameFromRoomNumber(number)\r
672 {\r
673         return "/" + number;\r
674 }\r
675 \r
676 function GetRoomNumberFromName(name)\r
677 {\r
678         if(name.charAt(0) == "/")\r
679                 return parseInt(name.substr(1));\r
680         throw "GetRoomNumberFromName error";\r
681 }\r
682 \r
683 function ParseGetPastLogList(socket,msg)\r
684 {\r
685         var list = fs.readdir($log_directory,function(err,files){\r
686                 var text = "";\r
687                 var rno = GetRoomNumberFromName(socket.namespace.name);\r
688                 var pattern = $pastlogfile_pattern.replace("%d",rno);\r
689                 for(var i = 0; i < files.length; i++)\r
690                 {\r
691                         var logname = files[i];\r
692                         if(logname.match(pattern))\r
693                                 text += files[i] + "\n";\r
694                 }\r
695                 socket.emit("req pastloglist",text);\r
696         });\r
697 }\r
698 \r
699 function ParseGetPastLog(socket,file)\r
700 {\r
701         if(file == "")\r
702                 return;\r
703         var path = $log_directory + "/" + file;\r
704         var log = new ChatLog(path);\r
705         log.ToArray(socket.handshake.admin,function(array){\r
706                 socket.json.emit("req pastlog",array);\r
707         });\r
708 }\r
709 \r
710 function ChatLog(path)\r
711 {\r
712         this.ToArray = function(hasIp,callback)\r
713         {\r
714                 var state = fs.stat(path,function(err,state){\r
715                         if(err)\r
716                                 return;\r
717                         var array = new Array();\r
718                         var stream = fs.createReadStream(path);\r
719                         new lazy(stream)\r
720                                 .spilt(";")\r
721                                 .forEach(function(line){\r
722                                         var msg = CreateMessageFromText(line.toString());\r
723                                         if(hasIp == false)\r
724                                                 msg.ip = "";\r
725                                         array.push(msg);\r
726                                 })\r
727                                 .join(function(){\r
728                                         callback(array);\r
729                                 });\r
730                 });\r
731         }\r
732 \r
733         this.Save = function(msg,ip,rno){\r
734                 var text = GetTextFromMessage(msg,ip);\r
735 \r
736                 SplitLog(rno,function(){\r
737                         WritePastLog(path,text);\r
738                 });\r
739         };\r
740 \r
741         function GetTextFromMessage(msg,ip)\r
742         {\r
743                 var text = msg.name + "<>" +\r
744                                 msg.date + "<>" +\r
745                                 ip + "<>" +\r
746                                 msg.message +\r
747                                 ";";\r
748                 return text;\r
749         }\r
750 \r
751         function SplitLog(rno,callback)\r
752         {\r
753                 var state = fs.stat(path,function(err,state){\r
754                         if(err && typeof(callback) == "function")\r
755                         {\r
756                                 callback();\r
757                                 return;\r
758                         }\r
759                         if(state.size > $spilt_size)\r
760                         {\r
761                                 var date = new Date();\r
762                                 var dateString = ""+date.getFullYear()+date.getMonth()+date.getDate()+date.getHours()+date.getMinutes()+date.getSeconds();\r
763 \r
764                                 var newpath = $log_directory + "/" +\r
765                                         util.format($splited_log_file_name,rno,dateString);\r
766                                 fs.rename(path,newpath,callback);\r
767                         }else{\r
768                                 if(typeof(callback) == "function")\r
769                                         callback();\r
770                         }\r
771                 });\r
772         }\r
773 \r
774         function WritePastLog(path,text)\r
775         {\r
776                 async.waterfall([\r
777                         function(callback){\r
778                                 fs.open(path,"a",callback);\r
779                         },\r
780                         function(fd,callback){\r
781                                 var buf = new Buffer(text);\r
782                                 fs.write(fd,buf,0,Buffer.byteLength(text),null,function(){\r
783                                         callback(null,fd);\r
784                                 });\r
785                         },\r
786                         function(fd){\r
787                                 fs.close(fd);\r
788                         }\r
789                 ]);\r
790         }\r
791 }\r
792 \r
793 function GetClientIPAdress(socket)\r
794 {\r
795         return socket.handshake.headers["x-forwarded-for"] || socket.handshake.address.address;\r
796 }\r
797 \r
798 // Message クラス\r
799 function CreateMessage(name,date,message)\r
800 {\r
801         var result = {name:name,\r
802                 date:date,\r
803                 ip:"",\r
804                 message:message};\r
805         return result;\r
806 }\r
807 function CreateMessageFromText(text)\r
808 {\r
809         var data = text.split("<>");\r
810         var msg = {name:data[0],\r
811                 ip:data[2],\r
812                 date:data[1],\r
813                 message:data[3]};\r
814         return msg;\r
815 }\r