OSDN Git Service

IPBANLISTをMYSQLのテーブルで定義した
[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 collection = {};\r
148         this.Get = function(rno){\r
149                 return collection[rno];\r
150         }\r
151         this.IsContains = function(rno){\r
152                 return rno in collection;\r
153         };\r
154         this.GetString = function(){\r
155                 var retval = "";\r
156                 for(var rno in collection)\r
157                 {\r
158                         if($rooms.Get(rno).IsVolatile())\r
159                                 continue;\r
160                         var pass = collection[rno].password;\r
161                         if(pass == null)\r
162                                 pass = "";\r
163                         var hiddenlog = collection[rno].hiddenlog;\r
164                         retval += rno + ":" + pass + ":" + hiddenlog + "\r\n";\r
165                 }\r
166                 return retval;\r
167         };\r
168         this.GetKeys = function(){\r
169                 var retval = {};\r
170                 for(var rno in collection)\r
171                 {\r
172                         retval[rno] = {};\r
173                 }\r
174                 return retval;\r
175         }\r
176         this.Update = function(text,callfunc){\r
177                 async.waterfall([\r
178                         function(callback){\r
179                                 fs.open($room_configure_file_name,"w",callback);\r
180                         },\r
181                         function(fd,callback){\r
182                                 var buf = new Buffer(text);\r
183                                 fs.write(fd,buf,0,Buffer.byteLength(text),null,function(){\r
184                                         callback(null,fd);\r
185                                 });\r
186                         },\r
187                         function(fd,callback){\r
188                                 fs.close(fd,function(){\r
189                                         GetRoomList(callfunc);\r
190                                 });\r
191                         }\r
192                 ]);\r
193         }\r
194         function GetRoomList(callback){\r
195                 Clear();\r
196                 fs.exists($room_configure_file_name,function(exists){\r
197                         if(exists == false)\r
198                         {\r
199                                 if(typeof(callback) == "function")\r
200                                         callback();\r
201                                 return;\r
202                         }\r
203                         var stream = fs.createReadStream($room_configure_file_name);\r
204                         new lazy(stream)\r
205                                 .lines\r
206                                 .forEach(function(line){\r
207                                         var token = line.toString().replace(/(\r|\n|\r\n)/gm, "").split(":");\r
208                                         if(token.length == 1)\r
209                                         {\r
210                                                 Add(token[0],null,false);\r
211                                         }\r
212                                         else if(token.length == 2)\r
213                                         {\r
214                                                 var rno = token[0];\r
215                                                 var pass = token[1];\r
216                                                 if(pass == "")\r
217                                                         pass = null;\r
218                                                 Add(rno, pass,false);\r
219                                         }\r
220                                         else if(token.length == 3)\r
221                                         {\r
222                                                 var rno = token[0];\r
223                                                 var pass = token[1];\r
224                                                 if(pass == "")\r
225                                                         pass = null;\r
226                                                 var hiddenlog = false;\r
227                                                 if(token[2] == "true")\r
228                                                         hiddenlog = true;\r
229                                                 Add(rno, pass,hiddenlog);\r
230                                         }\r
231                                 })\r
232                                 .join(function(){\r
233                                         if(typeof(callback) == "function")\r
234                                                 callback();\r
235                                 });\r
236                 });\r
237         }\r
238         function Clear(){\r
239                 collection = {};\r
240                 for(var i = 0; i < config.max_room_number; i++)\r
241                         Add(i,null,null);\r
242         };\r
243         function Add(rno,pass,hiddenlogflag){\r
244                 collection[rno] = new RoomInfomation(pass,hiddenlogflag);\r
245                 if(pass != null)\r
246                         collection[rno].owner = $system_name;\r
247         };\r
248         var $gc_interval_id = setInterval(function(){\r
249                 for(var rno in this.rom_list)\r
250                         collection[rno].GCRomList();\r
251         },$gc_time_interval);\r
252         GetRoomList();\r
253 }\r
254 \r
255 //RoomInfomationクラス\r
256 function RoomInfomation(pass,hiddenlogflag)\r
257 {\r
258         this.password = pass;\r
259         this.rom_list = {};\r
260         this.authed_list = {};\r
261         this.owner = null;\r
262         this.time = null;\r
263         this.hiddenlog = hiddenlogflag;\r
264         this.GetConfig = function(){\r
265                 var roomconfig = {};\r
266                 if(this.IsVolatile() == false)\r
267                 {\r
268                         if(this.IsFixedPassword())\r
269                                 roomconfig.type = 2;\r
270                         else if(this.IsHiddenLogFromRom())\r
271                                 roomconfig.type = 3;\r
272                         else\r
273                                 roomconfig.type = 1;\r
274                         roomconfig.IsOwned = !this.IsFirstAuth();\r
275                 }else{\r
276                         roomconfig.type = 0;\r
277                 }\r
278                 return roomconfig;\r
279         }\r
280         this.IsVolatile = function(){\r
281                 return this.owner == null &&\r
282                         this.password == null &&\r
283                         this.time == null &&\r
284                         this.hiddenlog == null;\r
285         }\r
286         this.GetRomCount = function(){\r
287                 var count = 0;\r
288                 for(var key in this.rom_list)\r
289                         count++;\r
290                 return count;\r
291         };\r
292         this.AddRom = function(ip){\r
293                 var date = new Date();\r
294                 this.rom_list[ip] = {time:date.getTime()};\r
295         };\r
296         this.RemoveRom = function(ip){\r
297                 delete this.rom_list[ip];\r
298         };\r
299         this.Reset = function(owner){\r
300                 var date = new Date();\r
301                 var time = date.getTime();\r
302                 this.password = null;\r
303                 this.authed_list = {};\r
304                 this.owner = owner;\r
305                 this.time = time;\r
306         };\r
307         this.IsFirstAuth = function(){\r
308                 return this.owner == null;\r
309         };\r
310         this.IsAuthed = function(name){\r
311                 return name == this.owner ||\r
312                         name in this.authed_list;\r
313         };\r
314         this.IsHiddenLogFromRom = function(){\r
315                 return this.hiddenlog;\r
316         };\r
317         this.IsFixedPassword = function(){\r
318                 return this.owner == $system_name;\r
319         };\r
320         this.IsOwner = function(name){\r
321                 return this.owner == name;\r
322         };\r
323         this.IsTimeout = function(){\r
324                 var date = new Date();\r
325                 var current_time = date.getTime();\r
326                 return !this.IsFixedPassword() &&\r
327                         current_time - this.time >= $reset_password_diff;\r
328         };\r
329         this.RemoveAuth = function(name)\r
330         {\r
331                 delete this.authed_list[name];\r
332         };\r
333         this.Auth = function(name,password){\r
334                 if(this.password != password)\r
335                         return false;\r
336                 var date = new Date();\r
337                 var time = date.getTime();\r
338                 this.time = time;\r
339                 this.authed_list[name] = "";\r
340                 return true;\r
341         };\r
342         this.SetPassword = function(owner,password){\r
343                 if(owner == this.owner &&\r
344                         !this.IsFixedPassword() &&\r
345                         !this.IsHiddenLogFromRom())\r
346                 {\r
347                         var date = new Date();\r
348                         this.time = date.getTime();\r
349                         this.password = password;\r
350                         return true;\r
351                 }\r
352                 return false;\r
353         };\r
354         this.GCRomList = function(){\r
355                 var date = new Date();\r
356                 var current_time = date.getTime();\r
357                 for(var ip in this.rom_list)\r
358                 {\r
359                         if(current_time - this.rom_list[ip].time >= $gc_time_interval)\r
360                                 delete this.rom_list[ip];\r
361                 }\r
362         };\r
363 }\r
364 \r
365 //IPBANクラス\r
366 function IpBanCollecion()\r
367 {\r
368         var MySQLPool = new require("./mysql_pool.js");\r
369         var pool = new MySQLPool({\r
370                                 host     : config.db_host,\r
371                                 user     : config.db_user,\r
372                                 password : config.db_password,\r
373                                 database : "configure",\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                 collection = {};\r
395                 async.waterfall([\r
396                         function(next){\r
397                                 pool.query("TRUNCATE TABLE ipbanlist",null,next);\r
398                         },\r
399                         function(result,next){\r
400                                 var items = new Array();\r
401                                 lines = text.split("\r\n");\r
402                                 for(var i = 0; i < lines.length; i++)\r
403                                 {\r
404                                         var token = lines[i].split(":");\r
405                                         var ip = token[0];\r
406                                         if(ip == "")\r
407                                                 continue;\r
408                                         if(token.length == 1)\r
409                                                 collection[ip] = "";\r
410                                         else\r
411                                                 collection[ip] = token[1];\r
412                                         items.push(new Array(ip,collection[ip]));\r
413                                 }\r
414                                 pool.query("INSERT INTO ipbanlist VALUES ?",[items],next);\r
415                         },\r
416                 ],callfunc);\r
417         }\r
418         function GetIpBanList(callfunc)\r
419         {\r
420                 async.waterfall([\r
421                         function(next){\r
422                                 pool.query("SELECT * FROM ipbanlist",null,next);\r
423                         },\r
424                         function(result,next){\r
425                                 for(var i = 0; i < result.length; i++)\r
426                                         collection[result[i].ip] = result[i].type;\r
427                                 next(null,null);\r
428                         },\r
429                 ],callfunc);\r
430         }\r
431         GetIpBanList();\r
432 }\r
433 \r
434 var ipbanlist = new IpBanCollecion();\r
435 var $rooms = new RoomInfomationCollection();\r
436 \r
437 createLogDirectory();\r
438 \r
439 function createLogDirectory()\r
440 {\r
441         fs.exists($log_directory,function(exists){\r
442                 if(exists == false)\r
443                         fs.mkdirSync($log_directory);\r
444         });\r
445 }\r
446 \r
447 function ParseConnect(socket)\r
448 {\r
449         var ip = GetClientIPAdress(socket);\r
450         console.log("connected from %s",ip);\r
451 \r
452         var rno = GetRoomNumberFromName(socket.namespace.name);\r
453 \r
454         var room = $rooms.Get(rno);\r
455 \r
456         room.AddRom(ip);\r
457 \r
458         var roomconfig = room.GetConfig();\r
459         roomconfig.admin = socket.handshake.admin;\r
460         socket.json.emit("send roominfo",roomconfig);\r
461 \r
462         var romcount = room.GetRomCount();\r
463         socket.json.emit("send romcount",romcount);\r
464         socket.json.broadcast.emit("send romcount",romcount);\r
465 \r
466         socket.on("get pastLogList", function (msg) {\r
467                 ParseGetPastLogList(socket,msg);\r
468         });\r
469         socket.on("get pastLog", function (msg) {\r
470                 ParseGetPastLog(socket,msg);\r
471         });\r
472         socket.on("join",function(msg){\r
473                 ParseJoin(socket,msg);\r
474         });\r
475         socket.on("quit",function(msg){\r
476                 ParseQuit(socket,msg);\r
477         });\r
478         socket.on("set password",function(msg){\r
479                 ParseSetPassword(socket,msg);\r
480         });\r
481         socket.on("send msg", function (msg) {\r
482                 ParseSendMsg(socket,msg);\r
483         });\r
484         socket.on("disconnect", function (msg) {\r
485                 ParseDisconnect(socket,msg);\r
486         });\r
487 }\r
488 \r
489 function ParseAuthorization(handshakeData, callback)\r
490 {\r
491         if(handshakeData.headers.cookie) {\r
492                 var signedCookie = cookie.parse(handshakeData.headers.cookie);\r
493                 var sessionID = connectUtils.parseSignedCookies(signedCookie, $secret)["connect.sid"];\r
494                 sessionStore.get(sessionID, function (err, session) {\r
495                         var result = null;\r
496                         if (ipbanlist.IsBaned(handshakeData.address.address))\r
497                                 result = "failed get from session store";\r
498                         else if(err)\r
499                                 result = err;\r
500                         else if(handshakeData.query.token != session.items.token)\r
501                                 result = "invaild token";\r
502                         if(typeof(session) != "undefined" && result == null)\r
503                         {\r
504                                 handshakeData.admin = session.items.admin;\r
505                                 handshakeData.sessionID = sessionID;\r
506                         }\r
507                         callback(result,result == null && !err);\r
508                 });\r
509         } else {\r
510                 return callback("failed get cookie", false);\r
511         }\r
512 }\r
513 \r
514 function ParseDisconnect(socket,msg)\r
515 {\r
516         var ip = GetClientIPAdress(socket);\r
517         var rno = GetRoomNumberFromName(socket.namespace.name);\r
518         $rooms.Get(rno).RemoveRom(ip);\r
519 \r
520         var romcount = $rooms.Get(rno).GetRomCount();\r
521         socket.json.emit("send romcount",romcount);\r
522         socket.json.broadcast.emit("send romcount",romcount);\r
523 \r
524         console.log("disconnected");\r
525 }\r
526 \r
527 function ParseSetPassword(socket,msg)\r
528 {\r
529         var rno = GetRoomNumberFromName(socket.namespace.name);\r
530         var newMeg = {\r
531                 name:$system_name,\r
532                 message:null,\r
533         };\r
534         if($rooms.Get(rno).IsVolatile() == false && $rooms.Get(rno).SetPassword(msg.owner,msg.password))\r
535                 newMeg.message = resource.password_setted_message;\r
536         else\r
537                 newMeg.message = resource.failed_set_password_message;\r
538         ParseSendMsg(socket,newMeg);\r
539 }\r
540 \r
541 function ParseJoin(socket,msg)\r
542 {\r
543         var ip = GetClientIPAdress(socket);\r
544 \r
545         if(ipbanlist.IsBlockedToWrite(ip))\r
546         {\r
547                 socket.emit("error",resource.block_message);\r
548                 return;\r
549         }\r
550 \r
551         var rno = GetRoomNumberFromName(socket.namespace.name);\r
552 \r
553         $rooms.Get(rno).RemoveRom(ip);\r
554         \r
555         var romcount = $rooms.Get(rno).GetRomCount();\r
556         socket.json.emit("send romcount",romcount);\r
557         socket.json.broadcast.emit("send romcount",romcount);\r
558 \r
559         if($rooms.Get(rno).IsVolatile() == false)\r
560         {\r
561                 if($rooms.Get(rno).IsTimeout() ||\r
562                         $rooms.Get(rno).IsFirstAuth())\r
563                 {\r
564                         $rooms.Get(rno).Reset(msg.name);\r
565                         ParseGetPastLog(socket,util.format($log_file_name,rno));\r
566                 }\r
567                 else if($rooms.Get(rno).Auth(msg.name,msg.password))\r
568                 {\r
569                         ParseGetPastLog(socket,util.format($log_file_name,rno));\r
570                 }\r
571                 else\r
572                 {\r
573                         socket.emit("error",$not_match_password);\r
574                         return;\r
575                 }\r
576         }\r
577 \r
578         var newMeg = {\r
579                 name:$system_name,\r
580                 message:util.format("/enteredby %s %s %s",msg.name,msg.color,msg.mailto),\r
581         };\r
582         ParseSendMsg(socket,newMeg);\r
583 }\r
584 \r
585 function ParseQuit(socket,msg)\r
586 {\r
587         var ip = GetClientIPAdress(socket);\r
588 \r
589         if(ipbanlist.IsBlockedToWrite(ip))\r
590         {\r
591                 socket.emit("error",resource.block_message);\r
592                 return;\r
593         }\r
594 \r
595         var rno = GetRoomNumberFromName(socket.namespace.name);\r
596 \r
597         var newMeg = {\r
598                 name:$system_name,\r
599                 message:resource.password_resetted_message,\r
600         };\r
601 \r
602         $rooms.Get(rno).AddRom(ip);\r
603 \r
604         var romcount = $rooms.Get(rno).GetRomCount();\r
605         socket.json.emit("send romcount",romcount);\r
606         socket.json.broadcast.emit("send romcount",romcount);\r
607 \r
608         if($rooms.Get(rno).IsVolatile() == false)\r
609         {\r
610                 if($rooms.Get(rno).IsOwner(msg.name))\r
611                 {\r
612                         $rooms.Get(rno).Reset(null);\r
613                         ParseSendMsg(socket,newMeg);\r
614                 }\r
615                 if(!$rooms.Get(rno).IsFirstAuth() &&\r
616                         !$rooms.Get(rno).IsAuthed(msg.name))\r
617                         return;\r
618                 else\r
619                         $rooms.Get(rno).RemoveAuth(msg.name);\r
620         }\r
621 \r
622         newMeg.message = util.format("/quitedby %s",msg.name);\r
623         ParseSendMsg(socket,newMeg);\r
624 }\r
625 \r
626 //socket 接続中のソケット\r
627 //msg msgクラス\r
628 function ParseSendMsg(socket,msg)\r
629 {\r
630         var ip = GetClientIPAdress(socket);\r
631 \r
632         if(ip in ipbanlist)\r
633         {\r
634                 socket.emit("error",resource.block_message);\r
635                 return;\r
636         }\r
637 \r
638         var rno = GetRoomNumberFromName(socket.namespace.name);\r
639 \r
640         if(msg.name != $system_name && \r
641                 $rooms.Get(rno).IsVolatile() == false &&\r
642                 !$rooms.Get(rno).IsAuthed(msg.name) &&\r
643                 !$rooms.Get(rno).IsOwner(rno,msg.name))\r
644         {\r
645                 return;\r
646         }\r
647 \r
648         var date = new Date();\r
649 \r
650         var repacked_msg = CreateMessage(msg.name,date,msg.message);\r
651 \r
652         if(socket.handshake.admin)\r
653                 repacked_msg.ip = ip;\r
654 \r
655         socket.json.emit("req msg", repacked_msg);\r
656 \r
657         socket.json.broadcast.emit("req msg", repacked_msg);\r
658 \r
659         var path = $log_directory + "/" + util.format($log_file_name,rno);\r
660         var log = new ChatLog(path);\r
661         log.Save(repacked_msg,ip,rno);\r
662 }\r
663 \r
664 function GetNameFromRoomNumber(number)\r
665 {\r
666         return "/" + number;\r
667 }\r
668 \r
669 function GetRoomNumberFromName(name)\r
670 {\r
671         if(name.charAt(0) == "/")\r
672                 return parseInt(name.substr(1));\r
673         throw "GetRoomNumberFromName error";\r
674 }\r
675 \r
676 function ParseGetPastLogList(socket,msg)\r
677 {\r
678         var list = fs.readdir($log_directory,function(err,files){\r
679                 var text = "";\r
680                 var rno = GetRoomNumberFromName(socket.namespace.name);\r
681                 var pattern = $pastlogfile_pattern.replace("%d",rno);\r
682                 for(var i = 0; i < files.length; i++)\r
683                 {\r
684                         var logname = files[i];\r
685                         if(logname.match(pattern))\r
686                                 text += files[i] + "\n";\r
687                 }\r
688                 socket.emit("req pastloglist",text);\r
689         });\r
690 }\r
691 \r
692 function ParseGetPastLog(socket,file)\r
693 {\r
694         if(file == "")\r
695                 return;\r
696         var path = $log_directory + "/" + file;\r
697         var log = new ChatLog(path);\r
698         log.ToArray(socket.handshake.admin,function(array){\r
699                 socket.json.emit("req pastlog",array);\r
700         });\r
701 }\r
702 \r
703 function ChatLog(path)\r
704 {\r
705         this.ToArray = function(hasIp,callback)\r
706         {\r
707                 var state = fs.stat(path,function(err,state){\r
708                         if(err)\r
709                                 return;\r
710                         var array = new Array();\r
711                         var stream = fs.createReadStream(path);\r
712                         new lazy(stream)\r
713                                 .spilt(";")\r
714                                 .forEach(function(line){\r
715                                         var msg = CreateMessageFromText(line.toString());\r
716                                         if(hasIp == false)\r
717                                                 msg.ip = "";\r
718                                         array.push(msg);\r
719                                 })\r
720                                 .join(function(){\r
721                                         callback(array);\r
722                                 });\r
723                 });\r
724         }\r
725 \r
726         this.Save = function(msg,ip,rno){\r
727                 var text = GetTextFromMessage(msg,ip);\r
728 \r
729                 SplitLog(rno,function(){\r
730                         WritePastLog(path,text);\r
731                 });\r
732         };\r
733 \r
734         function GetTextFromMessage(msg,ip)\r
735         {\r
736                 var text = msg.name + "<>" +\r
737                                 msg.date + "<>" +\r
738                                 ip + "<>" +\r
739                                 msg.message +\r
740                                 ";";\r
741                 return text;\r
742         }\r
743 \r
744         function SplitLog(rno,callback)\r
745         {\r
746                 var state = fs.stat(path,function(err,state){\r
747                         if(err && typeof(callback) == "function")\r
748                         {\r
749                                 callback();\r
750                                 return;\r
751                         }\r
752                         if(state.size > $spilt_size)\r
753                         {\r
754                                 var date = new Date();\r
755                                 var dateString = ""+date.getFullYear()+date.getMonth()+date.getDate()+date.getHours()+date.getMinutes()+date.getSeconds();\r
756 \r
757                                 var newpath = $log_directory + "/" +\r
758                                         util.format($splited_log_file_name,rno,dateString);\r
759                                 fs.rename(path,newpath,callback);\r
760                         }else{\r
761                                 if(typeof(callback) == "function")\r
762                                         callback();\r
763                         }\r
764                 });\r
765         }\r
766 \r
767         function WritePastLog(path,text)\r
768         {\r
769                 async.waterfall([\r
770                         function(callback){\r
771                                 fs.open(path,"a",callback);\r
772                         },\r
773                         function(fd,callback){\r
774                                 var buf = new Buffer(text);\r
775                                 fs.write(fd,buf,0,Buffer.byteLength(text),null,function(){\r
776                                         callback(null,fd);\r
777                                 });\r
778                         },\r
779                         function(fd){\r
780                                 fs.close(fd);\r
781                         }\r
782                 ]);\r
783         }\r
784 }\r
785 \r
786 function GetClientIPAdress(socket)\r
787 {\r
788         return socket.handshake.headers["x-forwarded-for"] || socket.handshake.address.address;\r
789 }\r
790 \r
791 // Message クラス\r
792 function CreateMessage(name,date,message)\r
793 {\r
794         var result = {name:name,\r
795                 date:date,\r
796                 ip:"",\r
797                 message:message};\r
798         return result;\r
799 }\r
800 function CreateMessageFromText(text)\r
801 {\r
802         var data = text.split("<>");\r
803         var msg = {name:data[0],\r
804                 ip:data[2],\r
805                 date:data[1],\r
806                 message:data[3]};\r
807         return msg;\r
808 }\r