New Content - Implemented KoLmafia doesn't fully support KoL's built-in tabbed chat

Bale

Minion
If there are people on here who are experiencing these bugs routinely (as in, you can replicate them on demand), I would love it if you could post the chat frame's source code on here so I can see if there are javascript differences that can explain it. Remember, it is not the source code for the whole page I need, just the chat frame (right click > this frame > view frame source).

Had the bug again. Refreshing did not fix it. Jarred it back into operation with /help. Before the page was refreshed I grabbed the source for you:

Code:
<!doctype html>
<html>
<head>
<title>LoathingChat</title>
<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<link rel="stylesheet" type="text/css" href="http://images.kingdomofloathing.com/styles.css">
<style type=text/css>
	input.text, textarea {
  		border: 1px black solid;
  		font-family: Arial, Helvetica,  sans-serif;
  		font-size: 10pt;
	}

	#tabs span.label {
		font-weight: bold;
	}


	
	#tabs .tab {
		font-size: 12px;
		display: inline-block;
		padding: 4px;
		height: 14px;
		border: 1px solid black;
		margin-right: 2px;
		margin-bottom: 2px;
		min-width: 30px;
		text-align: center;
		background-color: #eee;
		cursor: pointer;
		position: relative;
	}

	.tab .count { 
		display: none;
	}
	
	#tabs .unread .count { 
		display: block;
		background-color: #c00;
		color: #fff;
		border: 1px solid #600;
		position: absolute;
		right: -5px;
		top: -7px;
		padding: 2px;
		font-size: 9px;
		-moz-border-radius: 4px;
		-webkey-border-radius: 4px;
		-o-border-radius: 4px;
		border-radius: 4px;
		-webkit-box-shadow: 1px 1px 1px 1px rgba(100, 100, 100, .5);
		-moz-box-shadow: 1px 1px 1px 1px rgba(100, 100, 100, .5);
		box-shadow: 1px 1px 1px 1px rgba(100, 100, 100, .5);
	}

	#tabs.nounread .tab span.count { display: none; }

	#tabs.colortabs .unread {
		background-color: #fcc;
	}

	#tabs .active {
		/* font-weight: bold; */
		outline: 1px solid black;
		outline-width-bottom: 0px;
		background-color: #fff;
	}

	.event {color : green; }
	a.event, a.event:visited, a.event:active {color : green; }
	.pm {color : blue; } 
	.sys, .sys .player { color: red; }
	.warn, .warn .player { color: red; }
	.annc, .annc .player { color: green; }
	.welcome { color: green; font-style: italic; padding-bottom: 1em }

	.lastmark { width: 80%; }

	input.button {
  		border: 1px black solid;
  		font-family: Arial, Helvetica, sans-serif;
  		font-size: 9pt;
  		font-weight: bold;
  		background-color: #FFFFFF;
	}
	body {
		padding: 0px;
		spacing: 0px;
	}
	a, a:active, a:visited { text-decoration: none; color: black; }
	a.itemlink {
		color: blue !important;
		text-decoration: underline !important;
	}
	.chatdisplay {
		position: absolute;
		padding: 4px;
		spacing: 0px;
		top: 2px;
		left: 2px;
		font-family: arial;
		width: 100%;
		font-size: 12px;
		height: 300;
		border: 1px solid black;
		overflow-y: scroll; 
		overflow-x: hidden; 
		overflow: auto;
		z-index: 1;
		padding-top: 18px;
	}
	.chatdisplay .header {
		position: fixed;
		top: 0px;
		left: 3px;
		width: 100%;
		height: 16px;
		background-color: #00f;
		color: #fff;
		text-align: left;
		font-weight: bold;
		font-size: 12px;
		z-index: 2;
	}
	.inputform {
		position: absolute;
		border: 1px solid black;
		bottom: 2px;
		left: 2px;
		padding: 2px;
		spacing: 0px;
	}
	.tiny { font-size: 8pt; }
	.small { font-size: 10pt; }
	.nounder { text-decoration: none; }

	div.rcm {
        	position: absolute;
        	font-family: Arial;
        	font-size: 10pt;
        	border: 1px solid black;
        	background-color: #fff;
        	display: none;
			z-index: 99;
	}
	
	p.rcm {
        	cursor: pointer;
        	background-color: white;
        	margin: 0px;
        	padding: 0px 2px;
	}
	
	p.rcm:hover {
        	background-color: #ccccff;
	}

	.afk { font-style: italic; 	filter: alpha(opacity=50); -khtml-opacity: 0.5; -moz-opacity: 0.5; opacity: 0.5; background-color: #ddd; }

	.player {font-weight: bold; }
</style>
<script type="text/javascript" src="/images/scripts/jquery-1.5.1.js"></script>
<script type="text/javascript" src="/images/scripts/jquery-ui-1.8.18.custom.min.js"></script>
<script type="text/javascript" src="/images/scripts/window.js"></script>
<script type="text/javascript" src="/images/scripts/cookie.20100120.js"></script>
<script type="text/javascript">
// ====================================================================
//       URLEncode and URLDecode functions
//
// Copyright Albion Research Ltd. 2002
// http://www.albionresearch.com/
//
// You may copy these functions providing that 
// (a) you leave this copyright notice intact, and 
// (b) if you use these functions on a publicly accessible
//     web site you include a credit somewhere on the web site 
//     with a link back to http://www.albionresarch.com/
//
// If you find or fix any bugs, please let us know at albionresearch.com
//
// SpecialThanks to Neelesh Thakur for being the first to
// report a bug in URLDecode() - now fixed 2003-02-19.
// ====================================================================
function URLEncode(x)
{
	// The Javascript escape and unescape functions do not correspond
	// with what browsers actually do...
	var SAFECHARS = "0123456789" +					// Numeric
					"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +	// Alphabetic
					"abcdefghijklmnopqrstuvwxyz" +
					"-_.!~*'()";					// RFC2396 Mark characters
	var HEX = "0123456789ABCDEF";

	var plaintext = x;
	var encoded = "";
	for (var i = 0; i < plaintext.length; i++ ) {
		var ch = plaintext.charAt(i);
		if (ch=="+") {
			encoded+="%2B";
		} else if (ch == " ") {
		    encoded += "+";				// x-www-urlencoded, rather than %20
		} else if (SAFECHARS.indexOf(ch) != -1) {
		    encoded += ch;
		} else {
		    var charCode = ch.charCodeAt(0);
			if (charCode > 255) {
			    alert( "Unicode Character '" + ch + "' cannot be encoded using standard URL encoding.\n" +
				        "(URL encoding only supports 8-bit characters.)\n" +
						"A space will be substituted." );
				encoded += "+";
			} else {
				encoded += "%";
				encoded += HEX.charAt((charCode >> 4) & 0xF);
				encoded += HEX.charAt(charCode & 0xF);
			}
		}
	} // for

	return encoded;
};
var $cw,
	$inp,
	$tabs,
	CHMAX = 20,
	chpointer = -1,
	chcurrent = null,
	delay = 5000,
	lastdelay = 5000,
	chistory = [],
	payingattention = true,
	timer,
	lastrequest,
	KEYS = {
		0: 'shiftKey',
		1: 'ctrlKey',
		2: 'altKey',
		3: 'notAKey'
	},
	opts = {
		event: 'active',
		public: 'own',
		private: 'own',
		updatetitle: 0,
		showtimes: 1,
		marklast: true,
		active: "clan",
		modifier: 0,
		unreadbadges: 1,
		colortabs: 0,
		channeltag: 0,
		alwayswho: 0,
		buffer: 500,
		foo: 1

	},
	todo = [],
	playerid = 754005,
	pwdhash = "9721f0cdcb9f21e6a0b2f8822441187c";

var log = function (str) {
	if (typeof console != 'undefined' && console.log) console.log(str);
};

var msgTemplates = {
	public99: $('<div class="msg welcome"><span class="guts"></span></div>'),
	public98: $('<div class="msg event"><span class="guts"></span></div>'),
	public0: $('<div class="msg"><a class="player" target="mainpane"></a>: <span class="guts"></span></div>'),
	public1: $('<div class="msg emote"><span class="guts"></span></div>'),
	public2: $('<div class="msg sys"><a class="player" target="mainpane">System Message</a>: <span class="guts"></span></div>'),
	public3: $('<div class="msg warn"><a class="player" target="mainpane"></a>: <span class="guts"></span></div>'),
	public4: $('<div class="msg annc"><a class="player" target="mainpane">Mod Announcement</a>: <span class="guts"></span></div>'),
	private: $('<div class="msg pm"><a class="player" target="mainpane"></a>: <span class="guts"></span></div>'),
	event: $('<div class="msg event"><span class="guts"></span></div>'),
	system: $('<div class="msg sys"><a class="player" target="mainpane">System Message</a>: <span class="guts"></span></div>')
};

var formatMessage = function (msg) {
	var key = msg.type;
	if (key == 'public') key += msg.format;
	var out = msgTemplates[key].clone();
	if (msg.who) {
		out.find('.player').text(msg.who.name)
			.attr('href', 'showplayer.php?who='+msg.who.id)
			.css('color', msg.who.color || '');
	}

	if ((opts.channeltag || msg.ctag) && msg.channel) {
		var ctag = $('<span class="ctag"></span>').text('['+msg.channel+'] ');
		if (msg.channelcolor) ctag.css('color', msg.channelcolor);
		out.prepend(ctag);
	}

	if (opts.showtimes && msg.time) {
		var d = new Date(msg.time*1000);
		var h = d.getHours();
		var m = d.getMinutes();
		var s = d.getSeconds();
		if (m < 10) m = '' + 0 + m;
		if (s < 10) s = '' + 0 + s;
		var ttag = $('<span class="time"></span>').text('[' + h+ ':' + m + '] ');
		out.prepend(ttag);
	}

	if (msg.type =='event' && msg.link) {
		out.find('.guts').wrap('<a href="'+msg.link+'" target="mainpane" class="event" />');
	}
	out.find('.guts').html(msg.msg);
	return out;
};

var tabs = {};

var addTab = function (tab) {
	var link = $('<a><span class="label"></span><span class="count">0</span></a>')
		.addClass('tab')
		.data('tab', tab)
		.find('span.label').text(tab.data('label')).end();
			
	tab.data('handle', link);
	if ($('.tab', $tabs).length == 0) link.addClass('active')
	$tabs.append(link);
	sizing();
	return tab;
};

var getTab = function(msg) {
	var tkey = msg.type;
	if (msg.type == 'public') tkey += '-' + msg.channel;
	else if (msg.type == 'private' && msg['for']) tkey += '-' + msg['for'].id;
	else tkey += '-' + msg.who.id;

	if (tabs[tkey]) return tabs[tkey];

	var div = $('<div />').addClass('chatdisplay')
		.attr('id', tkey)
		.data('label', msg.type=='public'? msg.channel : (msg['for'] ? msg['for'].name : msg.who.name))
		.data('tkey', tkey)
		.data('type', msg.type);

	div.append($('<div class="header"></div>').html(' ' + div.data('label')));
	tabs[tkey] = div;

	$('body').append(tabs[tkey]);

	for (var i in tabs) {
		if (tabs.hasOwnProperty(i)) {
			tabs[tkey].hide();
			break;
		}
	}

	var showmain = false;
	for (i in opts) {
		if (opts[i] == 'main') {
			showmain = true;
			break;
		}
	}
	if (showmain && !tabs['main']) {
		$cw.data('label', 'events')
			.data('tkey', 'main')
			.data('type', 'main');
		tabs['main'] = $cw;
		$cw.append($('<div class="header"></div>').html(' events'));
		sizing();
		addTab($cw);
	}

	if (opts.alwayswho && msg.type == 'public') {
		submitchat('/who ' + msg.channel);
	}
	return addTab(tabs[tkey]);
};

var whereIGo = function (msg) {
	var where = opts[msg.type == 'system' ? 'event' : msg.type];
	switch (where) {
		case 'main': 
			if (msg.type == 'public') { msg.ctag = true}; 
			return $cw;
		case 'own': return getTab(msg);
		case 'active': return $('.chatdisplay:visible');
		//default: console.log('missing! ' + where); return $cw;
	}
};

var handleMessage = function (msg, nocount) {
	var where = whereIGo(msg);
	var toscroll = (where[0].scrollHeight - (where[0].scrollTop + where[0].offsetHeight) < 4);

	where.eq(0).append(formatMessage(msg));
	var h = where.data('handle');
	if (h && !nocount && (!msg.who || (msg.who.id != playerid)) && !msg.notnew) {
		if (!h.hasClass('active')) { h.addClass('unread'); }
		if (!h.hasClass('active') || !payingattention) {
			var n = 1 + parseInt(h.find('.count').text());
			h.find('.count').text(n);
		}
	}
	if (where.css('display') != 'none' && toscroll) {
		where[0].scrollTop = where[0].scrollHeight;
	}
};

var updateUnread = function () {
	if (opts.updatetitle) {
		var total = 0;
		$('#tabs .count').each(function () {
			total += parseInt($(this).text());
		});
		window.top.document.title = '(' + total + ') ' + opts.titlecache;
	}
};

var lastlast = null;
var gotChat = function (res) {
	if (!res || res == null) return;
	if (res.last == lastlast) return;
	delay = parseInt(res.delay);
	if (delay < 1 ||delay > (60*1000)) delay = 5000;
	for (var i=0; i<res.msgs.length; i++) {
		handleMessage(res.msgs[i]);
	}

	lastlast = res.last;
	updateUnread();
	$('.chatdisplay').each(function () {
		var $c = $(this);
		var cnt = $c.find('div.msg').size();
		if (cnt > opts.buffer) {
			$c.find('div.msg:lt('+(cnt - opts.buffer)+')').remove();
		}
	});
};

var cycle = function () {
	//if (lastrequest && !lastrequest.status) return;
	if (lastdelay != delay) {
		clearInterval(timer);
		timer = setInterval(cycle, delay);
	}
	lastrequest = $.ajax({
		url: '/newchatmessages.php?j=1',
		dataType: 'json',
		success: gotChat,
		timeout: 5000
	});
	lastdelay = delay;
};


var sizing = function () {
	var	th = $('#tabs').height(),
		h = ($(document).height() - $tabs.height() - (th ? 26 : 18) - $('#InputForm').height() - 16),
		w = Math.max(150, $('body').width() + 2),
		t = (th +8);
	$('#InputForm').css({ width: w + 4 });
	$('.chatdisplay').css({ width: w, height: h, top: t });
	$('.chatdisplay .header').css({ top: t +1, width: w + 8});
};

var nextAction = function () {
	var next_todo = todo.shift();
	if (next_todo) {
		try { eval(next_todo); } catch (e) {}
	}
}

var handleClientSide = function (msg) {
	if (msg.match(/^\/exit/)) {
		document.location = 'chatlaunch.php';
		return true;
	}
	else if (msg.match(/^\/(clearall|clsa)/)) {
		$('.chatdisplay > :not(.header)').remove();
		return true;
	}
	else if (msg.match(/^\/(cls|clear)/)) {
		$('.chatdisplay:visible > :not(.header)').empty();
		return true;
	}
	else if (msg.match(/^\/(\?|help)/)) {
		window.open("doc.php?topic=modern_chat","","height=400,width=550,scrollbars=yes,resizable=yes");
		return true;
	}
	else if (msg.match(/^\/close$/) || msg.match(/^\/close /)) {
		$('.chatdisplay:visible').data('handle').dblclick();
		return true;
	}
	else if (msg.match(/^\/mark/)) {
		var d = new Date();
		$('.chatdisplay:visible').append("<center class=tiny>——— " + d.getHours() + ":" + (d.getMinutes() < 10 ? "0" + d.getMinutes() : d.getMinutes()) + ":" + (d.getSeconds() < 10 ? "0" + d.getSeconds() : d.getSeconds()) + " ———</center>");
		return true;
	}


	return false;
};

var channelize = function (msg) {
	if (handleClientSide(msg)) {
		return false;
	}
	var mparts = msg.split(' ');

	var aid = $('.chatdisplay:visible').attr('id');
	var parts = aid.split('-');
	if (mparts.length == 1 && mparts[0] == '/who') return '/who ' + parts[1];
	else if (mparts.length == 1 && mparts[0] == '/whois' && parts[0] == 'private') return '/whois ' + parts[1];
	else if (parts.length < 2) return msg;
	else if (mparts.length >= 2 && mparts[0] == '/whois') return msg;


	if (mparts[0].match(/^\//) && !mparts[0].match(/^\/(me|em|who|ann|announce|warn)/)) {
		return msg;

	}

	if (parts[0] == 'public') return '/' + parts[1] + ' ' + msg;
	else if (parts[0] == 'private') return '/msg ' + parts[1] + ' ' + msg;
	else return msg;
}

var jstest = /<!--js\((.+?)\)-->/g;
var submitchat = function (over, cb) {
	var txt = $inp.val();
	if (over && typeof over != 'object') txt = over;
	else {
		$inp.val('');
		over.preventDefault();
	}

	if (txt == '') return;

	txt = channelize(txt);
	if (txt === false) return;

	chistory.unshift(txt);
	if (chistory.length > CHMAX) { chistory.pop(); }
	chpointer = -1;
	chcurrent = null;

	var url = '/submitnewchat.php?playerid='+playerid+'&pwd='+pwdhash+'&graf='+URLEncode(txt)+'&j=1';
	$.get(url, function (resp) {
		if (resp && resp.output) {
		   	var d = $('.chatdisplay:visible');
			if (resp.channel && tabs['public-'+resp.channel]) {
				d = tabs['public-'+resp.channel];
			}
		   	d.append('<div class="msg">'+resp.output+'</div>');
			d[0].scrollTop = d[0].scrollHeight;
		}
		if (resp && resp.msgs) {
			for (var i=0; i<resp.msgs.length; i++) handleMessage(resp.msgs[i]);
		}
		var ev;
		while (ev = jstest.exec(resp.output)) {
			var cmd = ev[1];
			if (cmd.indexOf('dojax') == -1) cmd += ';setTimeout(nextAction,3000)';
			todo.push(cmd);
		}
		if (cb) cb();
		nextAction();
		$inp[0].focus();
		cycle();
	},'json');

};

var handleKeys = function (e) {
	if (e[KEYS[opts.modifier]]) {
		if (e.which == 37 || e.which == 39) {
			var c;
			if (e.which == 37) {
				e.preventDefault();
				c = $('#tabs .active').prev();
				if (!c.length) c = $('#tabs .tab:last');
			}
			else if (e.which == 39) {
				e.preventDefault();
				c = $('#tabs .active').next();
				if (!c.length) c = $('#tabs .tab:first');
			}
			if (c) c.click();
		}
		if (e.which == 38 || e.which == 40) {
			e.preventDefault();
			if (chpointer == -1) {
				chcurrent = $inp.val();
			}
			if (e.which == 38) {
				chpointer++;
				if (chpointer >= CHMAX || !chistory[chpointer]) {
					chpointer = -1;
					tosee = chcurrent;
				}
				else { tosee = chistory[chpointer]; }
			}
			else if (e.which == 40) {
				chpointer--;
				if (chpointer == -1) {
					tosee = chcurrent;
				}
				else if (chpointer < 0) { 
					chpointer = chistory.length - 1;
					tosee = chistory[chpointer];
				}
				else {
					tosee = chistory[chpointer];
				}
			}
			$inp.val(tosee);
		}
	}
};

var todo = [];
function nextAction() {
	var next_todo = todo.shift();
	if (next_todo) {
		eval(next_todo);
	}
}
function dojax(dourl, afterFunc, hoverCaller, failureFunc) {
	$.ajax({
		type: 'GET', url: dourl, cache: false,
		global: false,
		success: function (out) {
			nextAction();
			if (out.match(/no\|/)) {
				var parts = out.split(/\|/);
				if (failureFunc) failureFunc(parts[1]);
				else $('#ChatWindow').append('<font color="green">Oops!  Sorry, Dave, you appear to be ' + parts[1] + '.</font><br />' + "\n");
				return;
			}

			if (hoverCaller)  {
				float_results(hoverCaller, out);
				if (afterFunc) { afterFunc(); }
				return;
			}			var $eff = $(top.mainpane.document).find('#effdiv');
			if ($eff.length == 0) {
				var d = top.mainpane.document.createElement('DIV');
				d.id = 'effdiv';
				var b = top.mainpane.document.body;
				if ($('#content_').length > 0) {
					b = $('#content_ div:first')[0];
				}
				b.insertBefore(d, b.firstChild);
				$eff = $(d);
			}
			$eff.find('a[name="effdivtop"]').remove().end()
				.prepend('<a name="effdivtop"></a><center>' + out + '</center>').css('display','block');
			if (!window.dontscroll || (window.dontscroll && dontscroll==0)) {
				top.mainpane.document.location = top.mainpane.document.location + "#effdivtop";
			}
			if (afterFunc) { afterFunc(); }
		}
	});
}var actions = { "sendmessage.php" : { "action" : 1, "title" : "Send Message", "arg" : "toid" }, "makeoffer.php" : { "action" : 1, "title" : "Propose Trade", "arg" : "towho" }, "skills.php" : { "action" : 1, "title" : "Buff", "arg" : "towho" }, "mallstore.php" : { "action" : 1, "title" : "Mall Store", "arg" : "whichstore" }, "displaycollection.php" : { "action" : 1, "title" : "Display Case", "arg" : "who" }, "ascensionhistory.php" : { "action" : 1, "title" : "Ascension History", "arg" : "back=other&who" }, "curse.php" : { "action" : 1, "title" : "Brick 'Em, Dano", "arg" : "whichitem=1649&targetplayer" }, "/./curse.php" : { "action" : 1, "title" : "Throw TP", "arg" : "whichitem=1923&targetplayer" }, "/./././curse.php" : { "action" : 1, "title" : "Send Candy Heart", "arg" : "randomheart=1&targetplayer" }, "/whois" : { "action" : 2, "useid" : false, "submit" : true}, "/msg" : { "action" : 3, "useid" : true, "query" : "Enter message to send to %:" }};
var notchat = false;
jQuery(function ($) {
	$cw = $('#ChatWindow');
	$inp = $('#graf');
	$tabs = $('#tabs');
	$(window).resize(sizing);
	$('#tabs .tab').live('click', function (e) {
		e.preventDefault();
		if (opts.marklast) {
			$('.chatdisplay:visible').find('hr.lastmark').remove()
					.end().append('<hr class="lastmark" />');
		}
		$('.chatdisplay').hide();
		$('#tabs .tab').removeClass('active');
		var w = $(this).data('tab');
		w.show();
		w[0].scrollTop = w[0].scrollHeight;
		$(this).removeClass('unread').addClass('active').find('.count').text(0);
		updateUnread();
		$inp[0].focus();
	}).live('dblclick', function (e) {
		e.preventDefault();
		if (confirm('Click OK to close this tab.')) {
			var k = $(this).data('tab').attr('id');
			var parts = k.split('-');
			var tb = this;
			var endtab = function () {
				delete tabs[k];
				$(tb).data('tab').remove();
				$(tb).remove();
				sizing();
				if ($('.chatdisplay:visible').length) return;
				$('#tabs .tab:first').click();
			};
			if (parts[0] == 'public') {
				submitchat('/listenoff ' + parts[1], endtab);
			} else endtab();
		}
	});

	$('#InputForm').parent().submit(submitchat);
	sizing();
	handleMessage({type:'event', 
		msg: 
		'<span class="welcome">Welcome to <B>LoathingChat</b> version 0.9302<br />' +
		'Click a tab to switch, double-click to close (and unlisten to) a channel.<br />' +
		'Shift-left and right to change tabs, shift-up and down for chat history.<br />' +
		'Click and drag to rearrange tabs.<br />' +
		'Type /? or /help for more information.<br />' +
		'There are some <a style="font-weight: bold; text-decoration: underline" href="/account.php?tab=chat" target="mainpane" style="font-weight: bold">Configuration options</a>.<br />' +
		'<br />' +
		'</span>' +
		''
	});
	if (opts.updatetitle) {
		if (!window.top || !window.top.document || !window.top.document.title) {
			opts.updatetitle = false;
		}
	}
	opts.titlecache = window.top.document.title.replace(/^.*The/,'The');

	if (!opts.unreadbadges) {
		$('#tabs').addClass('nounread');
	}
	if (opts.colortabs) {
		$('#tabs').addClass('colortabs');
	}

	$(document).keyup( handleKeys );
	$(window.top || window).focus(function () { 
		payingattention = true;
		$('#tabs .active .count').text(0);
	}) .blur(function () { payingattention = false; });

	handleMessage({type:'public', format: '99', channel: 'clan', msg: "This is a chat channel that only members of your clan can use."}, true);
	handleMessage({type:'public', format: '99', channel: 'haiku', msg: "Speak in haiku here,<br>and haiku <i>only</i>, mind you,<br>or you\'ll get banz0red."}, true);
	handleMessage({type:'public', format: '99', channel: 'hardcore', msg: "This is a channel to chat with other players who have completed at least one hardcore ascension."}, true);
	handleMessage({type:'public', format: '99', channel: 'trade', msg: "This channel is dedicated to the exchange of goods and services.  And Meat."}, true);

	if (opts.event == 'active') {
		$('#tabs .tab:first').click();
		var m = $('#ChatWindow .welcome');
		$('.chatdisplay:visible').prepend(m.clone());
		m.remove();
	}

	$('#tabs').sortable({
		appendTo: 'body',
		stop: function (e, ui) {
			var diff = Math.abs(ui.position.left - ui.originalPosition.left);
			if (diff < 10) ui.item.click();
		}
	});
	cycle();
	timer = setInterval(cycle, delay);
		
	$inp[0].focus();

});
</script>
<script type="text/javascript" src="/images/scripts/rcm.20101215.js"></script>
<script language="Javascript" src="/basics.js"></script><link rel="stylesheet" href="/basics.css" /></head>
<body>
	<div id="tabs"></div>
	<div id="ChatWindow" class="chatdisplay">
	</div>
	<form>
		<div id="InputForm" class="inputform">
			<center>
				<input style="width: 70%;" maxlength="200" class="text" type="text" size="12" name="graf" id="graf" autocomplete="off">
				<input class="button" type="submit" value="Chat">
			</center>
		</div>
	</form>
	<div id='menu' class='rcm'></div>
<div id='menu' class='rcm'></div></body>
</body>
<script language="Javascript"> var actions = { "sendmessage.php" : { "action" : 1, "title" : "Send Message", "arg" : "toid" }, "makeoffer.php" : { "action" : 1, "title" : "Propose Trade", "arg" : "towho" }, "skills.php" : { "action" : 1, "title" : "Buff", "arg" : "towho" }, "mallstore.php" : { "action" : 1, "title" : "Mall Store", "arg" : "whichstore" }, "displaycollection.php" : { "action" : 1, "title" : "Display Case", "arg" : "who" }, "ascensionhistory.php" : { "action" : 1, "title" : "Ascension History", "arg" : "back=other&who" }, "curse.php" : { "action" : 1, "title" : "Brick 'Em, Dano", "arg" : "whichitem=1649&targetplayer" }, "/./curse.php" : { "action" : 1, "title" : "Throw TP", "arg" : "whichitem=1923&targetplayer" }, "/./././curse.php" : { "action" : 1, "title" : "Send Candy Heart", "arg" : "randomheart=1&targetplayer" }, "/whois" : { "action" : 2, "useid" : false, "submit" : true}, "/msg" : { "action" : 3, "useid" : true, "query" : "Enter message to send to %:" }}; </script><script language="Javascript" src="/images/scripts/rcm.2.js"></script><script src="/onfocus.js"></script></html>
 

Veracity

Developer
Staff member
My messages through the relay browser also aren't logged in the mafia log.!
Bump. I've had two reports from clannies about issues with the new built-in tabbed chat:

- nothing goes into the chat log any more
- the Fax Request window complains that it never gets a response from FaxBot - even though the response is visible in chat.

I do notice that this bug report is still open. :)
 

Grotfang

Developer
The code I am writing for chat is progressing, but very slowly. If someone wants to do this, I am happy for them to do so. As it is, it will get there, but in time (probably quite a lot of it). I'm sorry for the lack of progress, but I have to put my course first, and I am currently working 12 hour days. A veterinary degree doesn't leave me with much spare time, sadly.

The way I have gone so far is to make the chat parser a specialised json parser. Since CDMoyer has suggested that old chat will eventually disappear, I am catching requests to the old system, moving them into the poller, and using the new system for them. Internally, I am keeping the old chat message structure (changing them slightly) and then can build a new or old-style response depending on what the browser asks for. That way, mafia will be immune to a KoL-side change and it also means that if there is a niche usage case for maintaining support for old-chat, mafia will be able to do so seemlessly (although we'd need to serve the frame html).

The parser is written and works, but is useless by itself. I am currently writing the formatter. The poller has been adapted as well as the relevant chat manager components. There is still an awful lot to do, though.
 

Veracity

Developer
Staff member
The way I have gone so far is to make the chat parser a specialised json parser.
Just want to check - you are aware that we have a JSON parser in our source tree already, right?

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

ApiRequest and VolcanoMazeManager use it.

I assume you mean that you are making the chat parser use it, too, for new chat.
 

Bale

Minion
Edited the thread title because the word "just" describing an update fourth months ago is making my mind flip out.
 

rlbond86

Member
"Receive A Fax" does not work with new tabbed chat

I tried switching to tabbed chat today to see if it worked. It seems to work perfectly except that the Fax GUI does not seem to detect the incoming messages from FaxBot since they are displayed differently.
 

Veracity

Developer
Staff member
Yes. I will merge this into the other "New Content" thread regarding the new tabbed chat, in which I reported this exact issue.
 

Lilac

Member
Tabbed chat does not produce chat logs since r10851

Was collaborating with a clanmate on this; her Mafia stopped logging chats around April 1, which is apparently when she got the daily build that included r10851, "Mirror KoL's requests when account options are set to tabbed chat". We did some basic testing, and it appears that Mafia will log the old chat just fine (with or without ActiveChat), but not tabbed chat.

All testing done on r11419 using only the relay browser's chat (i.e. not initializing chat through Mafia itself).
 

Veracity

Developer
Staff member
Yes. KoLmafia support for new tabbed chat remains incomplete. This exact issue is reported in the New Content thread discussing tabbed chat. This should be merged with that one.
 

Lilac

Member
My apologies. I looked back for all instances of "log" but should've actually used the forum search instead of just Ctrl+F.
 

lostcalpolydude

Developer
Staff member
Bumping this so that I can get started on fixing new chat. Unless grotfang (or someone else) says that they have made a lot of progress and plan to have something working soon.
 

Grotfang

Developer
Bumping this so that I can get started on fixing new chat. Unless grotfang (or someone else) says that they have made a lot of progress and plan to have something working soon.

That sounds great. I am unlikely to finish this. I don't even have time for KoL itself at the moment.
 

heeheehee

Developer
Staff member
I've thrown together a very basic patch for new chat. All I've really tested is that PMs and messages (including emotes) to /clan are logged correctly in chats; there's still a lot of work that needs to go into this (parsing msg.output, confirming integration with KoLmafia chat).

See attached.

edit: this *should* address the two issues Veracity brought up in #22.

edit edit: Confirmed that FaxBot works.
also, hmm, I forgot to remove a System.out.println.
 

Attachments

  • mchat.patch
    3.5 KB · Views: 26
Last edited:

Bale

Minion
heeheehee, did you test your patch for having chat open in both the relay browser and the mafia chat at the same time?
 

heeheehee

Developer
Staff member
No, I did not. Why?

edit: also, there was a slight bug in channel name -- I needed to add brackets manually. See attached for my current working copy, which fixes that and removes the println. I don't remember if I changed anything else.
 

Attachments

  • mchat.patch
    3.5 KB · Views: 22

Bale

Minion
heeheehee, did you test your patch for having chat open in both the relay browser and the mafia chat at the same time?

Because right now, when I have both open, some private messages directed to me go to my Mafia chat pane and some go to my relay browser. It is unpredictable and switches during a single conversation. It would be better if all messages went to both locations.
 

lostcalpolydude

Developer
Staff member
ChatPoller.handleNewChat() should probably only be called if the user is using new chat (or at least should immediately return otherwise), which could be done by getting chatversion from api.php (and just accepting that things will break until quickly fixed if yet another version of chat is released, since the newest version is 0, older is 1, and ancient is 2).

The stranger part of this is that, without looking at the existing chat code, it seems like mafia GUI integration and relay browser handling are using completely unconnected code (since this patch only touches relay browser handling). I don't know if older chat does something similar. I guess that isn't necessarily a problem if it all works...

I can try to test this some more in the next few days, but since I never use mafia's GUI for chat it will be hard for me to notice if anything isn't working properly there.
 

heeheehee

Developer
Staff member
Because right now, when I have both open, some private messages directed to me go to my Mafia chat pane and some go to my relay browser. It is unpredictable and switches during a single conversation. It would be better if all messages went to both locations.

Interesting, I would guess that Mafia uses older chat's API for polling, although I'm not sure why you wouldn't be able to see all messages in Mafia chat. My patch probably doesn't register messages in enough places.

I take it the two sets of messages are disjoint, though?
 
Top