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