OSDN Git Service

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