
Der Code ist noch im Teststadium und es wird sich sicher noch einiges ändern, aber da ich schon ein paar Tester bräuchte poste ich schonmal die derzeitige Version:
Script:Zeigen
Code: Alles auswählen
// Grundscriptsammlung
// V. 0.0.1
GSS = new (function () {
// Mit Global greifen wir auf öffentliche Funktionen zu und definieren diese auch innerhalb von GSS.
Global = this;
/* Funktionen */
// getChatData - lädt und speichert alle wichtigen Daten über den Chat und den eingeloggten User
Global.getChatData = function (interval, startStreamer)
{
var chatData = RegExp(/server(\d)\.webkicks\.de\/(\w+)\/(\w+)stream\/(\w+)\/.+\/\w+/).exec(parent.document.getElementsByName("mainframe")[0].src);
// Server, Chatname, Anmeldungsstatus, Nick (ohne Case Sensitive), erste Chateinstellungen (Raumsystem), Intervall für Streamer
Global.chat.server = chatData[1];
Global.chat.name = chatData[2];
Global.chat.rank = (chatData[3] == "guest_") ? 0 : 1;
Global.chat.nick = chatData[4];
Global.chat.settings[0] = (parent.ChannelFrame) ? 1 : 0;
Global.chat.streamInterval = interval;
// Auslesefunktionen für das Eingabeframe, die Onlineliste und, falls vorhanden, das Raumauswahlframe aufrufen
Global.getInputData();
Global.getOnlineData();
if (Global.chat.settings[0])
{
Global.getChannelData();
}
// Auslesen der Teamliste
Global.xmlRequest({
path:Global.chat.name+"/api/get_teamlist",
method:"GET",
func: function (r)
{
Global.getTeamData(r);
}
});
// Soll der Streamer standardmäßig gestartet werden?
if (startStreamer)
{
Global.startStreamer();
Global.chat.streaming = 1;
}
};
// getInputData - lädt und speichert alle relevanten Daten aus dem Eingabeframe
Global.getInputData = function ()
{
if (Global.inputLoaded())
{
var p = parent.info.document;
// eigenen Nick in Case Sensitive speichern
Global.chat.nick = Global.stripTags(p.getElementsByTagName("b")[p.getElementsByTagName("b").length-1].innerHTML);
// Ist der User Teammitglied und nicht Hauptadmin?
if (p.getElementsByTagName("a")[p.getElementsByTagName("a").length-1].innerHTML != "ALARM" && Global.chat.rank != 4)
{
Global.chat.rank = (p.getElementsByTagName("script")[0].innerHTML.match("function CallMenue")) ? 3 : 2;
}
// User-Objekt erstellen, falls noch nicht vorhanden
Global.updateUser(Global.chat.nick, {status: 1, rank: Global.chat.rank, color: Global.extractColors(p.getElementsByTagName("b")[p.getElementsByTagName("b").length-1])});
// Links und Einstellungen (Smileys, Topliste, Profile) auslesen
Global.chat.links = [];
Global.chat.settings = [0,0,0];
for (var i = 1; i < p.links.length; i++)
{
var link = RegExp(/^http:\/\/outlink\.webkicks\.de\/dref\.cgi\?url\=(.+)/i).exec(p.links[i].location);
if (link)
{
Cache.menuLinks.push([link[1], p.links[i].text]);
}
else if (p.links[i].location == "javascript:CallRL()")
{
Global.chat.settings[1] = 1;
}
else if (p.links[i].location == "http://server"+Global.chat.server+".webkicks.de/"+Global.chat.name+"/top/wk")
{
Global.chat.settings[2] = 1;
}
else if (p.links[i].location == "javascript:CallProfil()")
{
Global.chat.settings[3] = 1;
}
}
}
else
{
window.setTimeout(function () { GSS.getInputData() }, 500);
}
};
// getOnlineData - lädt und speichert alle relevanten Daten aus dem Onlineframe
Global.getOnlineData = function ()
{
if (Global.onlineLoaded())
{
// Daten zum derzeitigen Raum speichern
Global.chat.currentRoom = [RegExp(/server\d\.webkicks\.de\/cgi-bin\/ol\.cgi\?cid=\w+&raum=(.+)/).exec(parent.document.getElementsByName("rightFrame")[0].src)[1], []];
// User im Raum auslesen
var divs = parent.rightFrame.document.getElementById("bd:").getElementsByTagName("div");
for (var i = 0; i < divs.length; i++)
{
if (divs[i].id && !RegExp(/\W/i).test(divs[i].id))
{
Global.chat.currentRoom[1].push(divs[i].id);
// User-Objekt erstellen, falls noch nicht vorhanden
Global.updateUser(divs[i].id, {status: 1});
}
}
Global.chat.currentRoom[1].sort();
}
else
{
window.setTimeout(function () { GSS.getOnlineData() }, 500);
}
};
// getChannelData - lädt und speichert alle relevanten Daten aus dem Raumauswahl-Frame
Global.getChannelData = function ()
{
if (Global.channelLoaded())
{
// Zugängliche Räume auslesen
var options = parent.ChannelFrame.document.getElementsByTagName("option");
Global.chat.rooms = [];
for (var i = 0; i < options.length; i++)
{
Global.chat.rooms[i] = options[i].value.split(" ");
// Hauptchat als "main" speichern, Privatraum als "sep.NICK" (interne Raum-IDs, werden z.B. für das Onlineframe benötigt)
if (!Global.chat.rooms[i][1])
{
Global.chat.rooms[i] = "sep."+Global.chat.nick;
}
else if (Global.chat.rooms[i][1] == "Hauptchat")
{
Global.chat.rooms[i] = "main";
}
else
{
Global.chat.rooms[i] = Global.chat.rooms[i][1];
}
}
Global.chat.rooms.sort();
}
else
{
window.setTimeout(function () { GSS.getChannelData() }, 500);
}
};
// getTeamData - lädt und speichert alle relevanten Daten über das Team
// r - XMLHttpRequest-Objekt, das von xmlRequest weitergegeben wurde
Global.getTeamData = function (r)
{
if (r.readyState == 4)
{
Global.chat.team = [[],[],""];
var content = r.responseXML.documentElement;
// Mods auslesen
for (var i = 0; i < content.getElementsByTagName("mod").length; i++)
{
Global.chat.team[0].push(content.getElementsByTagName("mod")[i].firstChild.data);
// User-Objekt erstellen, falls noch nicht vorhanden
Global.updateUser(Global.chat.team[0][i], {rank: 2});
}
for (var i = 0; i < content.getElementsByTagName("admin").length; i++)
{
Global.chat.team[1].push(content.getElementsByTagName("admin")[i].firstChild.data);
// User-Objekt erstellen, falls noch nicht vorhanden
Global.updateUser(Global.chat.team[1][i], {rank: 3});
}
Global.chat.team[0].sort();
Global.chat.team[1].sort();
Global.chat.team[2] = content.getElementsByTagName("hauptadmin")[0].firstChild.data;
// User-Objekt erstellen, falls noch nicht vorhanden
Global.updateUser(Global.chat.team[2], {rank: 4});
// Bin ich Hauptadmin?
if (Global.chat.nick == Global.chat.team[2])
{
Global.chat.rank = 4;
}
}
};
// stripTags - entfernt HTML-Tags aus einem String
// str: zu bearbeitender String
Global.stripTags = function (str)
{
return str.replace(/<\/?[^>]+>/ig, "");
};
// stripScripts - entfernt Script- und Style-Tags samt Inhalt.
// str: zu bearbeitender String
Global.stripScripts = function (str)
{
return str.replace(/<(?:script|style)[^>]*>(?:.*)?<\/(?:script|style)>/ig, "");
};
// stripBadChars - Entfernt kritische Zeichen aus einem String
// str - zu bearbeitender String
Global.stripBadChars = function (str)
{
return str.replace(/</g, "<").replace(/>/g, ">").replace(/\"/g, """).replace(/\'/g, "'");
};
// stripRegExp - escaped spez. RegExp-Zeichen in einem String sodass der String als RegExp benutzbar wird
// str: zu bearbeitender String
Global.stripRegExp = function (str)
{
return str.replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1");
};
// stripReplacers - filtert alle Webkicks-Replacer in einem Textstring. Gibt ein Array mit dem neuen String und den Replacern (Name und Dateiendung) zurück.
// str - zu bearbeitender String
Global.stripReplacers = function (str)
{
reps = [];
while ((/<span onclick\=\"javascript: repClick\(\'[^\']+\'\)" style\=\"cursor: pointer;\"><img src=\"\/\w+\/replacer\/[^\.]+\.\w+\" alt\=\"\:[^\"]+\"><\/span>/i).test(str))
{
// Replacer speichern
reps.push(RegExp(/<span onclick\=\"javascript: repClick\(\'[^\']+\'\)" style\=\"cursor: pointer;\"><img src=\"\/\w+\/replacer\/([^\.]+)\.(\w+)\" alt\=\"\:[^\"]+\"><\/span>/i).exec(str).slice(1));
// Replacer aus String entfernen
str = str.replace(/<span onclick\=\"javascript: repClick\(\'[^\']+\'\)" style\=\"cursor: pointer;\"><img src=\"\/\w+\/replacer\/[^\.]+\.\w+\" alt\=\"(\:[^\"]+)\"><\/span>/i, "$1");
}
return [str, reps];
};
// stripSEVars - filtert die SE-Variablen %me% und %user% und ersetzt sie entsprechend mit ihren Text-Equalienten. Für %user% wird der entsprechende Usernick zurückgegeben.
// str - zu bearbeitender String, dontUpdate: bestimmt, ob Userobjekte geupdatet werden sollen
Global.stripSEVars = function (str, dontUpdate)
{
var vars = [];
// String als HTML-Element speichern
var dom = document.createElement("div");
dom.innerHTML = str;
for (var i = 0; i < dom.getElementsByTagName("b").length; i++)
{
var nickDom = dom.getElementsByTagName("b")[i];
var content = Global.stripTags(nickDom.innerHTML);
// Wir sind hier ziemlich vorsichtig, deshalb kommt nun eine seeehr lange Abfrage die unter anderem Länge, HTML-Inhalt und eine ganze Menge anderes Zeugs prüft :)
if (!nickDom.getElementsByTagName("b")[0] && !content.match(/\W/) && content.length < 21 && content.length > 1 && nickDom.firstChild.nodeName == "FONT" && (!nickDom.childNodes[1] && (!nickDom.firstChild.childNodes[1] && nickDom.firstChild.firstChild.nodeName == "#text" || nickDom.firstChild.childNodes[1] && nickDom.firstChild.firstChild.nodeName == "FONT" && nickDom.firstChild.lastChild.nodeName == "FONT") || nickDom.childNodes[1] && nickDom.firstChild.nodeName == "FONT" && nickDom.lastChild.nodeName == "FONT"))
{
if (dom.getElementsByTagName("b")[i].innerHTML == Cache.user[self.user[0]].color[1])
{
// %me%, gegebenenfalls Userobjekt erneuern
if (!dontUpdate)
{
Global.updateUser(Global.chat.nick, {color: Global.extractColors(nickDom)});
}
dom.getElementsByTagName("b")[i].innerHTML = "%me%";
}
else
{
// %user%, gegebenenfalls Userobjekt erneuern
if (!dontUpdate)
{
Global.updateUser(content, {color: Global.extractColors(nickDom)});
}
dom.getElementsByTagName("b")[i].innerHTML = "%user%";
vars[1] = content;
}
}
}
return vars;
};
// onlineLoaded - prüft, ob die Onlineliste geladen wurde
Global.onlineLoaded = function ()
{
return !!(parent.rightFrame.document && parent.rightFrame.document.getElementById("bd:"));
};
// inputLoaded - prüft, ob das Eingabeframe korrekt geladen wurde
Global.inputLoaded = function ()
{
return !!(parent.info.document && parent.info.document.eingabe);
};
// channelLoaded - prüft, ob das Raumauswahlframe korrekt geladen wurde
Global.channelLoaded = function ()
{
return !!(parent.ChannelFrame.document && parent.ChannelFrame.document.getElementsByTagName("select")[0]);
};
// sendText - sendet einen Text in den Chat
// text: zu sendender Text; user: Absender des Texts
Global.sendText = function (text, user)
{
// Soll der User den Text absenden?
if (!user || Global.chat.nick.toLowerCase() == Global.stripTags(user).toLowerCase())
{
var path = (Global.chat.rank) ? "chat" : "guest_ct";
path = "/cgi-bin/"+path+".cgi";
Global.xmlRequest({
path: path,
method: "POST",
str: "user="+Global.chat.nick+"&pass="+parent.info.pass+"&cid="+Global.chat.name+"&message="+escape(text).replace(/\+/g, "%2B").replace(/%u/g, "%26#x")
});
}
};
// xmlRequest - lädt Daten von einer Datei auf dem WK-Chatserver
// Erwartet ein Object (data) mit folgenden Angaben:
// path: Pfad auf dem WK-Server, ohne zusätzlichen Slash am Anfang - MUSS immer angegeben werden!
// method: Request-Methode (POST, GET, ...) - MUSS immer angegeben werden!
// str: String mit Daten für den Request
// func: Funktion, die bei onreadystatechange ausgeführt wird
Global.xmlRequest = function (data)
{
var xml = new XMLHttpRequest();
xml.open(data.method, "http://server"+Global.chat.server+".webkicks.de/"+data.path, true );
// Funktion reinpacken oder klar als undefined definieren
xml.onreadystatechange = (data.func) ? function (e) { data.func(xml) } : undefined;
xml.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8');
// Daten absenden
if (data.str)
{
xml.send(data.str);
}
else
{
xml.send(null);
}
};
// getCookie - lädt Inhalt eines Cookie aus.
// id: ID des Cookies
Global.getCookie = function (id)
{
id += "=";
var cookies = parent.document.cookie;
for (var i = 0; i < cookies.length; i++)
{
// Cookie gefunden?
if (cookies.substring(i, i + id.length) == id)
{
// Rausfinden wie lang der Cookie ist und den Wert zurückgeben
var position = cookies.indexOf(";", i + id.length);
position = (position > -1) ? position : cookies.length;
return cookies.substring(i + id.length, position);
}
}
return false;
};
// setCookie - speichert einen Cookie
// id: ID des Cookies; content: Inhalt des Cookies; exp: Ablaufdatum des Cookies
Global.setCookie = function (id, content, exp)
{
var cookie = id + "=" + content;
// Hat der Cookie ein Ablaufdatum?
cookie += (exp) ? ";expires=" + exp.toGMTString() : '';
parent.document.cookie = cookie;
};
// startStreamer - diese Funktion startet den Streamer sobald der Chat fertig geladen wurde.
Global.startStreamer = function ()
{
// Alles fertig geladen?
if (Global.inputLoaded() && Global.onlineLoaded() && (!Global.chat.settings[0] || Global.choiceLoaded()) && Global.chat.team)
{
Global.streamer();
}
else
{
setTimeout(function () { GSS.startStreamer(); }, 1000);
}
};
// streamer - die allgemeine Script-Intervallfunktion, über die alle intervallabhängige Scripts ausgeführt werden.
Global.streamer = function ()
{
// Durchlauf staten, solange nicht alle Chatzeilen überprüft sind
Streamer: while (Global.chat.streamCount < Global.chat.streamContent.length)
{
// try
// {
// getLineData auf die Zeile anwenden, Daten speichern
Global.chat.currentLine = Global.getLineData(Global.chat.streamContent[Global.chat.streamCount]);
// Zeile unkommentieren, um Ergebnisse im Stream zu sehen :)
// document.write([Global.chat.currentLine.type,Global.chat.currentLine.text,Global.chat.currentLine.user,Global.chat.currentLine.time,Global.chat.currentLine.guest,Global.chat.currentLine.vars]);
// for (var i = 0; i < Global.scripts.functions.length; i++)
// {
// Global.scripts.functions[i]();
// }
Global.chat.streamCount++;
// }
// catch (error)
// {
// document.write(error);
// setTimeout(function () { GSS.streamer(); }, 10000);
// break Streamer;
// }
}
// Ist nichts schiefgelaufen? Dann den nächsten Durchlauf vorbereiten.
if (Global.chat.streamCount == Global.chat.streamContent.length)
{
setTimeout(function () { GSS.streamer(); }, GSS.chat.streamInterval);
}
}
// getLineData - klassifiziert und "ordnet" eine Chatzeile
// line: HTML-Objekt, das an die Funktion weitergegeben wird
// 0: normal
// 1: /link - 0: URL, die gepostet wurde
// 2: /me und SE
// 3: /away
// 4: /away back
// 5: andere kursive Befehle, einschließlich /hp, /mail und /icq
// 6: flüster an jmd. (user[1] = Empfänger)
// 7: flüster von jmd. (user[1] = Empfänger)
// 8: /team
// 9: /comment und /commentall
// 10: Login
// 11: Login aus Raum - 0: Raum
// 12: Logout
// 13: Logout aus Raum - 0: Raum; 1: User wurde gemoved
// 14: /mecol und /col - type: definiert, ob es sich um /mecol (0) oder /col (1) handelt
// 15: Flooding - 0: Verwarnungs-Anzahl (falls nicht gegeben: Flooding-Kick)
// 16: Kicks, Banns, Deletes, Restores, Knebel - 0: Typ der Aktion (0: Knebel, 1: Restore, 2: Kick, 3: Bann, 4: /makemod, 5: /makeadmin, 6: /modkick, 7: /adminkick, 8: IP-Bann; 9: Delete; 1: Knebelzeit bei Knebel oder IP bei IP-Bann
// 17: Chatbot Allg. - 0; PM (1 = ja, 0 = nein)
// 18: /w - 0: Alle Räume samt Usern
// 19: /iplist - 0: Array aller IPs mit zugehörigen Usern
// 20: /rmip - 0: ausgelesene IP
// 21: Timeout-Warnung
// 22: Sonstiges
//
// type: Zeilentyp; text: Zeilentext; user: Liste der involvierten User; vars: zusätzliche Variablen; time: Array mit Timestamp; guest: 1 wenn die Zeile von einem Gast ist
Global.getLineData = function (line)
{
// Zeilenumbrüche vorsichtshalber entfernen
line.innerHTML = line.innerHTML.replace(/\n/g, "");
// Alle wichtigen Daten vordefinieren damit wir am Ende keine unnötigen Fehler bekommen.
var data = {type:22,text:"",user:[],vars:[],time:"",guest:0};
// Hat die Zeile Inhalt?
if (line.firstChild)
{
// Hat die Zeile einen Timestamp?
if (RegExp(/^\s*\(\d+:\d+\)\s+.*/).test(Global.stripTags(line.innerHTML)))
{
// Timestamp speichern
data.time = line.getElementsByTagName("font")[0].innerHTML.replace("(", "").replace(")", "").split(":");
if (line.childNodes[2] && line.childNodes[2].nodeName == "IMG" && line.childNodes[2].src.indexOf("/pfeilg.gif") > -1 && RegExp(/^\s*\(\d+:\d+\)\s+.*/).test(Global.stripTags(line.innerHTML)))
{
// Typ 9 - /comment und /commentall
data.type = 9;
data.user[0] = line.getElementsByTagName("font")[1].title;
data.text = line.getElementsByTagName("span")[0].innerHTML;
}
else
{
// Basisdaten speichern
lineArray = RegExp(/^\s*\(\d+:\d+\)\s+(\w+)(\W)\s?(.*)/).exec(Global.stripTags(Global.stripScripts(line.innerHTML)));
// Standard-Chatzeile?
if (lineArray)
{
lineArray = lineArray.slice(1);
// Zeilentrennungszeichen als Indikator für den Zeilentyp benutzen
switch (lineArray[1])
{
case ":":
data.user[0] = lineArray[0];
if (line.getElementsByTagName("a")[0] && line.getElementsByTagName("a")[0].innerHTML == lineArray[2])
{
// Typ 1 - /link
data.type = 1;
data.text = line.getElementsByTagName("a")[0].innerHTML;
data.vars.push(RegExp(/dref\.cgi\?url\=(.*)/).exec(line.getElementsByTagName("a")[0].href)[1]);
}
else
{
// Typ 0 - Normale Chatzeile
data.type = 0;
data.text = RegExp("title\\=\\\""+data.user[0]+"(?: \\(Gast\\))?\\\">: (.*)$", "i").exec(line.innerHTML)[1].replace(/<\/font>$/, "");
data.guest = (line.getElementsByTagName("span")[0].innerHTML == data.user[0]) ? 1 : 0;
}
break;
case " ":
data.user[0] = lineArray[0];
if (line.firstChild.nodeName == "SPAN")
{
// Typ 12 - Logout
data.type = 12;
data.text = RegExp(/<span class=\"commandcolor\">(.*)<\/span>(?:\s)?<\/i>/).exec(line.innerHTML)[1];
data.guest = (line.getElementsByTagName("i")[0].firstChild.nodeValue == data.user[0]) ? 1 : 0;
}
else if (line.childNodes[2])
{
var child = line.childNodes[2];
switch(child.nodeName)
{
case "IMG":
if (child.src.indexOf("/pfeil.gif") > -1 && lineArray[2].indexOf("i"))
{
// Typ 3 - /away
data.type = 3;
data.text = (lineArray[2].indexOf("(") > -1) ? RegExp(/meldet sich kurz ab \((.*)\)(?:[^)]*)$/).exec(Global.stripScripts(line.innerHTML))[1] : "";
}
else
{
// Typ 5 - andere /me-gestylten Zeilen
data.type = 5;
data.text = lineArray[2];
}
break;
case "FONT":
if (child.firstChild && child.firstChild.nodeName == "IMG")
{
if (child.firstChild.src.indexOf("/gruen.gif") > -1)
{
data.text = RegExp(/<span class=\"commandcolor\">(.*)<\/span>(?:\s)?<\/i>/).exec(line.innerHTML)[1];
if (line.getElementsByTagName("span")[line.getElementsByTagName("span").length-1].firstChild.nodeName == "I")
{
// Typ 11 - Login aus einem anderen Raum
data.type = 11;
data.vars[0] = line.getElementsByTagName("b")[line.getElementsByTagName("b").length-1].innerHTML;
data.guest = (line.getElementsByTagName("span")[0].innerHTML == data.user[0]) ? 1 : 0;
}
else
{
// Typ 10 - normaler Login
data.type = 10;
data.guest = (line.getElementsByTagName("span")[0].innerHTML == data.user[0]) ? 1 : 0;
}
}
else if (line.getElementsByTagName("small")[0])
{
data.text = RegExp(/<span class=\"commandcolor\">(.*)<\/span>(?:\s)?<\/i>/).exec(line.innerHTML)[1];
if (line.getElementsByTagName("small")[0].getElementsByTagName("i")[0])
{
// Typ 13 - Logout in anderen Raum
data.type = 13;
data.vars[1] = 1;
data.vars[0] = line.getElementsByTagName("b")[line.getElementsByTagName("b").length-1].innerHTML;
data.guest = (line.getElementsByTagName("span")[0].innerHTML == data.user[0]) ? 1 : 0;
}
else
{
// Typ 12 - Logout
data.type = 12;
if (RegExp(/\((.+)\)/).exec(line.getElementsByTagName("small")[0].innerHTML)[1] == "Browser geschlossen")
{
data.guest = (line.getElementsByTagName("i")[0].firstChild.nodeValue == data.user[0]) ? 1 : 0;
}
}
}
else if (line.getElementsByTagName("span")[line.getElementsByTagName("span").length-1].firstChild.nodeName == "I")
{
// Typ 13 - Logout in anderen Raum
data.type = 13;
data.text = RegExp(/<span class=\"commandcolor\">(.*)<\/span>(?:\s)?<\/i>/).exec(line.innerHTML)[1];
data.vars[0] = line.getElementsByTagName("b")[line.getElementsByTagName("b").length-1].innerHTML;
data.guest = (line.getElementsByTagName("span")[0].innerHTML == data.user[0]) ? 1 : 0;
}
else
{
// Typ 12 - normales Ausloggen
data.type = 12;
data.text = RegExp(/<span class=\"commandcolor\">(.*)<\/span>(?:\s)?<\/i>/).exec(line.innerHTML)[1];
data.guest = (line.getElementsByTagName("span")[0].innerHTML == data.user[0]) ? 1 : 0;
}
}
else
{
// Typ 2 - /me und Scripting-Engine
data.text = RegExp(/i> (.*)$/i).exec(line.innerHTML)[1].replace(/<\/i><\/font>$/, "");
data.type = 2;
data.guest = (line.getElementsByTagName("span")[0].innerHTML == data.user[0]) ? 1 : 0;
}
break;
case "B":
if (child.getElementsByTagName("span")[0].firstChild.nodeName == "#text")
{
if (lineArray[2].indexOf("flüsterst"))
{
// Typ 7 - Flüstern (von jmd.)
data.type = 7;
data.user[1] = Global.chat.nick;
}
else
{
// Typ 6 - Flüstern (an jmd.)
data.type = 6;
data.user = [Global.chat.nick, RegExp(/an (\w+)/).exec(lineArray[2])[1]];
}
data.text = RegExp(/<font color=\"red\">(.*)$/).exec(line.innerHTML)[1].replace(/<\/font><\/b>$/, "");
}
else if (!lineArray[2].indexOf("meldet sich wieder zurück"))
{
// Typ 4 - Away-Rückmeldung
data.type = 4;
}
else
{
// Typ 14 - /mecol und /col
data.type = 14;
data.vars.type = (line.getElementsByTagName("b")[line.getElementsByTagName("b").length-1].getElementsByTagName("font")[0].innerHTML == lineArray[0]) ? 0 : 1;
}
break;
}
}
break;
case "-":
switch (lineArray[0])
{
case "Chat":
if (lineArray[2].indexOf("Bot-PM"))
{
lineArray[2] = lineArray[2].replace("Bot: ", "");
if (line.getElementsByTagName("small")[0])
{
// Typ 16: moderative Aktion
data.type = 16;
data.user[0] = RegExp(/by (\w+)/).exec(line.getElementsByTagName("small")[0].innerHTML)[1];
if (RegExp(/- .+/).exec(line.innerHTML))
{
data.text = RegExp(/- (.*)\)/).exec(line.innerHTML)[1];
}
if (RegExp(/Neuer (?:Mod|Ad)/).exec(lineArray[2]))
{
data.vars[0] = (lineArray[2].indexOf("Neuer A")) ? 4 : 5;
data.user[1] = RegExp(/: (\w+)/).exec(lineArray[2])[1];
}
else
{
if (RegExp(/^(\w+) /).exec(lineArray[2]))
{
data.user[1] = RegExp(/^(\w+)/).exec(lineArray[2])[1];
switch (RegExp(/^[\w\.]+ (\w+)/).exec(lineArray[2])[1])
{
case "wird":
data.vars[0] = 0;
data.vars[1] = RegExp(/für (\d+)/).exec(lineArray[2])[1];
if (RegExp(/für \d+ .+ Minute\(n\) geknebelt/).exec(lineArray[2]))
{
data.text = RegExp(/für \d+ (.+) Minute\(n\) geknebelt/).exec(line.innerHTML)[1];
}
break;
case "kicked":
data.vars[0] = 2;
break;
case "banned":
data.vars[0] = 3;
break;
case "restored":
data.vars[0] = 1;
break;
case "deleted":
data.vars[0] = 9;
break;
case "bekommt":
data.vars[0] = (lineArray[2].indexOf("Administrator-") > -1) ? 6 : 7;
break;
}
}
else
{
data.vars[0] = 8;
data.vars[1] = RegExp(/^([\d\.]+)/).exec(lineArray[2])[1];
}
}
}
else if (lineArray[2].indexOf("Flooding-Verwarnung") > -1 || lineArray[2].indexOf("Flooding gekickt!") > -1)
{
// Typ 15 - Flooding
data.user[0] = line.getElementsByTagName("font")[1].title;
data.guest = (line.getElementsByTagName("b")[1]) ? 0 : 1;
data.type = 15;
if (lineArray[2].indexOf("Flooding-Verwarnung") > -1)
{
data.vars[0] = (lineArray[2].slice(0,1) == "1") ? 1 : 2;
}
}
else if (!lineArray[2].indexOf("Alarm-Ruf!"))
{
// Typ 17 - Chatbot Allgemein
data.type = 17;
data.text = lineArray[2];
}
}
else
{
lineArray[2] = lineArray[2].replace("Bot-PM: ", "");
if (!lineArray[2].indexOf("IP von "))
{
// Typ 20 - /rmip
data.type = 20;
data.user[0] = RegExp(/IP von (\w+)/).exec(lineArray[2])[1];
data.vars[0] = RegExp(/: (.+)/).exec(lineArray[2])[1];
}
else
{
// Typ 17 - Chatbot Allgemein
data.type = 17;
data.text = lineArray[2];
data.vars[0] = 1;
}
}
break;
case "Team":
if (line.getElementsByTagName("font")[1].title == "Team-Nachricht")
{
// Typ 8 - /team
data.type = 8;
data.text = RegExp(/<span class=\"not_reg\"><b> (.*)<\/span>/i).exec(line.innerHTML)[1].replace(/<\/b>$/,"");;
data.user[0] = RegExp(/von (\w+)/).exec(line.getElementsByTagName("font")[3].innerHTML)[1];
}
else
{
// Typ 22 - sonstiges
data.text = lineArray[2].replace("Nachricht: ", "");
}
break;
default:
break;
}
break;
case "´":
// Typ 5 - sonstige kursive Befehle
data.user[0] = lineArray[0];
data.type = 5;
data.text = lineArray[2];
break;
default:
break;
}
}
else
{
// Typ 15 - Flooding
data.type = 15;
data.vars[0] = (line.getElementsByTagName("span")[0].innerHTML.slice(1,2) == "1") ? 1 : 2;
data.user[0] = line.getElementsByTagName("font")[1].title;
data.guest = (line.getElementsByTagName("b")[1]) ? 0 : 1;
}
}
}
else
{
if (line.firstChild && line.firstChild.firstChild.nodeName == "FONT")
{
if (line.firstChild.firstChild.innerHTML == "IP-Liste")
{
// Typ 19 - /iplist
data.type = 19;
if (line.getElementsByTagName("span")[0])
{
data.vars[0] = [];
for (var i = 0; i < line.getElementsByTagName("span").length; i++)
{
data.vars[0][i] = [line.getElementsByTagName("span")[i].getElementsByTagName("b")[0].innerHTML];
if (line.getElementsByTagName("span")[i].getElementsByTagName("font")[0])
{
data.vars[0][i][1] = line.getElementsByTagName("span")[i].getElementsByTagName("font")[0].innerHTML.replace(/ /g, "").split(",");
}
else
{
data.vars[0][i][1] = [line.getElementsByTagName("span")[i].childNodes[1].nodeValue.replace(": ", "")];
}
}
}
}
else
{
// Typ 21 - Timeout-Warnung
data.type = 21;
}
}
else if (line.lastChild.nodeName == "FONT" && !line.lastChild.innerHTML.indexOf("Info:"))
{
// Typ 18 - /w
data.type = 18;
var child = line.childNodes;
data.vars[0] = [];
for (var i = 0; i < child.length; i++)
{
if (child[i].nodeName == "SPAN")
{
var index = data.vars[0].push([child[i].getElementsByTagName("u")[0].innerHTML])-1;
data.vars[0][index][1] = {};
for (var j = 0; j < child[i].getElementsByTagName("span").length; j++)
{
var user = child[i].getElementsByTagName("span")[j];
var nick = Global.stripTags(user.innerHTML).replace("(G)", "");
if (nick.indexOf("*") > -1)
{
nick = data.vars[0][index][2] = nick.replace("(*)", "");
}
else
{
data.vars[0][index][2] = 0;
}
data.vars[0][index][1][nick] = 1;
}
}
}
}
}
/*
// Ist der User ein Gast?
if (guest)
{
Cache.user[self.user[0]].rank = 0;
}
// Sind in der Zeile Daten für die Nickfarbe?
else if (self.type < 24 || self.type > 27 && self.type < 33)
{
// Loggt der User sich gerade ein?
if (self.type == 9 || self.type == 10)
{
Cache.user[self.user[0]].status = 1;
}
// Hat der User den Raum verlassen?
else if (self.type > 10 && self.type < 20 || self.type == 30)
{
Cache.user[self.user[0]].status = 0;
}
// Benutzt der User /away?
else if (self.type == 20)
{
updateUser(self.user[0],
{
status: 2,
away: self.text
});
}
// Meldet der User sich aus /away zurück?
else if (self.type == 21)
{
updateUser(self.user[0],
{
status: 1,
away: ""
});
}
// Farbobjekt suchen und prüfen
for (var i = 0; i < dom.getElementsByTagName("b").length; i++)
{
var nickDom = dom.getElementsByTagName("b")[i];
if (stripTags(nickDom.innerHTML) == self.user[0] && !nickDom.getElementsByTagName("b")[0] && nickDom.firstChild.nodeName == "FONT" && (!nickDom.childNodes[1] && (!nickDom.firstChild.childNodes[1] && nickDom.firstChild.firstChild.nodeName == "#text" || nickDom.firstChild.childNodes[1] && nickDom.firstChild.firstChild.nodeName == "FONT" && nickDom.firstChild.lastChild.nodeName == "FONT") || nickDom.childNodes[1] && nickDom.firstChild.nodeName == "FONT" && nickDom.lastChild.nodeName == "FONT"))
{
// Farbe parsen
if (!Cache.user[self.user[0]].color || Cache.user[self.user[0]].color[1] != nickDom.innerHTML)
{
Cache.user[self.user[0]].parseColor(nickDom);
}
break;
}
}
// Spezialfall Scripting-Engine: Replacer %me% und %user% wieder einsetzen
if (self.type == 1)
{
dom = document.createElement("div");
dom.innerHTML = self.text;
for (var i = 0; i < dom.getElementsByTagName("b").length; i++)
{
var nickDom = dom.getElementsByTagName("b")[i];
var content = stripTags(nickDom.innerHTML);
if (!nickDom.getElementsByTagName("b")[0] && !content.match(/\W/) && content.length < 21 && content.length > 1 && nickDom.firstChild.nodeName == "FONT" && (!nickDom.childNodes[1] && (!nickDom.firstChild.childNodes[1] && nickDom.firstChild.firstChild.nodeName == "#text" || nickDom.firstChild.childNodes[1] && nickDom.firstChild.firstChild.nodeName == "FONT" && nickDom.firstChild.lastChild.nodeName == "FONT") || nickDom.childNodes[1] && nickDom.firstChild.nodeName == "FONT" && nickDom.lastChild.nodeName == "FONT"))
{
self.vars[0] = 1;
// %me%
if (dom.getElementsByTagName("b")[i].innerHTML == Cache.user[self.user[0]].color[1])
{
dom.getElementsByTagName("b")[i].innerHTML = "%me%";
}
// %user%
else
{
if (!self.user[1])
{
self.user[1] = content;
updateUser(self.user[1],
{
color: dom.getElementsByTagName("b")[i]
});
}
dom.getElementsByTagName("b")[i].innerHTML = "%user%";
}
}
}
self.text = dom.innerHTML.replace(/<b><b>%me%<\/b><\/b>/ig, "%me%").replace(/<b>%user%<\/b>/ig, "%user%");
}
// Spezialfälle /col und /mecol: alten Farbstring speichern, neue Farbe generieren
else if (self.type == 22 || self.type == 23)
{
self.vars[0] = Cache.user[self.user[0]].color[0];
Cache.user[self.user[0]].parseColor(dom.getElementsByTagName("b")[dom.getElementsByTagName("b").length-1]);
}
}
*/
}
return data;
};
// updateUser - erstellt oder erneuert ein User-Element für den entsprechenden User
// nick: Nick des Users; data: Objekt mit allen Daten, die geupdatet werden sollen
Global.updateUser = function (nick, data)
{
// Gibt es den User bereits?
if (!Global.userList[nick])
{
Global.userList[nick] = new Global.User(nick, data);
}
else
{
Global.userList[nick].update(data);
}
};
// expandUser - fügt zusätzliche Standard-Einstellungen zur User-Klasse hinzu
Global.expandUser = function ()
{
};
// extractColors - liest Farben und Schriftart aus einem Usernick aus. Gibt ein Array mit bis zu drei Werten zurück (Farbe1, Farbe2, Schriftart).
// dom: HTML-Element mit Nick als Inhalt (ohne B-Tags)
Global.extractColors = function (dom)
{
var col = [];
// Ist der Nick überhaupt gefärbt?
if (dom.getElementsByTagName("font")[0])
{
// Mecol oder Col?
if (dom.getElementsByTagName("font").length > 1)
{
// Schriftart angegeben?
if (!dom.childNodes[1])
{
dom = dom.firstChild;
col[2] = dom.face;
}
col[1] = dom.lastChild.color;
}
col[0] = dom.firstChild.color;
}
return col;
};
/*
Klasse User
Klasse zum Speichern von Usern und entsprechenden Einstellungen.
Erwartet: nick: Nick des Users
Methoden:
update: setzt weitere Daten in das Element ein.
Erwartet: data: Objekt mit den neuen Daten
Variablen:
nick: Nick des Users
status: Online-Status des Users (Standard: 0)
0: nicht im Raum
1: im Raum
rank: Systeminterner Rang des Users (Standard: 0)
0: Gast
1: User
2: Mod
3: Admin
color: Farbdaten des Users (Standard: User hat Gastfarben)
0: Farbe 1
1: Farbe 2
2: Schriftart
*/
Global.User = function (nick, data)
{
var self = this;
self.nick = nick;
self.status = 0;
self.rank = 0;
self.color = [];
self.update = function (data)
{
for (var i in data)
{
self[i] = data[i];
}
}
self.update(data);
};
// In diesem Objekt werden alle User gespeichert
Global.userList = {};
/* Variablen */
// server: Server-ID
// name: Chatname
// nick: Nick
// currentRoom: derzeitiger Raum (interner Raumname, Userliste)
// rooms: alle betretbaren Räume des Chats (interner Raumname)
// rank: chatinterner eigener Status (0 = Gast, 1 = User, 2 = Mod, 3 = Admin, 4 = Hauptadmin)
// *color: Farbschema (Farbe 1, Farbe 2, Schriftart)
// team: Liste aller Teammitglieder (Mods, Admins, Hauptadmin)
// links: alle selbsteingetragenen Links im Eingabeframe
// settings: Raumsystem aktiviert, Smileys aktiviert, Topliste aktiviert, Profile aktiviert
// streamContent: alle td-Elemente des Chatstreams
// streamCount: bisher verarbeitete td-Elemente
// streamInterval: Aufruf-Intervall der Streamer-Scripts
// streaming: definiert, ob die Streamer-Funktion momentan ausgeführt wird oder nicht
// currentLine: letzte bearbeitete Chatzeile
Global.chat = {
streamContent: document.getElementsByTagName("td"),
streamer: 0,
settings: [0,0,0,0]
};
Global.chat.streamCount = Global.chat.streamContent.length,
// scripts: speichert alle relevanten Scriptdaten (Scriptliste, Streamer-Unterfunktionen, ...)
// functions: alle Funktionen, die über streamer aufgerufen werden sollen
// list: Script-Liste
Global.scripts = {
functions: [],
list: {}
};
});
GSS.getChatData(500, 1);
- alle Funktionen sind nun unter dem globalen Objekt "GSS" gespeichert. Das heißt, dass ihr z.B. für strip_tags nun GSS.stripTags aufrufen müsst.
- ebenso sind globale Variablen nun unter GSS.chats zu finden (myStatus ist nun z.B. GSS.chat.rank).
- es gibt eine globale Intervallfunktion, die alle Scripts verwalten kann, die einen Intervall benötigen.
- ein allgemeines User-Element, auf welches alle Scripts zugreifen können und das auch erweitert werden kann.
- eine ganze Menge neuer Funktionen, die mehr oder weniger nützlich für den Scripteralltag sein sollten!
Insbesondere GSS.getTeamData und GSS.chat.team wird sicher für viele ziemlich interessant sein.
- Erweiterungsfunktion für die Userklasse
- System zum Abfangen von Fehlern im globalen Intervall
- Script-Supportsystem. Jedes Script kann dort eine ID eintragen und so kann man sich z.B. mit nur einem Befehl alle im Chat eingebauten Scripts ausgeben lassen.
- Optimierungen, Optimierungen, Optimierungen...
- Rückwärtskompatibilität zu alten Scripts
- Testen in anderen Browsern, außer Firefox (WebKit-Browser sollten keine Probleme machen, Opera an sich auch nicht, der IE wird aber wohl in älteren Versionen bei xmlRequest rummucken)
