<?php
error_reporting(0);
/****************************************
* Mini AJAX Chatroom By Longbill
* http://www.longbill.cn
* Longbill all rights reserved
* 2008-03-26
* 2019 全功能修复版
*
* 创作共用(Creative Commons)
*
* 你可以免费:
* * 拷贝、分发、呈现和表演当前作品
* * 制作派生作品
*
* 但是必须基于以下条款:
* * 署名。你必须明确标明作者的名字。.
* * 非商业用途。 你不可将当前作品用于商业目的。
* * 保持一致。 如果你基于当前作品更改、变换或构造新作品,你应当按照与当前协议完全相同的协议分发最终作品
* * 对于任何二次使用或分发,你必须让其他人明确当前作品的授权条款
* * 在得到作者的明确允许下,这里的某些条款可以放弃
*
* 此约定是法律文本 (完整的协议)的简单易读概要
****************************************/
//****************参数设置****************
// 显示在线用户
$disonline = true;
// 新登陆时显示最近内容的条数(默认为30条)
$leastnum = 30;
// 默认的房间名(默认是每天换一个文件),如果去掉d,则是每月换一个文件
$room = date("Y-m-d");
// 房间保存路径,必须以/结尾
$roomdir = "rooms/";
// 编码方式
$charset = "UTF-8";
// 客户端最大显示内容条数(建议不要太大)
$maxdisplay = 300;
//语言
$lang = array(
// 聊天室描述
"description" =>"在线聊天室",
// 聊天室标题
"title" =>"在线聊天室",
// 第一个到聊天室的欢迎
"firstone" =>"<span style='color:#16a5e9;'>欢迎来到在线聊天室!</span>",
// 关键字
"keywords" =>"聊天室,迷你,小型,AJAX,Chat,Chatroom,Longbill,Longbill.cn,PHP,Javascript",
// 发言提示
"hereyourwords" => "在这里发言!"
);
header("content-type:text/html; charset=utf-8");
$get_past_sec = 3; // 如果发现丢话,可以适当调大这个值
$touchs = 10; // 检查在线人数的时间间隔
$title = $lang["title"];
$earlier = 10;
$description = $lang["description"];
$origroom = $room;
$least = ($_GET["dis"])?intval($_GET["dis"]):$leastnum; //新登录时显示的条数
$touchme = $_POST['touchme'];
if (!is_dir($roomdir)) @mkdir($roomdir) or die("error when creating folder $roomdir");
$room = $_GET['room'];
if (!$room) $room = $_POST["room"];
$room = checkfilename($room);
if (!$room) $room = $origroom;
$filename = $roomdir.$room.".dat.php";
$datafile = $roomdir.$room.".php";
if (!file_exists($filename)) @file_put_contents($filename,'<?php die();?>'."\n".time()."|".$lang["firstone"]."\n");
if (!file_exists($datafile)) @file_put_contents($datafile,'<?php die();?>'."\n");
$action = @$_POST["action"];
// 检测文件名是否合法
function checkfilename($file)
{
if (!$file) return "";
$file = trim($file);
$a = substr($file,-1);
$file = preg_replace("/^[.\\\/]*/","",$file);
$file = preg_replace("/[.\\\/]*$/","",$file);
$arr = array("../","./","/","\\","..\\",".\\");
$file = str_replace($arr,"",$file);
return $file;
}
// 获取用户IP地址
function get_ip()
{
global $_SERVER;
if ($_SERVER)
{
if ( $_SERVER[HTTP_X_FORWARDED_FOR] )
$realip = $_SERVER["HTTP_X_FORWARDED_FOR"];
else if ( $_SERVER["HTTP_CLIENT_ip"] )
$realip = $_SERVER["HTTP_CLIENT_ip"];
else
$realip = $_SERVER["REMOTE_ADDR"];
} else {
if ( getenv( 'HTTP_X_FORWARDED_FOR' ) )
$realip = getenv( 'HTTP_X_FORWARDED_FOR' );
else if ( getenv( 'HTTP_CLIENT_ip' ) )
$realip = getenv( 'HTTP_CLIENT_ip' );
else
$realip = getenv( 'REMOTE_ADDR' );
}
return $realip;
}
// 保持在线
function keeponline()
{
global $disonline, $datafile;
if (!$disonline) return;
$name = $_POST['name'];
$ip = get_ip();
$onlines = @file_get_contents($datafile);
$s1 = "|{$name}|{$ip}|";
if (strpos($onlines, $s1) === false)
{
if (strpos($onlines,"|".$name."|") === false)
{
$fp = @fopen($datafile, "a+");
if ($fp)
{
if (@flock($fp, LOCK_EX))
{
@fputs($fp,time()."|".time().$s1."\n");
@flock($fp, LOCK_UN);
}
@fclose($fp);
}
} else {
echo "NAME"; // 名称重复了
die();
}
}
}
switch($action) {
case 'write': // 接收到消息
$color = $_POST["color"];
if (!preg_match("/[0-9a-fA-F]{6}/i",$color) || $color == "#000000") $color = "";
$color = "#".$color;
$size = intval($_POST["size"]);
$name = str_replace(array("\n","\r"),"",$_POST['name']);
if (!$name) die("No Name!!");
$ip = get_ip();
keeponline();
$s = "";
$style = "";
$font = $_POST["font"];
if ($font == "songti") $font = "宋体";
else if ($font == "heiti") $font = "黑体";
else if ($font == "kaiti") $font = "楷体_GB2312";
else $font = '';
$style .= (!$font)?"":"font-family:".$font.";";
$style .= (!$_POST["bold"])?"":"font-weight:bold;";
$style .= (!$color || $color == "#")?"":"color:{$color};";
$style .= (!$size || $size == "16")?"":"font-size:{$size}px;";
$t = time();
$content = $_POST['content'];
$content = str_replace(array('<', '>'), array('<', '>'), $content); // HTML 转义
$content = str_replace(array("\n", "\r"), '<br>', $content);
$content = ($style) ? "<span style='{$style}'>{$content}</span>" : $content; // 添加样式
$s.= $t."|".$name.":".$content."\n";
if (!$s) die("No Content!!");
$fp = @fopen($filename,"a+");
if (!$fp) die("repeat");
$re_time = 0;
while(!@flock($fp, LOCK_EX))
{
sleep(1);
$re_time++;
if ($re_time >=4) break;
}
if ($re_time < 4) {
@fputs($fp,$s);
@flock($fp, LOCK_UN);
} else {
die("repeat");
}
@fclose($fp);
die('OK');
break;
case 'read': // 读取最近的消息
$first = $_POST["first"];
$lastmod = intval($_POST["lastmod"]) - $get_past_sec; //得到两秒以内的所有发言,
$alastmod = @filemtime($filename);
$name = $_POST['name'];
$name = str_replace("\n","",$name);
$ip = get_ip();
$json = array();
$json["lastmod"] = time();
$item = array();
$newonline = array();
$offline = array();
$fp = @fopen($filename,'r');
flock($fp,LOCK_EX);
$s = fread($fp,filesize($filename));
flock($fp,LOCK_UN);
fclose($fp);
$lines = explode("\n",$s);
if ($alastmod >= $lastmod && !$first)
{
foreach($lines as $l)
{
$item2 = array();
$l = str_replace(array("\n", "\r"), '', $l);
if (strpos($l, "|") === false) continue;
$arr = explode("|", $l);
$t = intval($arr[0]);
if ($t >= $lastmod)
{
$item2["time"] = date("H:i:s",$t);
$item2["word"] = $arr[1];
$item[] = $item2;
}
}
}
else if ($first)
{
$item = array();
$total = count($lines);
for($i=$total-1;$i>=$total-$least;$i--) //显示新登录条数消息
{
if ($i<=0) break;
$item2 = array();
$l = str_replace(array("\n","\r"),"",$lines[$i]);
if (strpos($l,"|") === false) continue;
$arr = explode("|",$l);