OSDN Git Service

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