-------------------------------------index.php (client)-----------------------------------
[code]<?php
if(!file_exists("config.php")){
	header("Location: installer.php");
	exit();
}
session_start(); ?>
<html>
<head>
<style>
body{
	padding: 0;
	margin: 0;
	font-family: Arial, Helvetica, sans-serif;
	font-size: 12px;
}
fieldset.message, fieldset.warning, fieldset.notice, fieldset.error, fieldset.personal{
	display: block;
	margin: 3px;
	padding: 5px;
	-moz-border-radius: 10px;
}
fieldset.warning{
	border: 1px solid #800000;
	background: #CC0000;
	color: #ffffff;
}
fieldset.notice{
	border: 1px solid #c8c8c8;
	background: #e6e6e6;
}
fieldset.personal{
	border: 1px solid #bfc790;
	background: #eff3d4;
}
fieldset.error{
	border: 1px solid #c8c8c8;
	background: #e6e6e6;
}
legend.messageheading{
	color:#999999;
	display: block;
}
div.messagebody{
	color: #000000;
	display: block;
}
span.name{
	color:#CC0000;
}
#chatwindow{
	height: 80%;
	width:100%;
	overflow: scroll;
}
form{
	margin: 0; padding: 0;
}
tt{
	color: #990000;
}
tt .optional{
	color: #009900;
}
table{
	width: 100%;
}
table, tr, td, th{
	font-size: 12px;
}
tr{
	border-bottom: 1px solid grey;
}
</style>
<script type="text/javascript">
var timeout = 5;//hoeveel seconden tussen de updates

//einde intellingen.
var xmlhttp=false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
// JScript gives us Conditional compilation, we can cope with old IE versions.
// and security blocked creation of the objects.
try {
  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (E) {
   xmlhttp = false;
  }
}
@end @*/
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
  xmlhttp = new XMLHttpRequest();
}
var dead = false;
<?php
	if(isset($_SESSION['name'])){ 
		echo "var nickname = \"".$_SESSION['name']."\";\n";
	}
	else{
		echo "var nickname = \"annoniem\";\n";
	}
	echo "var basepath = \"http://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF'])."/\";\n";
?>
var timer = 0;
var busy = false;
function setname()
{
	busy = true;
	document.getElementById("submitbutton").disabled = true;
	var d = new Date();
	var newname = prompt("Wat wordt je nickname", nickname);
	if(newname != null){
		xmlhttp.open("GET",basepath+"server.php?message=/NAME "+newname+"&random="+d.getFullYear()+(d.getMonth()+1)+d.getDate()+d.getHours()+d.getMinutes()+d.getSeconds(),true);
		xmlhttp.onreadystatechange=function() {
			if (xmlhttp.readyState==4) {
				if(xmlhttp.responseText.indexOf("OK") != -1){
					document.getElementById('chatwindow').innerHTML += "<fieldset class=\"notice\">"+nickname+" has changed his name to "+newname+"</fieldset>\n";
					document.getElementById('chatwindow').scrollTop = 10000000;
					nickname = newname;
					update("undefined");
				}
				//else{
				//	alert("Failed to set nickname:\n"+xmlhttp.responseText);
				//	dead = true;
				//}
			}
		}
		busy = false;
		xmlhttp.send(null);
	}
	else
	{
		document.getElementById("submitbutton").disabled = false;
		busy = false;
		return true;
	}
	document.getElementById("submitbutton").disabled = false;
	busy = false;
}

function setaway()
{
	document.getElementById("submitbutton").disabled = true;
	var d = new Date();
	xmlhttp.open("GET",basepath+"server.php?message=/AWAY&random="+d.getFullYear()+(d.getMonth()+1)+d.getDate()+d.getHours()+d.getMinutes()+d.getSeconds(),true);
	xmlhttp.onreadystatechange=function() {
		if (xmlhttp.readyState==4) {	
			if(xmlhttp.responseText.indexOf("OK") != -1){
				document.getElementById('chatwindow').innerHTML += "<fieldset class=\"notice\">Lastid is has successfully been reset to zero.</fieldset>\n";
				document.getElementById('chatwindow').scrollTop = 10000000;
				dead = true;
			}
			else{
				alert("Failed to reset your id:\n"+xmlhttp.responseText);
				dead = true;
			}
		}
	}
	xmlhttp.send(null);
	document.getElementById("submitbutton").disabled = false;
}


