OSDN Git Service

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