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