function update(bericht)
{
	if(bericht.toUpperCase() == "/DISCONNECT"){
		setaway;
		dead = true;
	}
	if(bericht != "" && busy != true && dead != true){
		busy = true;
		document.getElementById("submitbutton").disabled = true;
		timer = timeout;
		var d = new Date()
		if(bericht == "undefined"){
			var url = "server.php?random="+d.getFullYear()+(d.getMonth()+1)+d.getDate()+d.getHours()+d.getMinutes()+d.getSeconds();
		}
		else{
			var url = "server.php?message="+bericht+"&random="+d.getFullYear()+(d.getMonth()+1)+d.getDate()+d.getHours()+d.getMinutes()+d.getSeconds();
		}
		xmlhttp.open("GET",basepath+url,true);//method, target, async (set always true!)
	    xmlhttp.onreadystatechange=function() {
			if (xmlhttp.readyState==4) {
				if(xmlhttp.responseText != "" && xmlhttp.responseText != " "){
					if(xmlhttp.responseText.indexOf("SETNAME") != -1)
					{
						setname();
					}
					else{
						var rows = xmlhttp.responseText.split("\n");
						for(i = 0; i <= rows.length-1; i++)
						{
							var data = rows[i].split("||");
							if(data[0] == "OK"){	var type = data[1];}
							else{					var type = data[0];}
							switch(type.toUpperCase()){
							case "DIE":
								if(data[0] == "OK"){data[0]=data[1];data[1]=data[2];}
								document.getElementById('chatwindow').innerHTML += "<fieldset class=\"error\"><div class=\"messagebody\">"+data[1]+"</div></fieldset>\n";
								dead=true;
								break;
							case "MESSAGE":
								if(data[0] == "OK"){data[0]=data[1];data[1]=data[2];data[2]=data[3],data[3]=data[4],data[4]=data[5];}
					           	document.getElementById('chatwindow').innerHTML += "<fieldset class=\"message\"><legend class=\"messageheading\"><span class=\"id\">"+data[1]+"</span><span class=\"name\">"+data[2]+"</span> said on "+data[3]+":</legend><div class=\"messagebody\">"+data[4]+"</div></fieldset>\n";
								break;
							case "NOTICE":
								if(data[0] == "OK"){data[0]=data[1];data[1]=data[2];data[2]=data[3],data[3]=data[4],data[4]=data[5];}
								document.getElementById('chatwindow').innerHTML += "<fieldset class=\"notice\"><div class=\"messagebody\">"+data[4]+"</div></fieldset>\n";
								break;
							case "PERSONAL":
								if(data[0] == "OK"){data[0]=data[1];data[1]=data[2];}
								document.getElementById('chatwindow').innerHTML += "<fieldset class=\"personal\"><div class=\"messagebody\">"+data[1]+"</div></fieldset>\n";
								break;
							case "WARNING":
								if(data[0] == "OK"){data[0]=data[1];data[1]=data[2];}
								document.getElementById('chatwindow').innerHTML += "<fieldset class=\"warning\"><div class=\"messagebody\">"+data[1]+"</div></fieldset>\n";
								break;
							default:
								document.getElementById('chatwindow').innerHTML += "<fieldset class=\"error\">"+xmlhttp.responseText+"</fieldset>\n";
								break;
							}
							document.getElementById('chatwindow').scrollTop = 10000000;
						}
					}
		        }
		    }
		}
	    xmlhttp.send(null);
		busy = false;
		document.getElementById("submitbutton").disabled = false;
	}
	else{ if(dead){
		if(bericht.toUpperCase() == "/CONNECT"){
			dead = false;
			counter();
			document.getElementById('chatwindow').innerHTML = "<fieldset class=\"Notice\">Client has been reset.</fieldset>\n";
		}
	}}
}

function counter()
{
	if(!dead){
		if(timer <= 0)
		{
			update("undefined");
			timing = setTimeout("counter()", 1000);
		}
		else{
			timer = timer-2;
			timing = setTimeout("counter()", 1000);
		}
	}
	else{
		clearTimeout(timing)
		document.getElementById('chatwindow').innerHTML += "<fieldset class=\"error\">Client terminated. Please reload this page to restart the chat.</fieldset>\n";
	}
}
</script>
</head>
<body onunload="setaway()">
<div id="chatwindow"></div>
<form name="formulier" onSubmit="javascript: update(document.getElementById('chattext').value);document.getElementById('chattext').value = '';return false;">
	<input type="text" id="chattext" name="chattext" maxlength="256" style="width: 450px; "/>
	<input type="submit" id="submitbutton" value="Say!" style="width:150px; "/>
	<input type="button" onClick="setname()" value="andere naam"/>
