OSDN Git Service

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