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