</form>
<script>
	counter();
</script>
<br/>
</body>
</html>
[/code]
-------------------------server.php (zoals de naam al zegt)----------------------------
[code]<?php
ob_start();
session_start();
error_reporting(E_ALL);
/*SQLtable
CREATE TABLE IF NOT EXISTS `PREFIXmessages` ( 
`id` int(8) NOT NULL auto_increment, 
`message` mediumtext NOT NULL, 
`author` text NOT NULL, 
`ip` varchar(15) NOT NULL default '', 
`timestamp` int(10) NOT NULL default '0', 
`type` enum('message','notice','warning','error') NOT NULL default 'message', 
UNIQUE KEY `id` (`id`) 
) TYPE=MyISAM AUTO_INCREMENT=42 ;
*/
//instellingen
require("config.php");
//optionele hooks
/*
function messagepreparser($message){
	//deze functie wordt uitgevoerd voordat het bericht in de database wordt geplaatst
}

function outputparser($input){
	//als je de gehele uitvoer nog eventjes wilt doorscannen op dingen die niet kunnen, 
	//zoals scheldwoorden. Deze functie heeft in tegenstelling tot de vorige 2 ook invloed 
	//op het naamveld het de timestamp
	$output = str_replace("fuck", "f*ck", $input);
	return $output;
}
*/

//belangrijke array defineren
$commands = array();

