Here we have yet another page of PsycZilla crap to clog the wiki


Finished or Abandoned PsycZilla stuff

Here lie the remains of our fallen Javascript heroes. Our hopes and our dreams, some fulfilled, some abandoned indefinitely.

Solved / Implemented

Modular Packet Handlers

Allow javascript code to be registered on a psyc entity in similar to the way that javascript event handlers are registered.

TODO: Add support for multiple listeners per mc

Session (global) scope:
  PsycSession.addPacketListener(mc, listenerFunctionOrObject);

UNI Scope (implemented in PsycPlace.js):
  place.addHandler(mc, listenerFunctionOrObject);

These handlers should be easily added by the user and the api well documented to encourage custom many extensions once there is a decent size user base.

To address inheritance and efficiency, I implemented the AbbrevHash idea as suggested by el.


Ideas and strategies for implementing the plug-in/mapping architecture.

Two-level mapping
Note: This has been abandoned in favor of the AbbrevHash method!

Perhaps a two-level mapping solution would be both efficient and powerful. Use the first segment of the mc to classify the message and then pass it to the appropriate Message Handler Chain for that message class. Each chain can contain any number of handlers which are linked to any mc suffix relevant to that class of message. The suffix can be general or specific and Method Inheritance would be supported by using mc.startsWith().

Some Examples:

//general: monitor all _notice_update messages

//more specific: monitor wiki updates: _notice_update_wiki 

//monitor errors

The advantage here is that we won't have to process the list of _notice handlers when we process a message with the _error message mc.

Further optimization could be done to improve on this design, however, the design needs to pay attention to the size of each handler chain as well as the complexity of the search algorithm. Hashing can be used to quickly find an exact match in a large collection of handlers. In order to do prefix matching we are limited to linear searching and a call to .startsWith for each registered handler. By reducing the size of the lists we reduce the processing time to find our match, however, there is not much benefit when list size is initially small. Also, by doing a two-level lookup we increase the complexity of the entire matching process and the added complexity has it's own performance cost.

Please add your own comments or ideas. This is a critical part of the overall design because it will be a high-traffic part of the api and any added efficiency will be multiplied by the number of messages processed.


Use hasing to match the prefix of an mc, the strategy is to match the full mc against the hash collection, if no match is found, then we progressively remove sections from the suffix, repeating the hash lookup until a match is found.

<Monkey 14:11, 28 June 2006 (CEST)> Thanks for the suggestion el! from Net::PSYC
<Monkey> Here I have implemented what should be essentially the same thing in JavaScript:
function McMap() {
	this.hash = {};

McMap.prototype = {

	set: function(key, val) {
		this.hash[key] = val;

	findExact: function(mc) {
		return this.hash[mc];
	findPrefix: function(mc) {
		var result = [];
		var mc_prefix = mc;
		while (mc_prefix) {
			var match = this.hash[mc_prefix];
			if (match) {
			mc_prefix = this.stripSuffix(mc_suffix);
		if (result.length > 0)
			return result;
			return false;

	stripSuffix: function(mc) {
		var idx = mc.lastIndexOf("_");
		if (idx < 1)
			return false;
		return mc.substring(0,idx);


This implementation is currently in CVS under chrome/content/lib/PsycPlace.js and it is used in the PsycSession object (socket.js)

Using Mozilla's Password Manager

I finally managed to get Password Manager to work with XULRunner! There are preferences that control whether Password Manager is enabled and how it behaves. There preferences are missing from XULRunner by default! Here is what I did:

		var prefs = Components.classes[";1"].getService(Components.interfaces.nsIPrefService);
		var signonBranch = prefs.getBranch("signon.");

		try {
			var rememberPref = signonBranch.getBoolPref("rememberSignons");
			if (!rememberPref)
		} catch (err) {


There is a slight distinction between routing variables like _target and _source_identification to end-to-end variables like _nick or _topic. As you probably noticed the server always sends them to you seperated by an empty line. As of now psyced is patient in accepting them mixed up, but we might one day have to change that. Although I'm trying to keep things simple for client coders, so maybe it well never change and the server simply keeps on putting them in the right buckets as it ever did. Bah, never mind. Keep on rockin'

<Monkey> Is the _place variable part of MMP or PSYC?

It's on the PSYC side, as an argument to _request_input or _execute. Only when something affects routing it happens in MMP. In your case it is pretty trivial: You only need to put the _target of the things you do in MMP, since _source is not relevant from a client to its server. Also _context is always generated by the context, never by you.

wanted: psyc icon

We need a psyc icon graphic. Any ideas? ?

hmm, why does no longer point to it.. have to fix that

or something bigger?

like minipsyc.png ?

<Monkey> Maybe both? - I was thinking about the little one but the bigger one could be used somewhere too! :)

<Monkey>I have the icon checked in under chrome/icons/default/psycwin_msg.ico. Would one of our linux hackers care to make an xpm version of that file, in the same location/name only using the .xpm extension? This way the window icon will work under linux as well! :)

/show in json

listAcqJson(ppltype, pplvalue) { // Acq(uaintance) to be renamed into Peer
	string person, *p;
#ifdef ALIASES
	string pdisp;
# define pdisp	person
	mixed mc,resultMsg;
	int i, s;

	p = m_indices(ppl);
	resultMsg = "{";
	for (i=sizeof(p)-1; i>=0; i--) {
		person = p[i];
		if (ppl[person] == "    ") {
			m_delete(ppl, person);
		} else {
#ifdef ALIASES
	// well, i wouldn't need to ;, but it helps the vim syntax parser
			DEALIAS(pdisp, person);

			if (resultMsg!= "{" )
				resultMsg = ",\n";
			resultMsg  = "'" person "':{'name':'" pdisp  "',";
			resultMsg  = "'trust':'"   ppl[person][PPL_TRUST] "',";
			resultMsg  = "'expose':'"   ppl[person][PPL_EXPOSE] "',";
			resultMsg  = "'notify':'"   ppl[person][PPL_NOTIFY] "',";
			resultMsg  = "'display':'"   ppl[person][PPL_DISPLAY] "'}";
			//walk_mapping(ppl, "walkJson", resultMsg);
#ifdef pdisp
# undef pdisp

Abandoned / Postponed

PsycZilla:Sidebar and other browser integration efforts have been pulled out for a cleaner v0.4 release. 0.4 is (not yet released) as of 9/6/2006. We expect more effective browser integration to make a significant appearance sometime within the next 100 years.