Scripts

PHPChat V2 (mysql)

Het vervolg op PHP Chatbox Een Chatbox die gebruikmaakt van XMLHttpRequest, wat er voor zorgt dat bij iedere request alleen de berichten die nog niet bij de gebruiker bekend zijn worden verzonden. Als het goed is zorgt dit voor minder verbruik in bandbreedte. Uiteraard wel meer serverload ^^, Waarom deze chatbox beter is dan ieder ander? -Hij is heel makkelijk uit te breiden, zonder de source aan te hoven passen, doordat hij alle bestanden die in de directorie /plugins automatisch inlaad, en de rest van het script zo is gemaakt dat deze vrij simpel kan worden uitgebreid. -Hij heeft ondersteuning voor commando's net zoals in IRC, welken ook weer gemakkelijk toe te voegen zijn via bestanden in de /plugins directorie. -Hij stuurt per aanvraag alleen de nieuwe berichten op. Dus geen overbodig bandbreedteverbruik meer, maar wel het idee dat je realtime chat, zodner vertragingen. (bij standaardinstellingen) -Voor de handigheid geleverd met installer. (niet hieronder in de source vermeld) Beschikbare plugins: ipblocker download (om mensen te kicken en te bannen) default_commands download (zeer aangeraden uitbreiding) SmileyParser download Toeligting op het voorbeeld Beschikbare commando's typ maar eens /help in. Voor gedetailleerde help typ /help functienaam, bijv /help login . Als hij het niet meer doet, niet reageert, of je kunt niet meer op de send-knop drukken: Pagina even reloaden. Meestal is dit het gevolg van traag antwoord van de server. officieel gezien moet ik een licentie meeleveren. GNU GPL Licentie hier beschikbaar (neem aan welbekend). Veranderingen 16 mei 2005: naam kan nu spaties bevatten 16 mei 2005: Dat wat D@rk zei, oplossing voor/tegen lege grijze vakjes. 17 mei 2005: SQLtable die stond in server.php miste het ip-veld. Staat er nu bij. In de installer zat het al wel. 17 mei 2005: function_exists hier en daar verwijdert, had toch geen nut. 17 mei 2005: een errorbericht weggehaald, omdat het al ergens anders werd gemeld. 31 mei 2005: Smileyparser toegevoegd, ook wel bekend als messageparser. Maakt gebruik van .pak-bestanden (bekend van phpBB). Credits: Veel dank aan Jochum Molenaar die mij op het idee heeft gebracht om sessions te gebruiken. Ik was er (stom genoeg) niet opgekomen zonder zijn hulp. Ook dank aan de mensen van dit topic voor de wordwrap functie.

phpchat-v2-mysql
-------------------------------------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]

Reacties

0
Nog geen reacties.