json = new JSON_obj(); $this->username = $_SESSION['username']; $this->password = $_SESSION['password']; // run the garbage collector (chance run) $this->gc(); // figure out which action we need to execute, // then execute it and print the output switch($call) { case 'login': print $this->login(strtolower($_POST['username']), $_POST['password']); break; case 'logout': print $this->logout(); break; case 'ping': print $this->ping($_POST['away']); break; case 'send': print $this->send($_POST['recipient'], $_POST['message'], $_POST['font'], $_POST['fontsize'], $_POST['fontcolor'], $_POST['bold'], $_POST['italic'], $_POST['underline'], $_POST['chatroom']); break; case 'addbuddy': print $this->addBuddy(strtolower($_POST['username']), $_POST['group']); break; case 'removebuddy': print $this->removeBuddy($_POST['username']); break; case 'blockbuddy': print $this->blockBuddy($_POST['username'], ($_POST['status']?$_POST['status']:0)); break; case 'removegroup': print $this->removeGroup($_POST['group']); break; case 'register': print $this->register($_POST['username'], $_POST['password'], $_POST['email']); break; case 'isuser': print $this->isUser(strtolower($_POST['username'])); break; case 'reset': print $this->reset($_POST['email']); break; case 'pwdchange': print $this->passwordChange($_POST['password'], $_POST['newpwd']); break; case 'joinroom': print $this->joinRoom($_POST['room']); break; case 'leaveroom': print $this->leaveRoom($_POST['room']); break; case 'roomlist': print $this->roomList(); break; case 'changeicon': print $this->changeIcon(); break; case 'changeprofile': print $this->changeProfile($_POST['profile']); break; case 'getprofile': print $this->getProfile($_POST['user']); break; } } /** * Logs the user in and sets the session for the user. * * @return JSON object of buddies/blocked users if it usr was successfully logged in, error string otherwise * @author Joshua Gross **/ function login($username, $password) { $user = $this->checkInfo($username, $password, array('admin', 'banned')); if(!$user) return 'invalid'; if($user['banned'] == 1) return 'banned'; $_SESSION['username'] = $username; $_SESSION['password'] = $password; $_SESSION['admin'] = $user['admin']; $set_status = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=1, last_ip=\'' . $_SERVER['REMOTE_ADDR'] . '\' WHERE username=\'' . $username . '\''); $buddylist = $this->getBuddylist($username, false); $blocklist = $this->getBlocklist($username); $this->userEvent($username, $buddylist, 'status', array('status'=>1)); $buddylist = $this->getBuddylistOnline($username); if(count($buddylist) > 0) $output['buddy'] = $this->json->encode($buddylist); else $output['buddy'] = array(); $output['blocked'] = $this->json->encode($blocklist); $output['admin'] = $user['admin']; return $this->json->encode($output); } /** * Logs the user out and destroys the session. * * @return String 'logged_out' * @author Joshua Gross **/ function logout() { if(!$this->checkInfo($this->username, $this->password)) return 'invalid'; $buddylist = $this->getBuddylist($this->username, false); $set_status = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=0, last_ping=\'' . time() . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\''); $in_chatrooms = mysql_query('SELECT room FROM ' . SQL_PREFIX . 'chats WHERE user=\'' . mysql_real_escape_string($this->username) . '\''); while($row = mysql_fetch_assoc($in_chatrooms)) { $buddylist['users'] = $this->getChatlist($row['room']); $this->userEvent($this->username, $buddylist, 'chat', array('action'=>'left', 'room'=>$row['room'])); } $exit_rooms = mysql_query('DELETE FROM ' . SQL_PREFIX . 'chats WHERE user=\'' . mysql_real_escape_string($this->username) . '\''); $notify_buddies = $this->userEvent($this->username, $buddylist, 'status', array('status'=>0)); $_SESSION = array(); if (isset($_COOKIE[session_name()])) setcookie(session_name(), '', time()-42000, '/'); session_destroy(); return 'logged_out'; } /** * Checks the database for new messages and events. * * @return JSON object of new messages/events if any, otherwise nothing * @author Joshua Gross **/ function ping($away) { $user = $this->checkInfo($this->username, $this->password, array('is_online', 'last_ping')); if(!$user) { $set_status = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=0, last_ping=\'' . time() . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\''); return 'not_logged_in'; } $buddylist = $this->getBuddylist($this->username, false); $set_status = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=\'' . mysql_real_escape_string($away + 1) . '\', last_ping=\'' . time() . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\''); if($user['is_online'] != ($away + 1)) $this->userEvent($this->username, $buddylist, 'status', array('status'=>($away + 1))); foreach($buddylist as $group => $users) { $user_count = count($users); $reverse_list = array(); for($i = 0; $i < $user_count; $i++) $reverse_list[$users[$i]] = $group; } $query = mysql_query('SELECT id, message, type, sender, recipient FROM ' . SQL_PREFIX . 'messages WHERE (recipient=\'' . mysql_real_escape_string($this->username) . '\') GROUP BY sender, message, recipient ORDER BY id ASC'); $i=0; $j=0; $to_delete = array(); $output = array(); while ($row = mysql_fetch_assoc($query)) { if(strpos($row['type'], 'msg') !== false) { if($row['sender'] != $this->username || $row['sender'] == $row['recipient']) { $output['messages'][$i++] = array('message' => $row['message'], 'sender' => $row['sender'], 'recipient' => $row['recipient'], 'chatroom' => ($row['type'] == 'chatmsg' ? 1 : 0)); $to_delete[] = $row['id']; } } else if($row['type'] == 'event') { $output['events'][$j++] = array('event' => $row['message'], 'sender' => $row['sender'], 'recipient' => $row['recipient']); $event = explode(',', $row['message']); if($event[0] == 'status') $output['events'][$j-1]['group'] = $reverse_list[$row['sender']]; $to_delete[] = $row['id']; } else if($row['type'] == 'server') { switch($row['message']) { case 'kick': $this->logout(); print 'not_logged_in'; break; } $to_delete[] = $row['id']; } } if(count($to_delete) > 0) $delete_new = mysql_query('DELETE FROM ' . SQL_PREFIX . 'messages WHERE id IN(' . implode(',', $to_delete) . ')'); return $this->json->encode($output); } /** * Sends a message to another user. * * @return String 'sent' if successful, error string otherwise * @author Joshua Gross **/ function send($to, $message, $font, $font_size, $font_color, $bold, $italic, $underline, $is_chat) { $to = mysql_real_escape_string($to); if(!$this->checkInfo($this->username, $this->password)) { $set_status = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=0, last_ping=\'' . time() . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\''); return 'not_logged_in'; } $is_online = $this->isOnline($to); if($is_online > 0 || $is_chat == 'true') { if($is_online == 100) { $check_friendship = mysql_query('SELECT is_online FROM ' . SQL_PREFIX . 'users WHERE username IN(SELECT user FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . strtolower($to) . '\' AND buddy=\'' . mysql_real_escape_string($this->username) . '\')'); if(mysql_num_rows($check_friendship) == 0) return 'not_online'; } $check_blocked = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . strtolower($to) . '\' AND buddy=\'' . mysql_real_escape_string($this->username) . '\''); if(mysql_num_rows($check_blocked) > 0) return 'not_online'; $check_blocked = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'blocklists WHERE buddy=\'' . strtolower($to) . '\' AND user=\'' . mysql_real_escape_string($this->username) . '\''); if(mysql_num_rows($check_blocked) > 0) return 'not_online'; if(strlen(trim($message)) > 0 && strlen($message) <= 1500) { $message = ('') . ($bold == 'true' ? '' : '') . ($italic == 'true' ? '' : '') . ($underline == 'true' ? '' : '') . $message . ($bold == 'true' ? '' : '') . ($italic == 'true' ? '' : '') . ($underline == 'true' ? '' : '') . (''); if($is_chat == 'true') { $where_to_send = $this->getChatlist($to); $to_insert = ''; foreach($where_to_send as $username) if($username != $this->username) $to_insert .= "('" . mysql_real_escape_string($message) . "', 'chatmsg', '" . $to . '.' . mysql_real_escape_string($this->username) . "', '" . strtolower($username) . "', " . time() . "),"; $to_insert = substr($to_insert, 0, strlen($to_insert) - 1); } else { $to_insert = "('" . mysql_real_escape_string($message) . "', 'msg', '" . mysql_real_escape_string($this->username) . "', '" . strtolower($to) . "', " . time() . ")"; } $query = mysql_query('INSERT INTO ' . SQL_PREFIX . 'messages (message, type, sender, recipient, stamp) VALUES ' . $to_insert); } else { if(strlen($message) > 1500) return 'too_long'; } return 'sent'; } else { return 'not_online'; } } /** * Adds the buddy to the user's buddylist, if possible. * * @return String 'added' if successful, error string otherwise * @author Joshua Gross **/ function addBuddy($username, $group) { if(!$this->checkInfo($this->username, $this->password)) return 'not_added'; $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND buddy=\'' . mysql_real_escape_string($username) . '\' LIMIT 1'); if(mysql_num_rows($query) == 0) { $add_buddy = mysql_query('INSERT INTO ' . SQL_PREFIX . 'buddylists (user, buddy, `group`) VALUES(\'' . mysql_real_escape_string($this->username) . '\', \'' . mysql_real_escape_string($username) . '\', \'' . mysql_real_escape_string($group) . '\')'); return 'added'; } else { return 'already_on_buddylist'; } } /** * Removes the buddy from the user's buddylist, if possible. * * @return String 'removed' if successful, error string otherwise * @author Joshua Gross **/ function removeBuddy($username) { if(!$this->checkInfo($this->username, $this->password)) return 'not_removed'; $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND buddy=\'' . mysql_real_escape_string($username) . '\' LIMIT 1'); if(mysql_num_rows($query) > 0) { $remove_buddy = mysql_query('DELETE FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND buddy=\'' . mysql_real_escape_string($username) . '\''); return 'removed'; } else { return 'no_user_on_buddylist'; } } /** * Blocks the user from being able to contact the user if blocked. Unblocks the user if blocked. * * @return String 'blocked' if not blocked, 'unblocked' if blocked, 'not_blocked' on error * @author Joshua Gross **/ function blockBuddy($username, $status) { if(!$this->checkInfo($this->username, $this->password)) return 'not_blocked'; $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND buddy=\'' . mysql_real_escape_string($username) . '\' LIMIT 1'); if(mysql_num_rows($query) == 0) { $block_buddy = mysql_query('INSERT INTO ' . SQL_PREFIX . 'blocklists (user, buddy) VALUES(\'' . mysql_real_escape_string($this->username) . '\', \'' . mysql_real_escape_string($username) . '\')'); $this->userEvent($this->username, array('block'=>array(mysql_real_escape_string($username))), 'status', array('status'=>0)); return 'blocked'; } else { $unblock_buddy = mysql_query('DELETE FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND buddy=\'' . mysql_real_escape_string($username) . '\' LIMIT 1'); $this->userEvent($this->username, array('block'=>array(mysql_real_escape_string($username))), 'status', array('status'=>mysql_real_escape_string($status))); return 'unblocked'; } } /** * Removes the group (and all buddies of group) from a user's buddylist. * * @return String 'removed' if successful, error string otherwise * @author Joshua Gross **/ function removeGroup($group) { if(!$this->checkInfo($this->username, $this->password)) return 'not_removed'; $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND `group`=\'' . mysql_real_escape_string($group) . '\' LIMIT 1'); if(mysql_num_rows($query) > 0) { $remove_buddy = mysql_query('DELETE FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND `group`=\'' . mysql_real_escape_string($group) . '\''); return 'removed'; } else { return 'no_group_on_buddylist'; } } /** * Registers a user. * * @return String 'registered' if successful, error string otherwise * @author Joshua Gross **/ function register($username, $password, $email) { $username = strtolower($username); if(preg_match('/^[a-z0-9_\\d]+$/', $username) !== false && strlen($username) >= 3 && strlen($username) <= 16) { if(preg_match('/^([a-zA-Z0-9_\\.\\-])+\\@(([a-zA-Z0-9\\-])+\\.)+([a-zA-Z0-9]{2,4})+$/', $email) !== false) { if(strlen($password) >= 6 && strlen($password) <= 20) { if(mysql_num_rows(mysql_query('SELECT email FROM ' . SQL_PREFIX . 'users WHERE email=\'' . mysql_real_escape_string($email) . '\'')) == 0) { $query = mysql_query('SELECT username FROM ' . SQL_PREFIX . 'users WHERE username=\'' . mysql_real_escape_string($username) . '\''); if(mysql_num_rows($query) == 0) { $query = mysql_query('INSERT INTO ' . SQL_PREFIX . 'users (username, password, email) VALUES (\'' . mysql_real_escape_string($username) . '\', \'' . md5($password) . '\', \'' . mysql_real_escape_string($email) . '\')'); print 'user_registered'; } else { print 'username_taken'; } } else { print 'email_already_used'; } } else { print 'password_bad_length'; } } else { print 'invalid_email'; } } else { print 'username_bad'; } } /** * Check if a certain user exists (only works when authenticated). * * @return String 'exists' if successful, error string otherwise * @author Joshua Gross **/ function isUser($username) { if(!$this->checkInfo($this->username, $this->password)) return 'not_logged_in'; $query = mysql_query('SELECT is_online FROM ' . SQL_PREFIX . 'users WHERE username=\'' . mysql_real_escape_string($username) . '\''); if(mysql_num_rows($query) > 0) { $userinfo = mysql_fetch_assoc($query); if($userinfo['is_online'] == 100) { $check_friendship = mysql_query('SELECT is_online FROM ' . SQL_PREFIX . 'users WHERE username IN(SELECT user FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . mysql_real_escape_string($username) . '\' AND buddy=\'' . mysql_real_escape_string($this->username) . '\')'); if(mysql_num_rows($check_friendship) == 0) return '0'; else return $userinfo['is_online']; } else { return $userinfo['is_online']; } } else { return 'not_exists'; } } /** * Resets a user's password based on their email address. * * @return String 'reset' if successful, 'no_email_on_record' otherwise * @author Joshua Gross **/ function reset($email) { $email = urldecode($email); $query = mysql_query('SELECT email FROM ' . SQL_PREFIX . 'users WHERE email=\'' . mysql_real_escape_string($email) . '\''); if(mysql_num_rows($query) > 0) { $new_pass = $this->generatePassword(); $query = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET password=\'' . md5($new_pass) . '\' WHERE email=\'' . mysql_real_escape_string($email) . '\''); mail($email, 'Your Reset Password', "You requested that your password be reset, your new password is below.\n\nNew Password: $new_pass", 'From: Reset Password '); return 'pw_reset'; } else { return 'no_email_on_record'; } } /** * Changes the user's password. * * @return String 'changed' if successful, error string otherwise * @author Joshua Gross **/ function passwordChange($password, $new_password) { if(!$this->checkInfo($this->username, $password)) return 'invalid_pw'; if(strlen($new_password) >= 6 && strlen($new_password) <= 20) { $query = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET password=\'' . md5($new_password) . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\''); return 'pw_changed'; } else { return 'password_bad_length'; } } /** * Adds a user to a chatroom. * * @return String 'joined' if successful, error string otherwise * @author Joshua Gross **/ function joinRoom($room) { $room = mysql_real_escape_string(strtolower($room)); $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'chats WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND room=\'' . $room . '\''); if(mysql_num_rows($query) > 0) { return 'already_joined'; } else { if(preg_match('/^[^a-z0-9_\d]+$/', $room) == false) { $query = mysql_query('INSERT INTO ' . SQL_PREFIX . 'chats (room, user) VALUES (\'' . $room . '\', \'' . mysql_real_escape_string($this->username) . '\')'); $output['users'] = $this->getChatlist($room); $notify_buddies = $this->userEvent($this->username, $output, 'chat', array('action'=>'join', 'room'=>$room)); return $this->json->encode($output); } else { return 'invalid_chars'; } } } /** * Removes a user from a chatroom. * * @return String 'left' if successful, 'not_left' otherwise * @author Joshua Gross **/ function leaveRoom($room) { $room = mysql_real_escape_string(strtolower($room)); $query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'chats WHERE user=\'' . mysql_real_escape_string($this->username) . '\' AND room=\'' . $room . '\'') ; if(mysql_num_rows($query) > 0) { $row = mysql_fetch_assoc($query); $query = mysql_query('DELETE FROM ' . SQL_PREFIX . 'chats WHERE id=\'' . $row['id'] . '\''); $output['users'] = $this->getChatlist($room); $notify_buddies = $this->userEvent($this->username, $output, 'chat', array('action'=>'left', 'room'=>$room)); return 'left'; } else { return 'not_left'; } } /** * Retrieves a list of room names and returns them to the user as a JSON object. * * @return JSON object * @author Joshua Gross **/ function roomList() { $rooms_query = mysql_query('SELECT room FROM ' . SQL_PREFIX . 'chats GROUP BY room ORDER BY room ASC'); $rooms = array(); while($row = mysql_fetch_assoc($rooms_query)) $rooms[] = $row['room']; return $this->json->encode($rooms); } /** * Proccesses the upload of the new Buddy Icon for the user. * * @return JSON object * @author Benjamin Hutchins **/ function changeIcon() { global $maxBuddyIconSize; if (!isset($maxBuddyIconSize) || $maxBuddyIconSize == 0) { return "unkown"; } /* @ini_set('file_uploads', 'On'); @ini_set('upload_max_filesize', $maxBuddyIconSize.'M'); @ini_set('post_max_size', $maxBuddyIconSize.'M'); */ $allowed_types = array("image/x-ms-bmp", "image/x-icon", "image/jpeg", "image/x-png", "image/gif", "image/png", "image/tiff"); $allowed_files = array('jpeg', 'jpg', 'jpe', 'bmp', 'png', 'gif', 'ico', "tif", "tiff"); if (empty($_FILES['icon']['tmp_name'])) { return "nofile"; } if ($_FILES['icon']['size'] > $maxBuddyIconSize*1024) { return "size"; } if (!in_array($_FILES['icon']['type'], $allowed_types)) { return "bad_type"; } $filename = $_FILES['icon']['name']; $extension = strtolower(end(explode(".", $filename))); if (!in_array($extension, $allowed_files)) { return "bad_extension"; } if (move_uploaded_file($_FILES['icon']['tmp_name'], "./buddyicons/".$this->username.".".$extension)) { if (mysql_query('UPDATE ' . SQL_PREFIX . 'users SET buddyicon=\'' . mysql_real_escape_string($extension) . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\'')) { return "success"; } else { return "unkown"; } } else { return "unkown"; } } /** * Updates a user's profile. * * @return success value * @author Benjamin Hutchins **/ function changeProfile($profile) { if (mysql_query('UPDATE ' . SQL_PREFIX . 'users SET profile=\'' . mysql_real_escape_string(strip_tags($profile)) . '\' WHERE username=\'' . mysql_real_escape_string($this->username) . '\'')) { return 'success'; } else { return 'failed'; } } /** * Returns a user's profile. * * @return HTML content * @author Benjamin Hutchins **/ function getProfile($username) { $query = mysql_query('SELECT profile FROM ' . SQL_PREFIX . 'users WHERE username=\'' . mysql_real_escape_string($username) . '\''); $result = mysql_fetch_assoc($query); return $result['profile']; } /* Begin private functions */ /** * Return a user's status. * * @return Integer representing user's status * @author Joshua Gross **/ function isOnline($username) { $query = mysql_query('SELECT is_online FROM ' . SQL_PREFIX . 'users WHERE username=\'' . mysql_real_escape_string($username) . '\''); $result = mysql_fetch_assoc($query); return $result['is_online']; } /** * Check to see if the supplied user information is valid, and if so return specific information. * * @return false if information is invalid, array of data otherwise * @author Joshua Gross **/ function checkInfo($username, $password, $return=array()) { if(count($return) > 0) $columns = implode(',', $return); else $columns = 'id'; $username = mysql_real_escape_string($username); $password = mysql_real_escape_string($password); $query = mysql_query('SELECT ' . $columns . ' FROM ' . SQL_PREFIX . 'users WHERE username=\'' . $username . '\' AND password=\'' . $password . '\' LIMIT 1'); if(mysql_num_rows($query) > 0) return mysql_fetch_assoc($query); else return false; } /** * Retrieves a list of users in a specific chatroom. * * @return Array of users * @author Joshua Gross **/ function getChatlist($room) { $query = mysql_query('SELECT DISTINCT user FROM ' . SQL_PREFIX . 'chats WHERE room=\'' . mysql_real_escape_string(strtolower($room)) . '\''); while ($row = mysql_fetch_assoc($query)) $userlist[]=$row['user']; return $userlist; } /** * Retrieves a list of all of the user's buddies. * * @return Array of buddies by group * @author Joshua Gross * @update Benjamin Hutchins - returns none-blocked buddies if $inc_blocked = false **/ function getBuddylist($username, $inc_blocked=true) { $username = mysql_real_escape_string($username); $query = mysql_query('SELECT ' . SQL_PREFIX . 'buddylists.buddy AS buddy, `group` FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . $username . '\' AND ' . SQL_PREFIX . 'buddylists.buddy NOT IN(SELECT user FROM ' . SQL_PREFIX . 'blocklists WHERE buddy=\'' . $username . '\')' . ($inc_blocked ? "" : ' AND ' . SQL_PREFIX . 'buddylists.buddy NOT IN(SELECT buddy FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . $username . '\')')); $buddylist = array(); while($row = mysql_fetch_assoc($query)) $buddylist[$row['group']][] = $row['buddy']; return $buddylist; } /** * Retrieves a list of the user's buddies that are online (with any status). * * @return Array of buddies by group with status information * @author Joshua Gross * @update Benjamin Hutchins - only returns buddies that did not block user. **/ function getBuddylistOnline($username) { $username = mysql_real_escape_string($username); //$query = mysql_query('SELECT ' . SQL_PREFIX . 'buddylists.buddy, `group`, buddyicon, is_online FROM ' . SQL_PREFIX . 'buddylists LEFT JOIN ' . SQL_PREFIX . 'users ON ' . SQL_PREFIX . 'buddylists.buddy = ' . SQL_PREFIX . 'users.username WHERE ' . SQL_PREFIX . 'buddylists.user=\'' . $username . '\' AND ' . SQL_PREFIX . 'buddylists.buddy NOT IN(SELECT user FROM ' . SQL_PREFIX . 'blocklists WHERE buddy=\'' . $username . '\')'); $query = mysql_query('SELECT ' . SQL_PREFIX . 'buddylists.buddy, `group`, buddyicon, is_online, ' . SQL_PREFIX . 'buddylists.buddy IN(SELECT user FROM ' . SQL_PREFIX . 'blocklists WHERE buddy=\'' . $username . '\') AS blocked FROM ' . SQL_PREFIX . 'buddylists LEFT JOIN ' . SQL_PREFIX . 'users ON ' . SQL_PREFIX . 'buddylists.buddy = ' . SQL_PREFIX . 'users.username WHERE ' . SQL_PREFIX . 'buddylists.user=\'' . $username . '\''); $buddylist = array(); while($row = mysql_fetch_assoc($query)) { $buddylist[$row['group']][] = array('username'=>$row['buddy'], 'icon'=>$row['buddyicon'], 'is_online'=>($row['blocked'] ? 0 : $row['is_online'])); } return $buddylist; } /** * Retrieves the list of blocked buddies from the database. * * @return Array of buddies * @author Joshua Gross **/ function getBlocklist($username) { $username = mysql_real_escape_string($username); $query = mysql_query('SELECT buddy FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . $username . '\''); $blocklist = array(); while($row = mysql_fetch_assoc($query)) $blocklist[] = $row['buddy']; return $blocklist; } /** * Event handler for status or chat status updates. * * @return void * @author Joshua Gross **/ function userEvent($username, $buddylist, $event, $args) { $username = mysql_real_escape_string($username); switch($event) { case 'chat': $users = $buddylist['users']; $users_str = @implode("','", $users); $query = mysql_query('SELECT username, is_online FROM ' . SQL_PREFIX . 'users WHERE username IN(\'' . $users_str . '\') AND is_online > 0 ORDER BY username ASC'); while ($row = mysql_fetch_assoc($query)) if(strlen($to_insert[$row['username']]) == 0) $to_insert[$row['username']] = mysql_real_escape_string($event . ',' . $args['action'] . ',' . $args['room']); break; case 'status': if($args['status'] == 100) { $args['status'] = 0; // we're going to do this backwards // instead of broadcasting a positive message to our buddies // we will send a negative (offline) message to all our non-buddies // who have us on their buddylist $query_string = 'username IN(SELECT user FROM ' . SQL_PREFIX . 'buddylists WHERE buddy=\'' . $username . '\') AND ' . 'username NOT IN(\''; } else { $query_string = '(username IN(SELECT user FROM ' . SQL_PREFIX . 'buddylists WHERE buddy=\'' . $username . '\') AND username NOT IN(SELECT buddy FROM ' . SQL_PREFIX . 'blocklists WHERE user=\'' . $username . '\')) OR ' . 'username IN(\''; } if(count($buddylist) == 0) $buddylist[''] = array(''); foreach($buddylist as $group => $users) { $users_str = implode("','", $users); $query = mysql_query('SELECT username, is_online FROM ' . SQL_PREFIX . 'users WHERE (' . $query_string . $users_str . '\')) GROUP BY username'); while($row = mysql_fetch_assoc($query)) { if(in_array($row['username'], $users) !== false) { if($row['is_online'] == 100) { $friend_query = mysql_query('SELECT id FROM ' . SQL_PREFIX . 'buddylists WHERE user=\'' . $row['username'] . '\' AND buddy=\'' . $username . '\' LIMIT 1'); if(mysql_num_rows($friend_query) == 0) $row['is_online'] = 0; } } if($row['is_online'] != 0 && strlen($to_insert[$row['username']]) == 0) $to_insert[$row['username']] = mysql_real_escape_string($event . ',' . $args['status']); } } break; } if(count($to_insert) > 0) { $time_cur = time(); foreach($to_insert as $user => $evt) $insert_str .= "('" . $evt . "', 'event', '" . $username . "', '" . mysql_real_escape_string($user) . "', " . $time_cur . "),"; $insert_str = substr($insert_str, 0, strlen($insert_str) - 1); $query = @mysql_query('INSERT INTO ' . SQL_PREFIX . 'messages (message, type, sender, recipient, stamp) VALUES ' . $insert_str); } } /** * Generates a random string of the specified length (default = 10). * * @return String * @author Joshua Gross **/ function generatePassword($length=10) { $randstr=''; srand((double)microtime()*1000000); $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; while(strlen($randstr)<$length) { $randstr.=substr($chars,(rand()%(strlen($chars))),1); } return $randstr; } /** * Garbage collector. Resets users who have been inactive for more than 5 minutes. * * @return void * @author Joshua Gross **/ function gc() { // cleanup logged-in users in database? [30% chance] if(rand(1, 100) <= 30) { // yes, cleanup! // $expire_time = time() - 30; // idle for more than 30 seconds? $cleanup_event = mysql_query('SELECT username FROM ' . SQL_PREFIX . 'users WHERE last_ping < ' . $expire_time . ' AND is_online > 0'); if(mysql_num_rows($cleanup_event) > 0) { while($row = mysql_fetch_assoc($cleanup_event)) $notify_buddies = $this->userEvent($row['username'], $this->getBuddylist($row['username']), 'status', array('status'=>0)); } $cleanup_event2 = mysql_query('SELECT user, room FROM ' . SQL_PREFIX . 'chats WHERE user IN(SELECT username FROM ' . SQL_PREFIX . 'users WHERE last_ping < ' . $expire_time . ' AND is_online > 0)'); if(mysql_num_rows($cleanup_event2) > 0) { while($row = mysql_fetch_assoc($cleanup_event2)) { $room = mysql_query('SELECT user FROM ' . SQL_PREFIX . 'chats WHERE room=\'' . $row['room'] . '\''); if(mysql_num_rows($room) > 0) { while($row2 = mysql_fetch_assoc($room)) $chatusers['users'][] = $row2['user']; } $notify_chatusers = $this->userEvent($row['user'], $chatusers, 'chat', array('action'=>'left', 'room'=>$row['room'])); } } $cleanup_chats = mysql_query('DELETE FROM ' . SQL_PREFIX . 'chats WHERE user IN(SELECT username FROM ' . SQL_PREFIX . 'users WHERE last_ping < ' . $expire_time . ' AND is_online > 0)'); $cleanup_msgs = mysql_query('DELETE FROM ' . SQL_PREFIX . 'messages WHERE stamp < ' . (time() - 300)); $cleanup = mysql_query('UPDATE ' . SQL_PREFIX . 'users SET is_online=0 WHERE last_ping < ' . $expire_time . ' AND is_online > 0'); } } } $ajax_im = new Ajax_IM($_POST['call']); mysql_close(); ?>