function recalcFixedChat() { if(!chat) return; if(MSIE6) return; if($('chat-wrapper').parentNode.id == 'chat-inline-placeholder') return; var totalHeight = $(document.body).getHeight(); var viewHeight = document.viewport.getHeight(); var scroll = document.viewport.getScrollOffsets().top; var offset = $('chat-wrapper').viewportOffset().top; if(Prototype.Browser.Opera) offset -= scroll; if(typeof __buggyFixedPosition != 'undefined') { $('chat-container').style.position = 'absolute'; $('chat-container').style.top = ( scroll + viewHeight - $('chat-container').getHeight() ) + 'px'; } else { $('chat-container').style.bottom = '0px'; /*if(offset + $('chat-wrapper').getHeight() > viewHeight) { $('chat-wrapper').addClassName('fixed'); } else { $('chat-wrapper').removeClassName('fixed'); }*/ } /*var cont = $.select('.messages div').last(); if(cont.scrollTop != cont.scrollHeight) { cont.scrollTop = cont.scrollHeight; }*/ } function xml2array(node) { if( node.firstChild.nodeType == 3 ) // TEXT_NODE return node.textContent || node.text; var result = {}; for(var i=0;i'}); $('test').insert({top: msg}); } function rawInput(data) { log('RECV: ' + data.escapeHTML()); } function rawOutput(data) { log('SENT: ' + data.escapeHTML() + ''); } function toggleChatVisible() { if( $('chat-wrapper').parentNode.id == 'chat-inline-placeholder' ) return; $('chat-wrapper').toggleClassName('hidden'); if( chat.params.game_id ) setPrefCookie('chat-game-hide', $('chat-wrapper').hasClassName('hidden')); else setPrefCookie('chat-general-hide', $('chat-wrapper').hasClassName('hidden')); recalcFixedChat(); if( $('chat-wrapper').hasClassName('hidden') ) { if(chat.resize) delete chat.resize; if(chat.active_room == 'general') chat.leaveRoom('general'); $$('#chat-title .mostright').last().title = 'Развернуть'; } if( !$('chat-wrapper').hasClassName('hidden') ) { if(chat.active_room == 'general') { chat.enterRoom('general'); } else { $$('#chat-title .game.c span').last().removeClassName('new'); if(chat.blink_new_ingame) { clearInterval(chat.blink_new_ingame); chat.blink_new_ingame = null; } } $$('#chat-title .mostright').last().title = 'Cвернуть'; } } function toggleChatFixed() { if( $('chat-wrapper').hasClassName('hidden') ) return; if( $('chat-wrapper').parentNode.id == 'chat-inline-placeholder' ) { $('chat-fixed-placeholder').appendChild( $('chat-inline-placeholder').removeChild($('chat-wrapper')) ); $('chat-inline-placeholder').hide(); setPrefCookie('inline_chat', false); } else { $('chat-inline-placeholder').show(); $('chat-inline-placeholder').appendChild( $('chat-fixed-placeholder').removeChild($('chat-wrapper')) ); setPrefCookie('inline_chat', true); setChatHeight( __vk ? 40 : 120, true); } recalcFixedChat(); } function setChatHeight(height, withMargin) { var elems = $$('#chat-wrapper .messages-content'); for(var i=0;i div > div').last().update(''); $$('#chat-general .userlist-content').last().update(''); var elems = $$('#chat-title .game'); for( var i=0;i div').last(), { handle: $$('#chat-title .dummy .resize-bar').last(), maxHeight: 400, resize: function(el) { setChatHeight(el.getHeight(), true); }, update: function(el) { setChatHeight(el.getHeight()); } }); } Chat.prototype.getXUserdata = function(items) { var data = $build( 'x', { xmlns: 'klavogonki:userdata' } ); data.c('user'); for(var k in this.params.user) if( typeof(this.params.user[k]) == 'string' ) data.c(k).t(this.params.user[k]).up(); if( this.params.game_id ) data.up().c('game_id').t(this.params.game_id); return data; } Chat.prototype.enterRoom = function(room) { if(!this.connected) return; var pres = $pres( { from: this.connection.jid, to: room+'@conference.jabber.klavogonki.ru/' + Strophe.getNodeFromJid(this.connection.jid) } ) .c( 'x', { xmlns: 'http://jabber.org/protocol/muc' } ) .up(); if( this.params.user ) { pres.cnode( this.getXUserdata().tree() ); } this.connection.send( pres.tree() ); this.user_list[room] = []; } Chat.prototype.leaveRoom = function(room) { if(!this.connected) return; this.connection.send( $pres( { from: this.connection.jid, to: room+'@conference.jabber.klavogonki.ru/' + Strophe.getNodeFromJid(this.connection.jid), type: 'unavailable' } ) .tree()); $$('#chat-'+room+' .messages > div > div').last().update(''); $$('#chat-'+room+' .userlist-content').last().update(''); } Chat.prototype.sendPrivateMsg = function(user_id, msg) { var user_name = this.cached_user_ids[user_id]; this.addMsgInList({ room: this.active_room, text: msg, user_id: this.params.user.id, time: new Date(), type: 'private', to: user_name, to_id: user_id}); this.connection.send( $msg( { from: Strophe.getNodeFromJid(this.connection.jid)+'@jabber.klavogonki.ru/web', to: user_id+'@jabber.klavogonki.ru/web', type: 'chat' } ) .c( 'body' ) .t( msg ) .up() .cnode( this.getXUserdata().tree() ) .tree() ); $('chat-'+this.active_room).select('input.text').last().value = '<'+user_name+'>'; } Chat.prototype.sendMsg = function(room) { if(!this.connected) return; var _this = this; var msg = $('chat-'+room).select('input.text').last().value; msg = msg.replace(/^ +$/,''); if(msg.length == 0) return; var to,type; var m = msg.match(/^<(.*?)>(.*)$/); msg = msg.replace(//,'>'); msg = msg.replace(/&/,'&'); if(m) { var user_id = null; msg = m[2]; var found_user_id = null; for( var i in this.cached_user_ids ) if(this.cached_user_ids[i] == m[1]) found_user_id = i; if(found_user_id) this.sendPrivateMsg(found_user_id, msg); else { new Ajax.Request('/.fetchuser', { parameters: { login: m[1]}, onSuccess: function(transport) { eval('var json='+transport.responseText+';'); if(!json.id) { popalert('Пользователь с таким именем не найден.'); return; } _this.cached_user_ids[json.id] = m[1]; _this.sendPrivateMsg(json.id, msg); }}); } } else { //if(Strophe.getNodeFromJid(this.connection.jid) == 21) // return; $('chat-'+room).select('input.text').last().value = ''; this.connection.send( $msg( { from: this.connection.jid, to: room+'@conference.jabber.klavogonki.ru', type: 'groupchat' } ) .c( 'body' ) .t( msg ) .up() .cnode( this.getXUserdata().tree() ) .tree() ); } } Chat.prototype.onMessage = function(msg) { var _this = this; var to = msg.getAttribute('to'); var from = msg.getAttribute('from'); var elems = msg.getElementsByTagName('body'); var room; if (elems.length > 0) { var body = elems[0]; var user_id, type; if(msg.getAttribute('type') == 'chat') { type = 'private'; user_id = Strophe.getNodeFromJid(from); room = this.active_room; } else { type = 'normal'; user_id = Strophe.getResourceFromJid(from); room = Strophe.getNodeFromJid(from); } var x = getElementByAttribute(msg, 'x', 'xmlns', 'klavogonki:userdata'); if(x) { var data = xml2array(x); if(data.user) { data.user = this.filterUserData(data.user); this.user_data[user_id] = data; } } if(!this.user_data[user_id]) return true; var time = new Date(); var x; if( x = getElementByAttribute(msg, 'x', 'xmlns', 'jabber:x:delay') ) { var m = x.getAttribute('stamp').match(/(\d{4})(\d{2})(\d{2})T(\d{2}):(\d{2}):(\d{2})/); time = new Date( Date.UTC(m[1],m[2],m[3],m[4],m[5],m[6]) ); } this.addMsgInList({ room: room, text: Strophe.getText(body), user_id: user_id, time: time, type: type }); } return true; } Chat.prototype.addMsgInList = function(args) { var user = this.user_data[args.user_id].user; var time = args.time.getHours() + ':' + args.time.getMinutes().format() + ':' + args.time.getSeconds().format(); var room_html = ''; if(args.type == 'game') room_html = '[заезд]'; if(args.type == 'private') { if(args.to) room_html = '[шепчет '+args.to+']'; else room_html = '[шепчет вам]'; } var cont_outer = $('chat-'+args.room).select('.messages > div').last(); var cont = $('chat-'+args.room).select('.messages > div > div').last(); var needScroll = (cont_outer.scrollTop+cont_outer.getHeight()) >= cont_outer.scrollHeight; args.text = args.text.replace(//g, '>'); // game link parse args.text = args.text.replace(/http:\/\/(?:www\.)?klavogonki\.ru\/play\/\?gmid=(\d+)\&?/g, '[Заезд #$1]'); args.text = args.text.replace(/http:\/\/([^ ]*)/g, 'http://$1'); // мат if(this.filter) { var replace_str = '$1[вырезано]'; args.text = args.text.replace(/­/g,''); args.text = ' '+args.text+' '; args.text = args.text.replace(/([^а-яА-Я])[а-яА-Я]*[хxΧ]+[уy]+[eеийяё]+[а-яА-Я]*(?=[^а-яА-Я])/gi, replace_str); args.text = args.text.replace(/([^а-яА-Я])[хxΧ]+[уy]+ю+[а-яА-Я]*(?=[^а-яА-Я])/gi, replace_str); args.text = args.text.replace(/([^а-яА-Я])[а-яА-Я]*м+у+д+[^рс]+[а-яА-Я]*(?=[^а-яА-Я])/gi, replace_str); args.text = args.text.replace(/([^а-яА-Я])[а-яА-Я]*[аеeoиоуыьъ]+[eеё]+б+[а-яА-Я]*(?=[^а-яА-Я])/gi, replace_str); args.text = args.text.replace(/([^а-яА-Я])[eеё]+б+[а-яА-Я]*(?=[^а-яА-Я])/gi, replace_str); args.text = args.text.replace(/([^а-яА-Я])[а-яА-Я]*п+[иeеё]+[cсз]+д+[а-яА-Я]*(?=[^а-яА-Я])/gi, replace_str); args.text = args.text.replace(/([^а-яА-Я])[а-яА-Я]*б+л+я+д+[а-яА-Я]*(?=[^а-яА-Я])/gi, replace_str); args.text = args.text.replace(/([^а-яА-Я])б+л+я+[а-яА-Я]*(?=[^а-яА-Я])/gi, replace_str); args.text = args.text.replace(/([^а-яА-Я])[а-яА-Я]*п+и+д+[оеаeo]+[рp]+[а-яА-Я]*(?=[^а-яА-Я])/gi, replace_str); args.text = args.text.replace(/([^а-яА-Я])[а-яА-Я]*г+[aoао]+в+[eеё]*н+[а-яА-Я]*(?=[^а-яА-Я])/gi, replace_str); args.text = args.text.replace(/([^а-яА-Я])[cс]+ц*у+[кч]+[eеaoаои]+[а-яА-Я]*(?=[^а-яА-Я])/gi, replace_str); args.text = args.text.replace(/^ (.*) $/,'$1'); } // длинные строки while(/([^\/ ­]{40,})([^\/ ­]{40,})/.test(args.text)) { args.text = args.text.replace(/([^\/ ­]{40,})([^\/ ­]{40,})/, '$1­$2'); } args.text = args.text.replace(/­/, ''); // смайлы var smilies = { smile: /(:-\)|:\)|:smile:)/g, biggrin: /(:-D|:D|:biggrin:)/g, angry: /(>:\(|:angry:)/g, blink: /(oO|Oo|o_O|O_o|оО|Оо|о_О|О_о|:blink:)/g, blush: /:blush:/g, cool: /(8\)|:cool:)/g, dry: /:dry:/g, excl: /:excl:/g, happy: /(\^\^|\^_\^|:happy:)/g, huh: /:huh:/g, laugh: /:laugh:/g, mellow: /:mellow:/g, ohmy: /:ohmy:/g, ph34r: /:ph34r:/g, rolleyes: /:rolleyes:/g, sad: /(:\(|:-\(|:sad:)/g, sleep: /:sleep:/g, tongue: /(:P|:-P|:Р|:-Р|:tongue:)/g, unsure: /:unsure:/g, wacko: /(\%\)|:wacko:)/g, wink: /(;\)|;-\)|:wink:)/g, wub: /:wub:/g, first: /:first:/g, second: /:second:/g, third: /:third:/g, power: /:power:/g, badcomp: /:badcomp:/g, complaugh: /:complaugh:/g, girlnotebook: /:girlnotebook:/g, crazy: /:crazy:/g, boredom: /:boredom:/g, cry: /:cry:/g, bye: /:bye:/g, dance: /:dance:/g, gamer: /:gamer:/g, rofl: /:rofl:/g, beer: /:beer:/g, kidtruck: /:kidtruck:/g, angry2: /:angry2:/g, spiteful: /:spiteful:/g, sorry: /:sorry:/g, boykiss: /:boykiss:/g, girlkiss: /(:girlkiss:|:\*|:-\*)/g, kissed: /:kissed:/g, yes: /:yes:/g, no: /:no:/g, hi: /:hi:/g, ok: /:ok:/g }; for(var name in smilies) { args.text = args.text.replace(smilies[name], ':'+name+':'); } args.text = args.text.replace(/script/g, 'sсript'); if(args.type == 'system') cont.insert('

['+time+']Пользователь '+user.login+' '+args.text+'

'); else if(args.type == 'private') cont.insert('

['+time+']<'+user.login+'>'+room_html+''+args.text+'

'); else cont.insert('

['+time+']<'+user.login+'>'+room_html+args.text+'

'); // ссылки на игры var links = cont.select('.gamelink-not-resolved'); for(var i=0;i b_login ? 1 : 0 ) ); } ); var html = ''; for(var i in this.user_list[room]) { var user_id = this.user_list[room][i]; if(typeof user_id == 'function') continue; if(user_id == 21) continue; var item = this.user_data[user_id]; var avatar_html = ''; if(item.user.avatar) avatar_html = 'style="background: transparent url('+item.user.avatar+') no-repeat 0% 0%"'; var game_html = ''; if(item.game_id && room == 'general' ) game_html = 'в игре'; var moderator_tools = ''; if(room == 'general' && this.params.user && this.params.user.moderator) moderator_tools = ' '; var icons = ''; if(item.user.moderator) icons += ''; html += ''+item.user.login+''+icons+moderator_tools+game_html+''; } $('chat-'+room).select('.userlist-content').last().update(html); } Chat.prototype.insertPrivate = function(user_id) { var input = $('chat-'+this.active_room).select('input.text').last(); input.value = '<'+this.user_data[user_id].user.login+'>'; input.focus(); } Chat.prototype.insertPrefix = function(user_id) { var input = $('chat-'+this.active_room).select('input.text').last(); input.value += this.user_data[user_id].user.login+', '; input.focus(); } Chat.prototype.kick = function(user_id) { var item = this.user_data[user_id]; var _this = this; popconfirm('Заблокировать пользователя '+item.user.login+' на
Причина: ', function() { new Ajax.Request('/ajax/chat-kick', { parameters: { user: user_id, period: $('chat_kick_period').value, reason: $('chat_kick_reason').value}, onSuccess: function() { _this.connection.send( $iq( { from: _this.connection.jid, id: 'kick1', to: 'general@conference.jabber.klavogonki.ru', type: 'set' } ) .c( 'query', { xmlns: 'http://jabber.org/protocol/muc#admin' } ) .c( 'item', { nick: user_id, role: 'none' } ) .c( 'reason' ) .t( _this.params.user.login+':'+$('chat_kick_period').value+':'+$('chat_kick_reason').value ) .up().up().up() .tree() ); }}); }); } Chat.prototype.grantModerator = function(user_id) { this.connection.send( $iq( { from: this.connection.jid, id: 'admin1', to: 'general@conference.jabber.klavogonki.ru', type: 'set' } ) .c( 'query', { xmlns: 'http://jabber.org/protocol/muc#admin' } ) .c( 'item', { jid: user_id+'@jabber.klavogonki.ru', affiliation: 'admin' } ) .up().up() .tree() ); this.connection.send( $iq( { from: this.connection.jid, id: 'mod1', to: 'general@conference.jabber.klavogonki.ru', type: 'set' } ) .c( 'query', { xmlns: 'http://jabber.org/protocol/muc#admin' } ) .c( 'item', { nick: user_id, role: 'moderator' } ) .up().up() .tree() ); } Chat.prototype.revokeModerator = function(user_id) { this.connection.send( $iq( { from: this.connection.jid, id: 'admin2', to: 'general@conference.jabber.klavogonki.ru', type: 'set' } ) .c( 'query', { xmlns: 'http://jabber.org/protocol/muc#admin' } ) .c( 'item', { jid: user_id+'@jabber.klavogonki.ru', affiliation: 'member' } ) .up().up() .tree() ); this.connection.send( $iq( { from: this.connection.jid, id: 'mod2', to: 'general@conference.jabber.klavogonki.ru', type: 'set' } ) .c( 'query', { xmlns: 'http://jabber.org/protocol/muc#admin' } ) .c( 'item', { nick: user_id, role: 'participant' } ) .up().up() .tree() ); } Chat.prototype.filterUserData = function(user) { user.login = user.login.replace(/[^a-zA-Z0-9_\-а-яА-Я]*/g, ''); user.login = user.login.substr(0,16); if(!/^http:\/\/img.klavogonki.ru\/avatars\/\d+\.gif$/.test(user.avatar)) user.avatar = ''; if(!/\#[A-Fa-f\d]+$/.test(user.background)) user.background = ''; return user; }