웹마스터 팁
간단한 ajax 채팅소스입니다.
2008.10.23 19:35
<?
ob_start();
session_start();
/*
* 채팅소스 135 EUC-KR
* Developed By 사리 (sariputra3@naver.com)
* License : GNU Public License (GPL)
* Homepage : http://blog.naver.com/sariputra3
*/
$chat = "chat.php"; //파일이름
$folder = "./"; //데이타파일 저장경로(권한777)
$cwidth = 350; //채팅내용 넓이 (숫자로만)
$cheight = 300; //채팅방 높이
$refresh = 1500; // 새글 확인하는 인터벌
$color_1 = "#828282"; // 어두운색
$color_2 = "#F4F5EE"; // 배경색
$color_3 = "#E8E9E3"; // 본문에 경계선
$color_4 = "#DBDCD5"; // 버튼배경색
$color_5 = "#F7F8F1"; // 본문에 닉네임배경색
$color_6 = "#8E946E"; // 본문에 안내문
if(substr($_SERVER[HTTP_USER_AGENT], 25,6) == 'MSIE 6') $exp = 6;
$dph = $folder."_prhbt"; // 금칙어
$dpi = $folder."__prhbt"; // 금지닉네임
$time = time();
$thm = date("H:i:s",$time);
$sessid = session_id();
//$ip = str_pad(str_replace('.','',$_SERVER[REMOTE_ADDR]),12,'x');
$ip = substr($sessid,0,12);
if($_COOKIE[mck] == md5($_SESSION[mk])) {
list($admin, $isadmin) = $_SESSION[$_COOKIE[md5($_COOKIE[mck]."x1b".$_SESSION[mk])]];
}
function toutf($word) {
return iconv("CP949","UTF-8//IGNORE", $word);
}
function toeuc($word) {
return iconv("UTF-8","CP949//IGNORE", $word);
}
function vnumbr($view,$value) {
$ff = glob($view."*");
if($ff[0]) $fff = substr($ff[0],strlen($view));
else if($value) @fclose(@fopen($view.$value,"w"));
return $fff;
}
if(is_dir($folder."/_data/")){
$db = $folder."/_data/";
$gu = $folder."/_gst/_guest";
$wtd = $folder."/_gst/wt_";
$dgv = $folder."/_gst/gv";
$dgw = $folder."/_gst/gw";
$dgr = $folder."/_gst/r_";
$dgg = $folder."/_gst/g_";
$dwv = vnumbr($wtd, '+
'01');
} else {
mkdir($folder."/_data/");
mkdir($folder."/_gst/");
mkdir($folder."/_ban/");
echo "<script type="text/javascript">location.href = '?';</script>";
exit;
}
if(!$_SESSION[nick]) {
$_SESSION[nick] = urldecode('%EC%86%90%EB%8B%98')."_".substr($ip, 4, 4);
}
$eucuid = toeuc($_SESSION[nick]);
function RmDirm($dirName) {
$dirName = urldecode($dirName);
if(is_dir($dirName)) {
if(substr($dirName, -1) != "/") $dirName .= "/";
$d = opendir($dirName);
while($entry = readdir($d)) {
if($entry != "." && $entry != "..") {
if(is_dir($dirName.$entry)) RmDirm($dirName.$entry);
else @unlink($dirName.$entry);
}
}
closedir($d);
}
}
function writee($dwn,$mema) {
global $wtd, $db;
$ndwv = $dwn%25 + 1;
$ndwv = str_pad($ndwv, 2, '0', str_pad_left);
@rename($wtd.$dwn, $wtd.$ndwv);
$fp = fopen($db.$ndwv,"w");
fputs($fp,$mema);
fclose($fp);
return $ndwv;
}
function whisp($rno) {
global $ip, $db;
$rnt = count($rno);
for($i = 0;$rno[$i];$i++) {
$rnn = str_pad($rno[$i],2,0,str_pad_left);
if($fsz = @filesize($db.$rnn)) {
$fp = fopen($db.$rnn,"r");
$fpo = fread($fp,$fsz);
fclose($fp);
if(substr($fpo, 0, 2) == "x1bx1b") {
if(substr($fpo,2,12) == $ip || substr($fpo,14,12) == $ip) $dtt .= substr($fpo,26)."x18";
} else $dtt .= $fpo."x18";
}
}
return $dtt;
}
function reaad($wtend,$red) {
global $ip;
$r = 0;
if($wtend > $red) {
for($i =$red + 1;$i <= $wtend;$i++) {$rno[$r] = $i;$r++;}
} else {
if($red < 25) {for($i = $red + 1;$i <= 25;$i++) {$rno[$r] = $i;$r++;}}
for($i = 1;$i <= $wtend;$i++) {$rno[$r] = $i;$r++;}
}
return whisp($rno);
}
function newtext($text, $tt) {
if($text) {
$text = stripslashes($text);
$text = preg_replace("`[x1bx18x7ft]`", "", $text);
if($tt < 3) $text = str_replace("<", "<", $text);
if($tt > 2) {
$text = preg_replace('`on[a-z]+=`i', 'onxx=', $text);
$text = str_replace("javascript:", "java<s></s>script:",$text);
$text = preg_replace('`<>([fbisu][o>])`i', '<$1', $text);
}
if($tt > 1 && strlen($text) < 158) {
$text = preg_replace("`http://([^"'<>:rns]+)`i", "<a href='#none' onclick='window.open(this.innerHTML)'>http://$1</a>", $text);
}
}
return $text;
}
function guestt($hp,$gp) {
global $gu, $dgw;
while(file_exists($gu."_tmp")) {usleep(30000);}
$fg = fopen($gu,"r");
$fmp = fopen($gu."_tmp","w");
while($fgo = fgets($fg)) {
if(substr($fgo,0,12) != $hp) fputs($fmp,$fgo);
}
fclose($fg);
fclose($fmp);
copy($gu."_tmp",$gu);
@unlink($gu."_tmp");
if($gp !=1) fclose(fopen($dgw,"w"));
return $gp;
}
if($_POST[tt]) {
header ("Content-Type: text/html; charset=UTF-8");
header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header ("Cache-Control: no-cache, must-revalidate");
header ("Pragma: no-cache");
if($_POST[neme]){
if($_SESSION[nick] != $_POST[neme]){
if($_POST[neme] = newtext($_POST[neme], 1)) {
$memo .= "x1b<font class=mc><span class='mm'>".$_SESSION[nick]."</span> ".urldecode('+
'%E2%86%92')." <span class='mm'>".$_POST[neme]."</span>".urldecode('%EC%9C%BC%EB%A1%9C+%EB%B0%94%EA%BF%A8%EC%8A%B5%EB%8B%88%EB%8B%A4.')."</font>x1b".$thm."x18";
$_SESSION[nick] = $_POST[neme];
}
}
}
$meo = "";
$egw = @filemtime($dgw);
$egg = @filemtime($dgg.$ip);
if($_POST[tt] == 'a' || $memo || $egw > $egg) {
$fg = fopen($gu,"a+");
while($fgo = trim(fgets($fg))) {
if(!$is && substr($fgo,0,12) == $ip) {$is = 1;if($memo) $fgo = $ip."x1b".$_POST[neme]."x1bx1b";}
$meo .= $fgo;
if($egg - @filemtime($dgg.substr($fgo,0,12)) > 60) {$fgdo = substr($fgo,0,12);guestt($fgdo,0);@unlink($dgg.$fgdo);@unlink($dgr.$fgdo.vnumbr($dgr.$fgdo,0));}
}
if(!$is) {
$fgo = $ip."x1b".$_SESSION[nick]."x1bx1b";
$meo .= $fgo;
if($id){
$memo .= "x1b<font class='mc'><span class='mm'>".$_SESSION[nick]."</span>".urldecode('%EB%8B%98%EC%9D%B4+%EC%9E%85%EC%9E%A5%ED%95%98%EC%85%A8%EC%8A%B5%EB%8B%88%EB%8B%A4.')."</font>x1b".$thm."x18";
}
}
fclose($fg);
fclose(fopen($dgg.$ip,"w"));
if(!$is || $memo) {
$fgo = str_replace("x1bx1b","x1bx1bn",$meo);
$fg = fopen($gu,"w");
fputs($fg,$fgo);
fclose($fg);
fclose(fopen($dgw,"w"));$egw = $time;
}
echo $meo;
}
if($time != $egw && $dggv = @filemtime($dgv) > $egw && $dggv < $time) fclose(fopen($dgw,"w"));
if($_POST[content] == "x1bx1bx1b") {
guestt($ip,1);
if($id) {
$memo = "x1b<font class=mc><span class='mm'>".$_SESSION[nick]."</span>".urldecode('%EB%8B%98%EC%9D%B4+%ED%87%B4%EC%9E%A5%ED%95%98%EC%85%A8%EC%8A%B5%EB%8B%88%EB%8B%A4.')."</font>x1b".$thm;
writee($dwv,$memo);
}
fclose(fopen($dgv, "w"));
@unlink($dgg.$ip);
@unlink($dgr.$ip.vnumbr($dgr.$ip,0));
exit;
}
if(file_exists($folder."/_ban/".$ip)) {
echo "<script type="text/javascript">location.href='?';</script>";
exit;
}
if($time != $egw && $dggv = @filemtime($dgv) > $egw && $dggv < $time) fclose(fopen($dgw,"w"));
if($_POST[neme] && $_POST[content]){
$_POST[content] = newtext($_POST[content], 3);
if($_POST[content]) $memo .= $_POST[neme]."x1b".$_POST[content]."x1b".$thm;
} else $memo = substr($memo,0,-1);
if($memo) $dwv = writee($dwv,$memo);
if($_POST[tt] != 'a') $red = vnumbr($dgr.$ip,0);
if($_POST[tt] == 'a' || $red <> $dwv) {
if($_POST[tt] == 'a' || !@rename($dgr.$ip.$red,$dgr.$ip.$dwv)) fclose(fopen($dgr.$ip.$dwv,"w"));
if($_POST[tt] == 'a') $red = $dwv;
$reead = reaad($dwv,$red);
if($reead) echo "x7f".$reead;
}
exit;
} else {
header ("Content-Type: text/html; charset=euc-kr");
if($_GET[to] && $_GET[memo] = newtext($_GET[memo], 2)) {
$memo= "x1bx1b".$ip.$_GET[to]."-- x1b<font class=mc><font class='mm'>".toutf($_GET[x]."</font>님에게 <font class='mm'>".$eucuid."</font>님의 귓속말 :</font><br><br><font class=mc>".$_GET[memo])."</font>x1b".$thm;
writee($dwv,$memo);
exit;
}
if($admin && isset($_POST[prhb]) && isset($_POST[prhc])) {
$fph = fopen($dph, "w");
$cnt = count($_POST[prhb]);
for($i = 0; $i < $cnt; $i++) if($_POST[prhb][$i]) fputs($fph, $_POST[prhb][$i]."n");
fclose($fph);
$fpi = fopen($dpi, "w");
$cnt = count($_POST[prhc]);
for($i = 0; $i < $cnt; $i++) if($_POST[prhc][$i]) fputs($fpi, $_POST[prhc][$i]."n");
fclose($fpi);
if($_POST[echrm] == 'b') fclose(fopen($dph."_echrm","w"));
else @unlink($dph."_echrm");
echo "<script type="text/javascript">location.href='/?open=1';</script>";
exit;
}
if($_POST[loginout]){
if($_POST[loginout] == "logout") {
while(list($key,$value) = each($_COOKIE)) {setcookie($key,'');}
session_destroy();
} else if($_POST[username] && $_POST[password]){
///----------------------------------------------------------------mysql host가 localhost가 아닌경우 아래 수정..
$okok = mysql_connect("localhost", $_POST[username], $_POST[password]);
if($okok){
$mk = substr(md5($sessid),rand(1,25));
$_SESSION[mk] = $mk;
$yid = md5($mk);
setcookie("mck", $yid);
$xid = md5($yid."x1b".$mk);
$wid = "w".rand(1000,100000);
setcookie($xid, $wid);
$_SESSION[$wid] = array($_POST[username],$yid);
}
}
echo "<script type="text/javascript">location.href='?';</script>";
exit;
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ko">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">
<style type='text/css'>
body {font-size:9pt;font-family:gulim;overflow-y:auto;overflow-x:hidden;}
td,select {font-size:9pt;}
input {font-size:9pt;padding:0}
a:link {color:<?=$color_1?>}
a:visited {color:<?=$color_1?>}
a:hover {color:blue;text-decoration:underline;}
.x {text-decoration:none;}
.log {border-width:6px; border-color:<?=$color_3?> <?=$color_1?> <?=$color_1?> <?=$color_3?>; border-style: solid;background-color:<?=$color_2?>;text-align:center}
.f8 {font-family:Tahoma;font-size:8pt;color:#F9BDAC}
.f7 {font-family:Tahoma;font-size:7pt;color:<?=$color_1?>}
.mm {color:<?=$color_6?>;font-weight:bold;font-family:gulim;text-align:center;padding-top:5px}
.mc {color:<?=$color_6?>;font-family:gulim;text-align:center;padding-top:5px}
.mh {padding-top:7px}
.button {background-color:<?=$color_4?>;border:0;border:1px solid <?=$color_1?>;margin-right:4px;margin-left:4px;width:45px}
.bt {background-color:<?=$color_4?>;border:0;border:1px solid <?=$color_1?>;cursor:pointer;font-size:11pt;width:15px;font-weight:bold;padding:1px 6px 1px 6px;}
.logn {border:0;border-bottom:1px solid <?=$color_1?>;width:77px;color:<?=$color_1?>}
.n {color:#98AFA8;font-weight:bold;}
.nobr {overflow-x:hidden;overflow-y:hidden;white-space:nowrap;}
.intex {width:80px;font-size:8pt;border:0;margin-top:4px;border-width:0px 0px 1px 0px;border-style:solid;border-color:black}
#AA {height:<?=$cheight?>px;width:<?=$cwidth?>px;overflow-x:hidden; overflow-y:auto;background-color:#FFFFFF;border:1px solid <?=$color_1?>;float:left}
#CC {width:100px;padding:5px;float:right;border-bottom:1px solid <?=$color_3?>;font-weight:bold;color:<?=$color_6?>;font-family:gulim;text-align:center;}
#DD {clear:right;padding-top:10px}
</style>
<!--[if IE]>
<style type='text/css'>
body {word-break:break-all;scrollbar-highlight-color:#FFFFFF; scrollbar-3dlight-color:<?=$color_1?>; scrollbar-face-color:<?=$color_2?>; scrollbar-shadow-color:<?=$color_1?>; scrollbar-darkshadow-color:#FFFFFF; scrollbar-track-color:#FFFFFF; scrollbar-arrow-color:<?=$color_1?>;}
td {word-break:break-all;}
</style>
<![endif]-->
<?
if($_GET[delete] == "all" && $admin) {
RmDirm($folder."/_data/");
RmDirm($folder."/_gst/");
RmDirm($folder."/_ban/");
echo "<script type="text/javascript">location.href = '?';</script>";
exit;
}
if($_GET[ban] && $admin && $_GET[ban] != $ip) {
fclose(fopen($folder."/_ban/".$_GET[ban],"w"));
$memo = "x1b<font class=mc><span class='mm'>".toutf($_GET[nick]."</span>님이 강퇴되셨습니다.")."</font>x1b".$thm;
writee($dwv,$memo);
guestt($_GET[ban],0);
@unlink($dgg.$_GET[ban]);
@unlink($dgr.$_GET[ban].vnumbr($dgr.$_GET[ban],0));
exit;
}
?>
<title>채팅방 - <?=$_GET[id]?></title>
<script type="text/javascript">
var gout = 0;
window.onbeforeunload = function(){if(gout != 3 && gout != 1){go('out');gout=3;return "---";}}
</script>
</head>
<body onLoad="setTimeout('setup()', 400);">
<div align='center'>
<div style='border:1px solid <?=$color_6?>;padding:5px;width:<?=$cwidth + 115?>px;' align='left'>
<div id='AA'></div><div id='CC'></div>
<div id='DD' style='height:<?=$cheight - 30?>px;overflow-x: hidden; overflow-y: auto;'></div>
<div style='padding:6px 0px 8px 0px;clear:both'>
<form name="cwf" style="margin:0" onsubmit="go('rpage');return false;" target="exeframe">
<input type="text" name="neme" maxlength="10" style="width:78" value="<?=$eucuid?>">
<input type="text" name="content" maxlength='200' style="width:<?=$cwidth - 81?>px;height:20px;font-size:9pt;overflow-y:hidden;ime-mode:active" onmouseover=this.focus();>
<input type="submit" value="쓰기" class="button" style='width:90px'><br>
<div style='float:left'>
<select name="fcolor" style="width:60px;background-color:#000000" onchange="var xx=this.options[this.selectedIndex].value;if(xx){tag(xx,'+
'color','fcolor');this.style.backgroundColor=xx}else{this.style.backgroundColor='#000000'}">
<option value="" style="background-color:000000"> </option>
<option value="919191" style="background-color:919191"></option>
<option value="d3d3d3" style="background-color:d3d3d3"></option>
<option value="ff0000" style="background-color:ff0000"></option>
<option value="ffa500" style="background-color:ffa500"></option>
<option value="ff1493" style="background-color:ff1493"></option>
<option value="deb887" style="background-color:deb887"></option>
<option value="b8860b" style="background-color:b8860b"></option>
<option value="7cfc00" style="background-color:7cfc00"></option>
<option value="32cd32" style="background-color:32cd32"></option>
<option value="008000" style="background-color:008000"></option>
<option value="00bfff" style="background-color:00bfff"></option>
<option value="0000ff" style="background-color:0000ff"></option>
<option value="0000b0" style="background-color:0000b0"></option>
<option value="ff00ff" style="background-color:ff00ff"></option>
<option value="ba00ba" style="background-color:ba00ba"></option>
<option value="800080" style="background-color:800080"></option>
</select>
<select name="fface" onchange="var xx=this.options[this.selectedIndex].value;if(xx)tag(xx,'face','fface');">
<option value="">- 글꼴</option>
<option value="굴림">굴림</option>
<option value="돋움">돋움</option>
<option value="바탕">바탕</option>
<option value="궁서">궁서</option>
<option value="Arial">Arial</option>
<option value="Tahoma">Tahoma</option>
<option value="Verdana">Verdana</option>
</select>
<select name="fsize" onchange="var xx=this.options[this.selectedIndex].value;if(xx)tag(xx,'size','fsize');">
<option value="">- 크기</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
<span id="fstyle_b" onclick="tag('b','','fstyle');" class='bt'><b>b</b></span>
<span id="fstyle_i" onclick="tag('i','','fstyle');" class='bt'><i>i</i></span>
<span id="fstyle_s" onclick="tag('s','','fstyle');" class='bt'><s>s</s></span>
<span id="fstyle_u" onclick="tag('u','','fstyle');" class='bt'><u>u</u></span>
<input type="hidden" name="fstyle" value="">
</div>
<div style='float:right'><input type='button' class="button" onclick="document.getElementById('login').style.display=(document.getElementById('login').style.display=='none')?'block':'none'" value="admin"></div>
</form></div>
<script type="text/javascript">
var obj = document.getElementsByName('content')[0];
function tag(fvalue, postfix, fname) {
var fsvalue = document.cwf.fstyle.value;
if(fname != 'fstyle' || fsvalue != fvalue) {
if(obj.createTextRange && obj.currentPos && obj.currentPos.text && obj.currentPos.text != obj.value) {
document.getElementsByName(fname)[0].value = '';
if(fname != 'fstyle') obj.currentPos.text = "<font " + postfix + "=" + fvalue + ">" + obj.currentPos.text + "</font>";
else obj.currentPos.text = "<" + fvalue + ">" + obj.currentPos.text + "</" + fvalue + ">";
} else if(obj.selectionEnd && obj.selectionStart != obj.selectionEnd && (obj.selectionStart != 0 ||obj.selectionEnd != obj.value.length)) {
var s1 = obj.value.substring(0, obj.selectionStart);
var s2 = obj.value.substring(obj.selectionStart, obj.selectionEnd);
var s3 = obj.value.substring(obj.selectionEnd);
document.getElementsByName(fname)[0].value = '';
if(fname != 'fstyle'+
') obj.value = s1 + "<font " + postfix + "=" + fvalue + ">" + s2 + "</font>" + s3;
else obj.value = s1 + "<" + fvalue + ">" + s2 + "</" + fvalue + ">" + s3;
} else document.getElementsByName(fname)[0].value = fvalue;
}
if(fname == 'fstyle' && document.cwf.fstyle.value != '') {
if(fvalue != 'b') document.getElementById("fstyle_b").style.background = "<?=$color_4?>";
if(fvalue != 'i') document.getElementById("fstyle_i").style.background = "<?=$color_4?>";
if(fvalue != 's') document.getElementById("fstyle_s").style.background = "<?=$color_4?>";
if(fvalue != 'u') document.getElementById("fstyle_u").style.background = "<?=$color_4?>";
if(fsvalue == fvalue) {
document.cwf.fstyle.value = '';
document.getElementById("fstyle_" + fvalue).style.background = "<?=$color_4?>";
} else document.getElementById("fstyle_" + fvalue).style.background = "<?=$color_1?>";
}
obj.focus();
}
</script>
<div id='login' style='display:none;width:<?=$cwidth +100?>px;text-align:center'>
<form style="margin:0px;width:100%" method="post" action="?" onsubmit="gout=1"><hr size='5' color='<?=$color_4?>'>
<?
if($admin){
?>
내용중 금칙어 지정<hr size='+
'1' color='<?=$color_4?>'>
<?
if(file_exists($dph)){
$i = 1;
$fph = fopen($dph, "r");
while($fpp = trim(fgets($fph))) {
?>
<input type='text' name='prhb[]' class='intex' value='<?=$fpp?>'>
<?
if($i % 3) {?> <?}
else {?><br><?}
$i++;
}
fclose($fph);
}
?>
<br><input type='text' name='prhb[]' class='intex'>
<hr size=3 color=<?=$color_4?>>
금지 닉네임 지정<hr size='1' color='<?=$color_4?>'>
<?
if(file_exists($dpi)){
$i = 1;
$fph = fopen($dpi, "r");
while($fpp = trim(fgets($fph))) {
?>
<input type='text' name='prhc[]' class='intex' value='<?=$fpp?>'>
<?
if($i % 3) {?> <?}
else {?><br><?}
$i++;
}
fclose($fph);
}
?>
<br><input type="text" name="prhc[]" class="intex"><br><br>
<input type="submit" value="입력" class="button">
</form><hr size='5' color='<?=$color_4?>'><form style='margin:0' method=post action='?' onsubmit="gout=1">
<input type="button" onclick="gout=1;if(confirm('리셋하시겠습니까'))location.href='/?delete=all';" value="채팅방리셋" class="button" style="width:100px"><input type="hidden" name="loginout" value="logout"><input type="submit" value="로그아웃" class="button" style="width:100px"></form></td></tr>
<?
} else {
?>
<input type='hidden' name='loginout' value='login'><font color='<?=$color_1?>'>아이디</font> : <input type='text' name='username' class='logn'> <font color='<?=$color_1?>'>비밀번호</font> : <input type='password' name='password' class='logn'> <input type="submit" value='로그인' class="button" style='width:50px'>
<?
}
if($_GET[open]) echo "<script type="text/javascript">document.getElementById('login').style.display='block';</script>";
?>
</form></div></div></div>
<script type="text/javascript">
function go(view) {
if(view == 'banned') {
gout = 1;
alert("강퇴되셨습니다.");
location.href='?';
} else if(view == 'baned') {
gout = 1;
alert("채팅방이 삭제되었습니다.");
location.href='?';
} else {
var param = '';
var ok = '';
if(view == 'rpage') {
var nam = document.cwf.neme.value.replace(/[&'"]/gi,"");
var contt = document.cwf.content.value.replace(/`/g,"").replace(/%/g,"%25").replace(/&/g,"%26").replace(/+/g,"%2B");if(contt =='') return false;
var ccolor = document.cwf.fcolor.value;
var csize = document.cwf.fsize.value;
var cface = document.cwf.fface.value;
var cstyle = document.cwf.fstyle.value;
if(ccolor||csize||cface){
var fff = "<font";
if(ccolor) fff += " color=" + ccolor;
if(csize) fff += " size=" + csize;
if(cface) fff += " face=" + cface;
contt = fff + ">" + contt + "</font>";
}
if(cstyle) contt = "<" + cstyle + ">" + contt + "</" + cstyle + ">";
contt = contt.replace(/<([^/])/g, "<>$1");
var dph = Array(<?
if(file_exists($dph) && !$admin){
$fph = fopen($dph, "r");
if(!feof($fph)) {
echo "'".trim(fgets($fph))."'";
while($ppp = trim(fgets($fph))) echo ",'".$ppp."'";
}
fclose($fph);
}
?>
);
var dpi = Array(<?
if(file_exists($dpi) && !$admin){
$fpi = fopen($dpi, "r");
if(!feof($fpi)) {
echo "'+
'".trim(fgets($fpi))."'";
while($ppp = trim(fgets($fpi))) echo ",'".$ppp."'";
}
fclose($fpi);
}
?>
);
for(var i = 0; dph[i]; i++){
if(document.cwf.content.value.indexOf(dph[i]) != -1) {
ok = "not";
alert("금칙어 '"+ dph[i] +"' 가 포함되어 있습니다.");
break;
}
}
if(ok == "") {
if(document.getElementById('pnam').value != nam) {
var dupl = document.getElementById('DD').innerHTML.replace(/<[^>]+>/g,"").split(" ");
for(var i = 1; dupl[i]; i++) {
if(dupl[i] == nam) {
ok = "not";
alert("중복된 '닉네임' 입니다");
break;
}
}
for(var i = 0; dpi[i]; i++) {
if(dpi[i] == nam) {
ok = "not";
alert("금지된 '닉네임' 입니다");
break;
}
}
}
if(ok == "") {
document.getElementById('pnam').value = nam;
if(document.getElementById('prev').value != contt) {
param = '<?=$chat?>?&neme='+ nam +'&content='+ contt + '&tt=' + document.getElementById('ntim').value;
}
}
}
} else if(view == 'out') {
param = "<?=$chat?>?&content=x1bx1bx1b&tt=" + document.getElementById('ntim').value;
} else if(gout != 3) {
param = '<?=$chat?>?&tt=' + document.getElementById('ntim').value;
}
if(param != '') {
if(window.ActiveXObject) {
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else if(window.XMLHttpRequest) {
var xmlHttp = new XMLHttpRequest();
}
xmlHttp.open("POST", param, true);
xmlHttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xmlHttp.setRequestHeader("Content-length", param.length);
xmlHttp.setRequestHeader("Connection", "close");
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState=='4' && xmlHttp.status=='200') {
var str = xmlHttp.responseText;
if(str == "") document.title = (document.title == "채팅방 ‥<?=$_GET[id]?> ┏┃┛")?'채팅방 ‥<?=$_GET[id]?> ┗┃┓':'채팅방 ‥<?=$_GET[id]?> ┏┃┛';
else if(str == "<script type="text/javascript">location.href='?';</script>") go('banned');
else if(str == "<script type="text/javascript">location.href = '?';</script>") go('baned');
else {
var vew = str.split("x7f");
if(vew.length > 0 && vew[0]){
var strr = vew[0].replace(/([^x1b]+)x1b([^x1b]+)x1bx1b/gi, " <font onclick='talk("$1","$2")' style='cursor:pointer'>$2</font><br>");
strr = "<span class='mm'>" + strr + "</span>";
document.getElementById('DD').innerHTML = strr;
}
if(vew.length > 1 && vew[1]){
var aline = vew[1].split("x18");
var strr = "";
var alinength = aline.length -1;
for(var i = 0;i < alinength;i++){
if(aline[i]) {
var nam = aline[i].split("x1b");
strr += "<div><span class='n' title='"+ nam[2] +"'>["+ nam[0] +"]</span> "+ nam[1] +"</div>";
}}
document.getElementById('AA').innerHTML = document.getElementById('AA').innerHTML.substring(0,document.getElementById('AA').innerHTML.length-8) + strr + "</table>";
document.getElementById('AA').scrollTop = 10000000;
document.title = '새글이 올라왔습니다. ‥<?=$_GET[id]?>';
if(document.getElementById('ntim').value != "b") document.getElementById('ntim').value = "b";
}
}
if(view == 'rpage') {
document.getElementById('prev').value = document.cwf.content.value;
document.cwf.content.value = "";
document.cwf.content.focus();
} else if(view == 'read') setTimeout("go('read')", <?=$refresh?>);
delete xmlHttp;
}
}
if(document.getElementById('ntim').value == "a") document.getElementById('ntim'+
').value = "c";
xmlHttp.send(param);
if(view == 'out') return view;
} else document.cwf.content.focus();
}
}
function gg() {
var today = new Date();
H = today.getHours();
if(H < 10) H = "0" + H;
M = today.getMinutes();
if(M < 10) M = "0" + M;
S = today.getSeconds();
if(S < 10) S = "0" + S;
document.getElementById('CC').innerHTML = "[" + H + ":" + M + ":" + S + "]";
setTimeout('gg()', 900);
}
function setup() {
document.getElementById('ntim').value='a';
gg();
go('read');
document.cwf.content.focus();
}
function talk(ip, x) {
var talk = document.getElementById('talk');
if(x == '' ||ip == '' ||talk.style.display == "block") {
talk.innerHTML = "";
talk.style.display = "none";
document.cwf.content.focus();
} else {
var inn = "<div align='center'><div class='log' style='z-index:101;width:330px;padding:10px'>" + x + "님에게 귓속말을 전합니다<br><input type='hidden' name='id' value='<?=$_GET[id]?>'><input type='hidden' name='to' value='" + ip + "'><input type='hidden' name='x' value='" + x + "'><input type='+
'text' name='memo' maxlength='200' style='width:300px'><br><input type='submit' value='전송' class="button"> <input type="reset" onclick="talk()" value="취소" class="button">";
inn += " <input type='button' onclick="if(confirm('" + x + "님을 강퇴합니까?')) window.open('?id=<?=$ued?>&ban=" + ip + "&nick=" + x + "', 'exeframe');talk()" value="강퇴" class="button">";
inn += "</div></div>";
talk.innerHTML = inn;
talk.style.top = document.body.scrollTop + 100;
talk.style.left = document.body.clientWidth/2 - 180 + 'px';
talk.style.display = "block";
talk.memo.focus();
}
}
</script>
<input type="hidden" id="ntim" value="a"><input type="hidden" id="prev" value=""><input type="hidden" id="pnam" value="<?=$eucuid?>">
<iframe name="exeframe" width="0px" height="0px" style="display:none"></iframe>
<div align='center'><form id="talk" action="<?=$chat?>" target="exeframe" onsubmit="gout=1;setTimeout('talk()', 50)" style="display:none;position:absolute;"></form></div>
</body>
</html>
<?
}
?>
여기가 소스끝..
배포하고 있는 ajax 채팅소스가 있는데,
그건 채팅방 개설해서 사용하는 방식이고,
이건 채팅방 하나짜리 입니다.
이건 따로 파일로 배포할게 아니라서, 이렇게 개인블로그에 올렸는데,
여기도 올려봅니다.
브라우저에서 인코딩은 euc-kr
소스내부 처리과정의 인코딩은 utf-8입니다.
채팅 데이타는 텍스트파일 25개에 순차적으로 저장됩니다.
26번째는 다시 01번 파일에,,,(그렇게 로테이션으로..)
어디까지 읽어갔는지를 사용자마다 서버에 파일로 기록하고 있습니다.(파일이름에다가)
사용자가 갱신해서 읽어간 방문자목록의 시간을 파악하기 위해서,
방문자목록을 읽어갈때, 빈파일을 생성하도록 해서,, 그 파일의 생성시점을 기준으로해서,
방문자목록에 변동이 있을때, 다시 읽어가거나, 아니면 지나치거나 합니다.
서버로의 접속은 ajax로 이뤄지고, 접속이 끝나고 1.5초 뒤에 다시 접속합니다.
배포하고 있는, 채팅방 개설하는 소스에는, 파일업로드도 있는데,
이건 간결하게 하느라고, 파일업로드는 없앴습니다.
관리자의 확인은, mysql에 접속되는지 여부로 판단합니다.
mysql을 그외의 용도로는 사용하지 않습니다.
사용된 php함수중에 glob() 함수가 있는데,
이건 PHP 4.3.0 버전이후부터 된다고 하더군요.
그래서, PHP 4.3.0 버전부터 됩니다.
소스10번줄, 11번줄은 소스의 파일이름과 데이타저장경로를 설정하는 부분입니다.
$chat = "chat.php"; //파일이름
$folder = "./"; //데이타파일 저장경로(권한777)
경로나 이름은 어떻게 해도 좋은데,
반드시 $chat 변수에 파일이름을 담고, $folder 변수에 ,,php가 읽고쓰고 할수 있도록, 권한 777을 준 디렉토리를 지정해줘야 합니다.
27~28번줄은 사용자를 특정하는 부분입니다.
//$ip = str_pad(str_replace('.','',$_SERVER[REMOTE_ADDR]),12,'x');
$ip = substr($sessid,0,12);
아이피를 이용하고자 하면 위쪽에 주석을 제거하고, 아래쪽에 주석처리하시고,
28줄에 $sessid는 그 위쪽에서 session_id()를 담고 있는 변수입니다.
세션아이디로 사용자를 특정하고자 할때는 지금 그대로.... 사용하면 됩니다.
귓속말기능 있고, 글자색같은..간단한 태그지원기능이 있고,
관리자에 의한 강퇴도있고, 채팅방 리셋도 있고, 금칙어설정도 있고, 금지닉네임설정도 있습니다.
배포하고 있는 채팅소스는 http://www2.ssam.biz/blog/?tb=1&ct=6 여기서..
댓글 12
-
제로저아
2008.10.23 19:39
-
제로저아
2008.10.23 19:49
이 소스의 예제는 http://www2.ssam.biz/chat/chat.php 여기고,
방문자가 퇴장하는 즉시, 방문자하고 관계된 파일이 전부 삭제됩니다.
--새로고침해도 마찬가지..
그러니까 계속 열어둬도, 뭐가 누적되어서 쌓이거나 하는건 없습니다.
데이타저장파일은 계속 25개고, 방문자하고 관계된 파일은 퇴장할때 삭제되니까요.
저번에 한번은 서버에 로그가 많이 쌓인다는 항의를 받은적이 있는데,
그 문제는 잘 모르겠군요.. -
이진수닷넷
2008.11.27 14:39
이글을 이제보다니...ㅋㅋ 공개감사드립니다.. -
제로저아
2008.12.07 00:25
이거 업글했습니다.
http://www2.ssam.biz/srboard/index.php?id=blog&no=787
오페라에서 내용이 박스밖으로 흐르는문제 고치고,
xhtml 1.0 웹표준으로 했습니다.
그리고 사소한 수정사항 몇몇개 있습니다.
색상이나 모양은 변하지 않았습니다. -
제로저아
2009.03.07 21:39
http://www2.ssam.biz/srboard/index.php?id=blog&no=&ct=06
계속 업뎃하고 있습니다.
인코딩에 따라 euc-kr, UTF-8 두가지,
그리고 채팅방 하나짜리와 개설하는 것 두가지. 총 네가지로 업뎃하고 있습니다. -
성범918
2009.03.20 12:24
good -
위남자
2009.05.21 09:53
제로보드에 첨 들어왔습니다. 초짜입니다.
이런 채팅창을 어떻게 제 홈에 부착하나요? 욕심은 나는데 올릴 방법을 몰라서요^^
제 홈은 http://winamja.com.ne.kr 입니다. 이제 막 시작을 해서 아무 것도 몰라요 다만 플러쉬를 조금 할 줄 알아 만들고 플러쉬로 만들고 있습니다.
-
제로저아
2009.05.22 16:25
혹시 거기도 php입니까?. 컴내꺼 ?
아니라면,, gigalive를 권장하겠습니다.
http://explanation.textcube.com/40 여기 붙이는 방법 설명되어 있네요
이 채팅소스는 php서버에서만 실행가능한 것입니다.
혹시 잘못 짚었다면 죄송합니다.
-
PsychOcean
2009.05.28 09:20
com.ne.kr 계정은 php 및 mysql 등을 지원하지 않습니다.
고로 제로보드나 PHP를 사용할 수 없습니다. 다른 무료 호스팅을 사용하시던가 유료 호스팅을 구매하셔야 해요~~~~ -
modamoda
2009.06.09 23:32
간단하지 않아요...ㅠㅠ -
srboard
2011.02.10 21:58
이걸로 찾아오시는 분들이 많은데,
http://www.xpressengine.com/?mid=download&category_srl=18322927&package_srl=19219428
이거 배포하고 있습니다. XE위젯용으로. -
무한탐구
2011.11.14 16:21
우워 방대하다. ajax 채팅인가?
달라진 부분이 없습니다. 그냥 그대로 복사해서 저장해서 쓰시면 되겠습니다.
----------- 그 얘기를 빠뜨렸는데, 채팅파일 하나로 돌아갑니다.
///----------------------------------------------------------------mysql host가 localhost가 아닌경우 아래 수정..
$okok = mysql_connect("localhost", $_POST[username], $_POST[password]);
이런 부분이 중간쯤에 있습니다.
관리자로그인 확인용으로 mysql에 접속하는거.
-- 혹시 뭐가 다르면, 소스를 수정해서 쓰시라고...알려드립니다.