//even wat standaard commando's defineren
$commands['name'] = array();
$commands['name']['usage'] = '/name [nickname]';
$commands['name']['description'] = 'Change your nickname.';
$commands['name']['help'] = '<tt>/name</tt> changes your nickname and will inform others.<br/>Warning: You can not use spaces in your nickname.';
$commands['name']['function'] = '
	unset($parameters[0]);
	$newname = implode(" ", $parameters);
	if(!isset($_SESSION[\'name\'])){
		addmessage($newname." has joined the chat", "Server", "notice");
	}
	else{
		addmessage($_SESSION[\'name\']." has changed his name to ".$newname,"Server","notice");
	}
	$_SESSION[\'name\'] = $newname;
	print("OK||");
	return true;
';

$commands['away'] = array();
$commands['away']['usage'] = '/away';
$commands['away']['description'] = 'Disconnects you from the chat.';
$commands['away']['help'] = '<tt>/away</tt> will inform all users when you leave the chatroom. It will also reset all your personal variables and eventually your client will get the message to stop.<br/>This function is automaticly called when you leave the client.<br/>You can reconnect by reloading your browserwindow or sending the <tt>/connect</tt> command.';
$commands['away']['function'] = '
	unset($_SESSION[\'lastupdate\']);
	if(isset($_SESSION[\'isadmin\'])){unset($_SESSION[\'isadmin\']);}
	if(addmessage($_SESSION[\'name\']." has left the chat", "Server", "notice") && !isset($_SESSION[\'lastupdate\']) && define("STOP", true) && print("OK||DIE||You have logged out.")){
		return true;
	}
';

$commands['help'] = array();
$commands['help']['usage'] = '/help <span class="optional">[command]</span>';
$commands['help']['description'] = 'displays the message that you are reading.';
$commands['help']['help'] = '<tt>/help</tt> shows you a list of all available commands and by typing for example <tt>/help name</tt> you will see the detailed help for <tt>/name</tt> if available.';

//standaardfuncties
function connected(){
	global $dbverbinding;
	
	/********hook********/
	if(defined('ADD_connected')){
		eval(ADD_connected);
	}
	
	if(!defined("CONNECTED")){
		if($dbverbinding=mysql_connect(MYSQL_SERVER,MYSQL_USER,MYSQL_PASSWORD)){
			if(mysql_select_db(MYSQL_DATABASE,$dbverbinding)){
				if(define("CONNECTED", true)){return true;}
				else{
					print("DIE||Kon de constante <i>CONNEDTED</i> niet dsefineren\n");
					return false;
				}
			}
			else{
				print("DIE||Fout nr ".mysql_errno($dbverbinding)." bij het selecteren van de database: ".mysql_error($dbverbinding)."\n");
				return false;
			}
		}
		else{
			print("DIE||Fout bij het verinding maken met de database op ".MYSQL_SERVER." als ".MYSQL_USER."\n");
			return false;
		}
	}
	else{
		return true;
	}
}

function addmessage($message = "", $name = "Annoniem", $type="message"){
	global $dbverbinding;
	
	/********hook********/
	if(defined('ADD_addmessage')){
		eval(ADD_addmessage);
	}
	
	if($message{0} == "/"){
		if(command($message)){
			return true;
		}
	}
	else{
	if(trim($message) != ""){
		if(connected()){
			if($name == "Annoniem" && isset($_SESSION['name'])){
				$name = $_SESSION['name'];
			}
			if(function_exists("messagepreparser")){
				$message = messagepreparser($message);
			}
			else{
				$message = strip_tags($message,'<b> <u> <i>');
			}
			if(mysql_query("INSERT INTO ".MYSQL_PREFIX."messages (message,author,ip,timestamp,type) VALUES ('".addslashes($message)."','".addslashes(htmlentities($name))."','".$_SERVER['REMOTE_ADDR']."',".mktime().",'".$type."')")){
				return true;
			}
			else{
				print("DIE||Error nr ".mysql_errno($dbverbinding)." while executing SQLquery: ".mysql_error($dbverbinding)."\n");
				return false;
			}
		}
		else{
			print("DIE||Function addmessage() doesn't get a connection to the database");
			return false;
		}
	}
	else{
		return false;
	}
	}
}

function echomessages(){
	global $dbverbinding;
	$awnser = array();
		/********hook********/
	if(defined('ADD_echomessages')){
		eval(ADD_echomessages);
	}
		if(connected()){
		if(!isset($_SESSION['lastupdate'])){
			$query = "SELECT * FROM ".MYSQL_PREFIX."messages WHERE timestamp > ".(mktime()-60*60*24)." ORDER BY id DESC LIMIT ".FIRSTTIME_MAX_MESSAGES;
		}
		else{
			$query = "SELECT * FROM ".MYSQL_PREFIX."messages WHERE timestamp > ".$_SESSION['lastupdate']." ORDER BY id DESC LIMIT ".MAX_MESSAGES;
		}
		if($results = mysql_query($query)){
			while($row = mysql_fetch_array($results)){
				if(defined('ADD_echomessages_loop')){
					eval(ADD_echomessages_loop);
				}
				$message = nl2br($row['message']);
				$awnser[] = $row['type']."||".$row['id']."||".$row['author']."||".date(TIMESTAMP, $row['timestamp'])."||".$message;
				$_SESSION['lastupdate'] = mktime();
				if($row['id'] >= MAX_SIZE_DB){
					cleandb();
				}
			}
			if(function_exists("outputparser")){
				outputparser($awnser);
			}
			else{
				echo implode("\n", array_reverse($awnser));
			}
			return true;
		}
		else{
			print('DIE||Fout nr '.mysql_errno($dbverbinding).' bij het uitvoeren van de SQLquery: '.mysql_error($dbverbinding)."\n");
			return false;
		}
	}
	else{
		print('DIE||Functie addmessage() krijgt geen verbinding met database.\n');
		return false;
	}
}

function command($in){
	global $commands;
	$parameters = explode(" ", substr($in, 1));
	$parameters[0] = strtolower($parameters[0]);

	/********hook********/
	if(defined('ADD_command')){
		eval(ADD_command);
	}
	if($parameters[0] == "help"){//speciale functie
		if(isset($parameters[1])){//doelgerichte help
			if(!isset($commands[$parameters[1]])){
				if(print("PERSONAL||<tt>/".$parameters[1]."</tt> is not a function.<br/>Type <tt>/help</tt> for all available commands.")){
					return true;
				}
			}
			elseif(!isset($commands[$parameters[1]]['help'])){
				if(print("PERSONAL||<tt>/".$parameters[1]."</tt> does not has a help.")){
					return true;
				}
			}
			else{
				if((!isset($commands[$parameters[1]]['secure']) || (isset($commands[$parameters[1]]['secure']) && $commands[$parameters[1]]['secure'] == false) || (isset($commands[$parameters[1]]['secure']) && $commands[$parameters[1]]['secure'] == true && isset($_SESSION['isadmin']))) && print("PERSONAL||".$commands[$parameters[1]]['help'])){
					return true;
				}
				else{
					if(print("PERSONAL||<tt>/".$parameters[1]."</tt> is not a function.<br/>Type <tt>/help</tt> for all available commands.")){
						return true;
					}
				}
			}
		}
		else{//list alle functies
			$output = "";
			foreach($commands as $key => $value){
				if(isset($commands[$key]['usage']) && isset($commands[$key]['description']) && (!isset($commands[$key]['secure']) || (isset($commands[$key]['secure']) && (!$commands[$key]['secure'] || ($commands[$key]['secure'] && isset($_SESSION['isadmin'])))))){
					$output .= "<li><tt>".$commands[$key]['usage']."</tt><br/>".$commands[$key]['description']."</li>";
				}
			}
			if(!empty($output)){
				print("PERSONAL||".nl2br("<ul class=\"help\">".$output."</ul>"));
			}
			else{
				print("PERSONAL||No functions available.");
			}
			return true;
		}
	}
	
	elseif(isset($commands[$parameters[0]])){
		if(isset($commands[$parameters[0]]['function'])){
			if(isset($commands[$parameters[0]]['secure']) && $commands[$parameters[0]]['secure'] == true){
				if(!isset($_SESSION['isadmin'])){
					if(print("PERSONAL||<tt>/".$parameters[0]."</tt> is not a function.<br/>Type <tt>/help</tt> for all available commands.")){
						return true;
					}
					exit();
				}
			}
			$awnser = eval($commands[$parameters[0]]['function']);
			if($awnser != false){
				if(isset($echo)){
					print($echo);
				}
				return true;
			}
			else{
				return false;
			}
		}
		elseif(print("PERSONAL||<tt>/".$parameters[0]."</tt> does not has a function.<br/>Type <tt>/help ".$parameters[0]."</tt> for more details")){
			return true;
		}
	}
	elseif(print("PERSONAL||<tt>/".$parameters[0]."</tt> is not a function.<br/>Type <tt>/help</tt> for all available commands.")){
		return true;
	}
}

function cleandb(){
	global $dbverbinding;
	
	/********hook********/
	if(defined('ADD_cleandb')){
		eval(ADD_cleandb);
	}
	
	if(connected()){
		if($results = mysql_query("TRUNCATE ".MYSQL_PREFIX."messages")){
			addmessage("Database has been cleaned", "Server", "notice");
			return true;
		}
		else{return false;}
	}else{return false;}
}

//plugins inladen.
if(PLUGINS_ENABLED && is_dir(PLUGINS_DIR)){
	if ($handle = opendir(PLUGINS_DIR."/")){ 
    	while (false !== ($file = readdir($handle))) {  
			$bestand = PLUGINS_DIR."/".$file ; 
	        $ext = pathinfo($bestand);
			if($ext['extension'] == "php"){
				include(PLUGINS_DIR."/".$file);
			}
		} 
		closedir($handle);
	}
}
//aanvraagafhandeling
if(!isset($_SESSION['name']) && !isset($_GET['message'])){
	echo "SETNAME";
}
elseif(isset($_GET['message'])){
	if(!addmessage(str_replace("||", "|",$_GET['message']))){
		print("WARNING||Kon bericht niet toevoegen\n");
	}
	elseif(!defined("STOP")){
		if(!echomessages()){die("DIE||Kon berichten niet weergeven\n");}
	}
}
else{
	if(!echomessages()){
		die("DIE||Kon berichten niet weergeven\n");
	}
}
ob_end_flush();
?>[/code]]

-------------------------------------config.php (client)-----------------------------------
[code]<?php
//het is ook mogelijk de installer te gebruiken. SLa dan dit bestand over en download het volgende, en zet het in dezelfde directorie als server.php en index.php
//http://jellinde.jl.funpic.org/phpchat_v2/plugins/_download_installer.php
define("MAX_MESSAGES", 10);
define("FIRSTTIME_MAX_MESSAGES", 1);

define("MYSQL_SERVER", "localhost");
define("MYSQL_USER", "root");
define("MYSQL_PASSWORD", "");
define("MYSQL_DATABASE", "chat");
define("MYSQL_PREFIX", "chat_");

define("MAX_SIZE_DB", 500);
define("TIMESTAMP", "Y-m-d H:i:s");//formaat van timestamp. Zie http://nl3.php.net/manual/nl/function.date.php

define("MAX_WORD_LENGTH", 30);

define("PLUGINS_ENABLED", true);
define("PLUGINS_DIR", "./plugins");

define("PASSWORD", "wachtwoord");
?>[/code]