OSDN Git Service

""をファイル名に指定して過去ログを取得するとサーバーが落ちるバグを修正した
[webchat/WebChat.git] / public / scripts / chatclient.js
1 $expires = 30;       //クッキーの保持日数\r
2 $afk_time = 1000 * 60 * 60;     //AFKと判定する時間(ミリ秒で指定すること)\r
3 $log_file_name = "logfile%d.txt";       //ログファイル名(%dはそのままにしておくこと)\r
4 $system_name = "system";        //システム発言を表す名前(chat.phpと同じにすること)\r
5 $entered_message = "%sが入室しました";\r
6 $quited_message = "%sが退室しました";\r
7 $system_msg_color ="#000000";\r
8 $profile_link = ""      //プロフィールシステムへのリンク先(%nで名前を表す)\r
9 $fanble_message = "[color=blue]%s ファンブル![/color]";    //ファンブル時のメッセージ\r
10 $critical_message = "[color=red]%s クリティカル![/color]";        //クリティカル時のメッセージ\r
11 $send_message = "%sからの送信 %s";\r
12 $failed_connect_message = "failed connect or ip banned";\r
13 \r
14 //ここから先は変更しないでください\r
15 $prefix_filelist = "!";\r
16 $socket = new Object();\r
17 $names = {};\r
18 $dateFormat = new DateFormat("yyyy/MM/dd HH:mm:ss");\r
19 //ここまで\r
20 \r
21 $(document).ready(function(){\r
22         CreateColorList();\r
23 \r
24         //クッキーからフォームに読み込む\r
25         var temp = $.cookie("name");\r
26         if(temp)        document.enter_form.name.value = temp;\r
27         temp = $.cookie("color_index");\r
28         if(temp)        document.enter_form.color.selectedIndex = temp;\r
29 \r
30         $("input[name=sid]").click(sidEventListener);\r
31         $("input[name=enter]").click(enterEventListener);\r
32         $("input[name=quit]").click(quitEventListener);\r
33         $("input[name=help]").click(function(e){\r
34                 $("#help_frame").css("display","block");\r
35         });\r
36         $("input[name=close]").click(function(e){\r
37                 $("#help_frame").css("display","none");\r
38         });\r
39         $("input[name=openPastlog]").click(openPastlogEventListener);\r
40         $("#enter_frame input[name=name]").keydown(function(e){\r
41                 if(e.keyCode == 13)\r
42                         enterEventListener();\r
43         });\r
44         $("#chat_frame input[name=message]").keydown(function(e){\r
45                 if(e.keyCode == 13)\r
46                         sidEventListener();\r
47         });\r
48         document.chat_form.onsubmit = function(){return false;};\r
49         document.enter_form.onsubmit = function(){return false;};\r
50 \r
51         $socket = io.connect(location.hostname + "/" + document.chat_form.rno.value);\r
52         $socket.on("error",getErrorMessage);\r
53         $socket.on("connect",function(){\r
54                 $socket.on("req pastlog",pastLogEventListerner);\r
55                 $socket.on("req msg",getMessageEventListerner);\r
56                 $socket.on("req pastloglist",CreatePastLogList);\r
57                 $socket.json.emit("get pastLogList",{rno:document.chat_form.rno.value});\r
58                 getCurretLog();\r
59         });\r
60 });\r
61 \r
62 function CreateColorList()\r
63 {\r
64         var c = new Array("00","33","66","99","CC","FF");\r
65         for(var r = 0; r < c.length; r++){\r
66                 for(var g = 0; g < c.length; g++){\r
67                         for(var b = 0; b < c.length; b++){\r
68                                 var t = document.createElement("option");\r
69                                 t.value = "#"+c[r]+c[g]+c[b];\r
70                                 t.style.backgroundColor = "#"+c[r]+c[g]+c[b];\r
71                                 t.appendChild(document.createTextNode("#"+c[r]+c[g]+c[b]));\r
72                                 $("#enter_frame form select[name=color]").append(t);\r
73                         }\r
74                 }\r
75         }\r
76 }\r
77 \r
78 function CreatePastLogList(text)\r
79 {\r
80         $("#enter_frame form select[name=past]").empty();\r
81         var rno = document.chat_form.rno.value;\r
82         var file = text.split("\n");\r
83         for(var i = 0; i < file.length; i++)\r
84         {\r
85                 var logname = file[i];\r
86                 if(logname == "")\r
87                         continue;\r
88                 var element = document.createElement("option");\r
89                 element.value = logname;\r
90                 element.appendChild(document.createTextNode(logname));\r
91                 $("#enter_frame form select[name=past]").append(element);\r
92         }\r
93 }\r
94 \r
95 function getCurretLog()\r
96 {\r
97         var rno = document.chat_form.rno.value;\r
98         var url = sprintf($log_file_name,rno);\r
99         $socket.emit("get pastLog",url);\r
100 }\r
101 \r
102 function openPastlogEventListener()\r
103 {\r
104         $tid = 0;\r
105         $("#message").empty();\r
106         $("#namelist").empty();\r
107         var url = document.enter_form.past.options[document.enter_form.past.selectedIndex].value;\r
108         $socket.emit("get pastLog",url);\r
109 }\r
110 \r
111 function pastLogEventListerner(msg)\r
112 {\r
113         ParseMessage(msg);\r
114 }\r
115 \r
116 function getMessageEventListerner(msg)\r
117 {\r
118         ParseMessage(msg);\r
119         if( document.getElementById("bell").checked == true && msg.name != document.enter_form.name.value)\r
120                 document.getElementById("NoticeSound").play();\r
121 }\r
122 \r
123 function ParseMessage(msg)\r
124 {\r
125         var util = new Util();\r
126         var cmd = new CommandParserWhenGet;\r
127         msg.message = util.htmlspecialchars(msg.message);\r
128         var childtag = cmd.parse(msg);\r
129 \r
130         if(childtag == null)\r
131                 return;\r
132 \r
133         var ptag = $("<p/>");\r
134 \r
135         var color = $system_msg_color;\r
136         var mailto = "";\r
137         var date = new Date(Date.parse(msg.date));\r
138         if(msg.name != $system_name)\r
139         {\r
140                 color = $names[msg.name].color;\r
141                 $names[msg.name].time = date.getTime();\r
142                 var atag = $("<a/>")\r
143                         .attr("href",GetNameLink(msg.name))\r
144                         .css("color",color)\r
145                         .text(util.htmlspecialchars(msg.name));\r
146                 ptag.append(atag);\r
147         }else{\r
148                 ptag.append(msg.name);\r
149         }\r
150         ptag.append(":");\r
151         ptag.append(childtag);\r
152         ptag.append("(" + $dateFormat.format(date) +")");\r
153 \r
154         ptag.css("color",color);\r
155 \r
156         if($("#message > p").length == 0)\r
157                 $("#message").append(ptag);\r
158         else\r
159                 $("#message > p:first").before(ptag);\r
160 \r
161         createNameList();\r
162 }\r
163 \r
164 function GetNameLink(name)\r
165 {\r
166         var util = new Util();\r
167         if(document.enter_form.mailto.value == "")\r
168                 return $profile_link.replace("%n",encodeURI(name));\r
169         return "mailto:" + util.htmlspecialchars($names[name].mailto);\r
170 }\r
171 \r
172 function createNameList()\r
173 {\r
174         var date = new Date();\r
175         $("#namelist").empty();\r
176         $("#namelist").append("<ul></ul>");\r
177         for(var name in $names)\r
178         {\r
179                 var diff = date.getTime() - $names[name].time;\r
180                 if(diff >= $afk_time)\r
181                         continue;\r
182                 if(name != $system_name)\r
183                 {\r
184                         var atag = $("<a/>")\r
185                                 .attr("href",GetNameLink(name))\r
186                                 .css("color",$names[name].color)\r
187                                 .text(name);\r
188                         $("#namelist > ul").append($("<li/>").append(atag));\r
189                 }\r
190         }\r
191 }\r
192 \r
193 function enterEventListener(){\r
194         $("#enter_frame").css("display","none");\r
195         $("#chat_frame").css("display","block");\r
196 \r
197         var color = document.enter_form.color.options[document.enter_form.color.selectedIndex].value;\r
198 \r
199         $.cookie("name",document.enter_form.name.value,{ expires: $expires });\r
200         $.cookie("color_index",document.enter_form.color.selectedIndex,{ expires: $expires });\r
201 \r
202         var text = "/enteredby " + document.enter_form.name.value + " " + color + " " + document.enter_form.mailto.value;\r
203 \r
204         $socket.json.emit("send msg",{name:$system_name,message:text,token:document.chat_form.token.value});\r
205 }\r
206 \r
207 function quitEventListener(){\r
208         var text = "/quitedby " + document.enter_form.name.value;\r
209         $socket.json.emit("send msg",{name:$system_name,message:text,token:document.chat_form.token.value});\r
210 \r
211         $socket.json.emit("get pastLogList",{rno:document.chat_form.rno.value});\r
212         $("#enter_frame").css("display","block");\r
213         $("#chat_frame").css("display","none");\r
214 }\r
215 \r
216 function sidEventListener(){\r
217         var cmd = new CommandParserWhenPost;\r
218         var msg = {\r
219                 name:document.enter_form.name.value,\r
220                 message:document.chat_form.message.value,\r
221                 token:document.chat_form.token.value\r
222         };      \r
223         msg.message = cmd.parse(msg);\r
224 \r
225         if(msg.message != null)\r
226                 $socket.json.emit("send msg",msg);\r
227 \r
228         document.chat_form.message.value ="";\r
229 }\r
230 \r
231 function ReflushChatMessage(flag)\r
232 {\r
233         if(flag)        $("#message").empty();\r
234 }\r
235 \r
236 function getErrorMessage(text)\r
237 {\r
238         if(text == "")\r
239                 alert($failed_connect_message);\r
240         else\r
241                 alert(text);\r
242 }\r
243 \r
244 //NameCollectionクラス\r
245 function GetNameCollection(text)\r
246 {\r
247         var output = new Array();\r
248         var list = text.split("\n");\r
249         for(var i = 0; i < list.length; i++)\r
250         {\r
251                 if(list[i] == "")\r
252                         continue;\r
253                 output.push(new NameElement(list[i]));\r
254         }\r
255         return output;\r
256 }\r
257 \r
258 //\r
259 // NamesElementsクラス\r
260 //\r
261 function NameElement(s)\r
262 {\r
263         this.data = s.split("<>");\r
264         this.getName = function()\r
265         {\r
266                 return this.data[0];\r
267         }\r
268 }\r
269 \r
270 // NameInfoクラス\r
271 function CreateNameInfo(time,color,mailto)\r
272 {\r
273         var result = { time:time,color:color,mailto:""};\r
274         if(typeof(mailto) != "undifined")\r
275                 result.mailto = mailto;\r
276         return result;\r
277 }\r
278 \r
279 //\r
280 // CommandParserクラス\r
281 //\r
282 function CommandParser()\r
283 {\r
284         this.word = new Array;\r
285         this.CommandList;\r
286         this.DefaultCommand = function(msg)\r
287         {\r
288                 return msg.message;\r
289         }\r
290 \r
291         this.parse = function(msg)\r
292         {\r
293                 this.word = msg.message.split(" ");\r
294                 if(this.CommandList[this.word[0]])\r
295                         return this.CommandList[this.word[0]](msg,this.word);\r
296                 else\r
297                         return this.DefaultCommand(msg);\r
298         }\r
299 }\r
300 \r
301 //\r
302 // CommandParserWhenGetクラス\r
303 //\r
304 //      function(msg,word)\r
305 //              msg\r
306 //                      msgオブジェクト\r
307 //              word\r
308 //                      トークンリスト\r
309 //              返り値\r
310 //                      タグもしくは文字列を返す\r
311 //                      nullを返した場合、メッセージリストには何も表示されなくなる\r
312 function CommandParserWhenGet()\r
313 {\r
314         this.DefaultCommand = function(msg)\r
315         {\r
316                 return parseBBCode(msg.message);\r
317         }\r
318         this.CommandList = new Array;\r
319         this.CommandList["/tell"] = function(msg,word)\r
320         {\r
321                 if((word[2] == "all")||\r
322                         (word[2] == document.enter_form.name.value)||\r
323                         (word[1] == document.enter_form.name.value)\r
324                 ){\r
325                         return $("<span/>").attr("id","whisper").append(parseBBCode(word[3]));\r
326                 }else{\r
327                         return null;\r
328                 }\r
329         }\r
330         this.CommandList["/enteredby"] = function(msg,word)\r
331         {\r
332                 var name = word[1];\r
333                 var color = word[2];\r
334                 var mailto = word[3];\r
335                 var text = sprintf($entered_message,name);\r
336                 var date = new Date(Date.parse(msg.date));\r
337                 $names[name] = CreateNameInfo(date.getTime(),color,mailto);\r
338                 createNameList();\r
339                 return text;\r
340         }\r
341         this.CommandList["/quitedby"] = function(msg,word)\r
342         {\r
343                 var name = word[1];\r
344                 var text = sprintf($quited_message,name);\r
345                 delete $names[name];\r
346                 createNameList();\r
347                 return text;\r
348         }\r
349 }\r
350 CommandParserWhenGet.prototype = new CommandParser;\r
351 \r
352 //\r
353 // CommandParserWhenPostクラス\r
354 //\r
355 //msg\r
356 //      msgオブジェクト\r
357 //word\r
358 //      word[0] コマンド名\r
359 //              word[1] 単語1\r
360 //                      :\r
361 //      word[n] 単語n\r
362 //      返却値\r
363 //              文字列を返す\r
364 //              nullを返した場合、送信操作が行われなくなる\r
365 function CommandParserWhenPost()\r
366 {\r
367         this.CommandList = new Array;\r
368         this.CommandList["/tell"] = function(msg,word)\r
369         {\r
370                 word[3] = word[2];\r
371                 word[2] = word[1];\r
372                 word[1] = msg.name;\r
373                 return word.join(" ");\r
374         }\r
375         this.CommandList["/dice"] = function(msg,word)\r
376         {\r
377                 if(word.length == 1)\r
378                         text = CastDice("6d1");\r
379                 else\r
380                         text = CastDice(word[1]);\r
381                 return text;\r
382         }\r
383         this.CommandList["/send"] = function(msg,word)\r
384         {\r
385                 if(word.length != 3)\r
386                         return msg.message;\r
387 \r
388                 var message = sprintf($send_message,document.enter_form.name.value,word[2]);\r
389 \r
390                 if(word[1] == document.chat_form.rno.value)\r
391                         $socket.json.emit("send msg",{name:$system_name,message:message,token:document.chat_form.token.value});\r
392 \r
393                 var socket = io.connect(location.hostname + "/" + word[1]);\r
394                 socket.on("error",getErrorMessage);\r
395                 socket.on("connect",function(){\r
396                         socket.json.emit("send msg",{name:$system_name,message:message,token:document.chat_form.token.value});\r
397                 });\r
398 \r
399                 return null;\r
400         }\r
401 }\r
402 CommandParserWhenPost.prototype = new CommandParser;\r
403 \r
404 function ParseDiceParam(number,option)\r
405 {\r
406         if(typeof(number) != "undefined")\r
407         {\r
408                 var result = new Object();\r
409                 result.option = typeof(option) == "undefined" ? null : option;\r
410                 result.number = parseInt(number);\r
411                 return result;\r
412         }\r
413         return null;\r
414 }\r
415 \r
416 function CastDice(text){\r
417         var p = text.match(/(\d+)D(\d+)C*(\d+)?(\-|\+)?F*(\d+)?(\-|\+)?/i);\r
418         var max = parseInt(p[1]);\r
419         var dice_num = parseInt(p[2]);\r
420         var critical = ParseDiceParam(p[3],p[4]);\r
421         var fanble = ParseDiceParam(p[5],p[6]);\r
422         var total = 0;\r
423         var hasCritical = true;\r
424         var hasFanble = true;\r
425         var util = new Util();\r
426 \r
427         text = "[" + text + "] -> ";\r
428         for(var i = 0; i < dice_num; i++)\r
429         {\r
430                 var t = util.get_random_number(1,max);\r
431                 total += t;\r
432                 text += t + " + ";\r
433 \r
434                 if(hasCritical && critical != null)\r
435                 {\r
436                         if(critical.option == "-" && t <= critical.number)\r
437                                 hasCritical = true;\r
438                         else if(critical.option == "+" && t >= critical.number)\r
439                                 hasCritical = true;\r
440                         else if(critical.option == null && t == critical.number)\r
441                                 hasCritical = true;\r
442                         else\r
443                                 hasCritical = false;\r
444                 }\r
445 \r
446                 if(hasFanble && fanble != null)\r
447                 {\r
448                         if(fanble.option == "-" && t <= fanble.number)\r
449                                 hasFanble = true;\r
450                         else if(fanble.option == "+" && t >= fanble.number)\r
451                                 hasFanble = true;\r
452                         else if(fanble.option == null && t == fanble.number)\r
453                                 hasFanble = true;\r
454                         else\r
455                                 hasFanble = false;\r
456                 }\r
457         }\r
458 \r
459         text = text.slice(0,text.length - 3);   //最後に付く" + "を取り除く\r
460         text += " = " + total;\r
461 \r
462         if(critical == null)\r
463                 hasCritical = false;\r
464         if(fanble == null)\r
465                 hasFanble = false;\r
466 \r
467         if(hasCritical)\r
468                 text = sprintf($critical_message,text);\r
469         else if(hasFanble)\r
470                 text = sprintf($fanble_message,text);\r
471 \r
472         return text;\r
473 }\r
474 \r
475 //\r
476 // Utilクラス\r
477 //\r
478 function Util()\r
479 {\r
480         this.get_random_number = function (a,b)\r
481         {\r
482                 return Math.floor(a + Math.random() * b);\r
483         }\r
484 \r
485         this.htmlspecialchars = function (ch) {\r
486                 ch = ch.replace(/&/g,"&amp;") ;\r
487                 ch = ch.replace(/"/g,"&quot;") ;\r
488                 ch = ch.replace(/'/g,"&#039;") ;\r
489                 ch = ch.replace(/</g,"&lt;") ;\r
490                 ch = ch.replace(/>/g,"&gt;") ;\r
491           return ch ;\r
492         }\r
493 \r
494 }\r