웹마스터 팁

<?
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("<", "&lt;", $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">&nbsp;</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>&nbsp;
<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>&nbsp;
<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>&nbsp;
<span id="fstyle_b" onclick="tag('b','','fstyle');" class='bt'><b>b</b></span>&nbsp;
<span id="fstyle_i" onclick="tag('i','','fstyle');" class='bt'><i>i</i></span>&nbsp;
<span id="fstyle_s" onclick="tag('s','','fstyle');" class='bt'><s>s</s></span>&nbsp;
<span id="fstyle_u" onclick="tag('u','','fstyle');" class='bt'><u>u</u></span>&nbsp;
<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) {?>&nbsp;<?}
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) {?>&nbsp;<?}
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'> &nbsp; <font color='<?=$color_1?>'>비밀번호</font> : <input type='password' name='password' class='logn'> &nbsp; <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("&nbsp;");
  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, "&nbsp;<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"> &nbsp; &nbsp;  &nbsp; &nbsp; <input type="reset" onclick="talk()" value="취소" class="button">";
inn += " &nbsp; &nbsp;  &nbsp; &nbsp; <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 여기서..

제목 글쓴이 날짜
글쓰기 폼에 미리 기본 내용 입력 [24] 송동우 2012.07.18
29일 licencexe설치시 XE마비현상 [3] XE힘들당휴 2015.05.29
CentOS 6.5 웹로그 모니터링 awstats 설치하기 [1] lililiillililiil 2014.04.29
푸시알림 앱 소개 pushbullet 안드로이드와 아이폰, 데스크탑까지 되면서 공짜!! garnecia 2015.05.28
(version 1.6)새글과 새댓글을 알림받는 앱을 직접 만들어보세요(XE 홈페이지와 연동되는 GCM을 이용한 푸시 안드로이드 앱 만들기 가이드-XE 알림센터 연동) [23] 단희아빠 2015.03.21
네이버맵 좌표(Lat, Lng) 검색기 YJHOON 2015.05.27
공지목록의 추출기준을 문서번호가 아니라 글순서로 변경 sejin7940 2015.05.26
설문조사 컴퍼넌트의 종료일 관련 버그 수정 sejin7940 2015.05.26
외부이미지 링크 + 고해상도 이미지 섬네일 생성 팁 socialskyo 2015.05.26
XE Core 안정된 버젼 좀 알려주세요.. [1] 팔도준 2015.05.26
자바로 스크롤 구현 [1] 착한동구 2015.05.25
레이어형 로그인 사용시에 SSL 적용방법 (선택적 사용시) [1] 불금 2015.05.20
모바일뷰 사용 안 할때 (반응형등) 에도 '모바일에서 최적화된 화면으로 보기' 가 나오는 버그 패치 sejin7940 2015.04.10
XE 템플릿 문법 : 조건부 class 작성하기 AJKJ 2015.05.23
추천수로 제목에 효과주기 [15] こさき! 2014.04.29
확장 컴포넌트 밖으로 뺀 후 완전한 버튼화 [1] file 키스미베이베 2015.05.20
RSS 게시판 업데이터 모듈이 SSL 부분적용시 동작하지 않는 문제 해결하기 [25] Gunmania 2013.02.25
플렛모바일 네이버로 로그인하기 버튼 file LI-NA 2015.05.17
오늘 작성된 게시글수 [2] file kdp 2015.05.07
확장변수(textarea)에서 html 사용하기 [3] 하늘종 2010.11.01