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