From 4224e0324c3ccd0a42bf40d80a993c55895385bd Mon Sep 17 00:00:00 2001 From: flashwave Date: Sun, 6 Feb 2022 17:26:14 +0100 Subject: [PATCH] First wave of Adjustments --- ajaxchat.php | 25 + config/config-db.php | 5 + {public/lib => config}/config.php | 28 +- lang/en.php | 120 + {public/lib/lang => lang}/title.php | 0 public/index.php | 8 +- public/lib/.htaccess | 4 - public/lib/class/AJAXChat.php | 3491 ----------------- public/lib/class/AJAXChatDataBase.php | 81 - public/lib/class/AJAXChatEncoding.php | 138 - public/lib/class/AJAXChatHTTPHeader.php | 56 - public/lib/class/AJAXChatLanguage.php | 102 - public/lib/class/AJAXChatMySQLDataBase.php | 92 - public/lib/class/AJAXChatMySQLQuery.php | 89 - public/lib/class/AJAXChatMySQLiDataBase.php | 91 - public/lib/class/AJAXChatMySQLiQuery.php | 81 - public/lib/class/AJAXChatString.php | 37 - public/lib/class/AJAXChatTemplate.php | 359 -- public/lib/class/CustomAJAXChatShoutBox.php | 25 - public/lib/class/satori.php | 239 -- public/lib/classes.php | 26 - public/lib/custom.php | 11 - public/lib/lang/en.php | 120 - src/AJAXChat.php | 3491 +++++++++++++++++ src/AJAXChatDataBase.php | 80 + src/AJAXChatEncoding.php | 137 + .../lib/class => src}/AJAXChatFileSystem.php | 15 +- src/AJAXChatHTTPHeader.php | 55 + src/AJAXChatLanguage.php | 101 + src/AJAXChatMySQLiDataBase.php | 90 + src/AJAXChatMySQLiQuery.php | 80 + src/AJAXChatString.php | 36 + src/AJAXChatTemplate.php | 358 ++ {public/lib/class => src}/CustomAJAXChat.php | 252 +- .../class => src}/CustomAJAXChatInterface.php | 13 +- src/CustomAJAXChatShoutBox.php | 24 + src/satori.php | 239 ++ {public/lib/template => template}/banned.html | 0 .../template => template}/legacyLogin.html | 0 .../lib/template => template}/loggedIn.html | 0 .../lib/template => template}/loggedOut.html | 0 .../template => template}/loggedOutFA.html | 0 .../lib/template => template}/loggedOut~.html | 0 {public/lib/template => template}/logs.html | 0 {public/lib/template => template}/mobile.html | 0 .../lib/template => template}/shoutbox.html | 0 .../lib/template => template}/~loggedOut.html | 0 47 files changed, 4995 insertions(+), 5204 deletions(-) create mode 100644 ajaxchat.php create mode 100644 config/config-db.php rename {public/lib => config}/config.php (93%) create mode 100644 lang/en.php rename {public/lib/lang => lang}/title.php (100%) delete mode 100644 public/lib/.htaccess delete mode 100644 public/lib/class/AJAXChat.php delete mode 100644 public/lib/class/AJAXChatDataBase.php delete mode 100644 public/lib/class/AJAXChatEncoding.php delete mode 100644 public/lib/class/AJAXChatHTTPHeader.php delete mode 100644 public/lib/class/AJAXChatLanguage.php delete mode 100644 public/lib/class/AJAXChatMySQLDataBase.php delete mode 100644 public/lib/class/AJAXChatMySQLQuery.php delete mode 100644 public/lib/class/AJAXChatMySQLiDataBase.php delete mode 100644 public/lib/class/AJAXChatMySQLiQuery.php delete mode 100644 public/lib/class/AJAXChatString.php delete mode 100644 public/lib/class/AJAXChatTemplate.php delete mode 100644 public/lib/class/CustomAJAXChatShoutBox.php delete mode 100644 public/lib/class/satori.php delete mode 100644 public/lib/classes.php delete mode 100644 public/lib/custom.php delete mode 100644 public/lib/lang/en.php create mode 100644 src/AJAXChat.php create mode 100644 src/AJAXChatDataBase.php create mode 100644 src/AJAXChatEncoding.php rename {public/lib/class => src}/AJAXChatFileSystem.php (53%) create mode 100644 src/AJAXChatHTTPHeader.php create mode 100644 src/AJAXChatLanguage.php create mode 100644 src/AJAXChatMySQLiDataBase.php create mode 100644 src/AJAXChatMySQLiQuery.php create mode 100644 src/AJAXChatString.php create mode 100644 src/AJAXChatTemplate.php rename {public/lib/class => src}/CustomAJAXChat.php (52%) rename {public/lib/class => src}/CustomAJAXChatInterface.php (54%) create mode 100644 src/CustomAJAXChatShoutBox.php create mode 100644 src/satori.php rename {public/lib/template => template}/banned.html (100%) rename {public/lib/template => template}/legacyLogin.html (100%) rename {public/lib/template => template}/loggedIn.html (100%) rename {public/lib/template => template}/loggedOut.html (100%) rename {public/lib/template => template}/loggedOutFA.html (100%) rename {public/lib/template => template}/loggedOut~.html (100%) rename {public/lib/template => template}/logs.html (100%) rename {public/lib/template => template}/mobile.html (100%) rename {public/lib/template => template}/shoutbox.html (100%) rename {public/lib/template => template}/~loggedOut.html (100%) diff --git a/ajaxchat.php b/ajaxchat.php new file mode 100644 index 0000000..48a76a7 --- /dev/null +++ b/ajaxchat.php @@ -0,0 +1,25 @@ +initConfig(); - - // Initialize the DataBase connection: - $this->initDataBaseConnection(); - - // Initialize request variables: - $this->initRequestVars(); - - // Initialize the chat session: - $this->initSession(); - - // Handle the browser request and send the response content: - $this->handleRequest(); - } - - function initConfig() { - $config = null; - if(!include(AJAX_CHAT_PATH.'lib/config.php')) { - print('Error: Configuration file could not be loaded.'); - exit; - } - $this->_config = &$config; - - // Initialize custom configuration settings: - $this->initCustomConfig(); - } - - function initRequestVars() { - $this->_requestVars = array(); - $this->_requestVars['ajax'] = isset($_REQUEST['ajax']) ? true : false; - $this->_requestVars['userID'] = isset($_REQUEST['userID']) ? (int)$_REQUEST['userID'] : null; - $this->_requestVars['userName'] = isset($_REQUEST['userName']) ? $_REQUEST['userName'] : null; - $this->_requestVars['channelID'] = isset($_REQUEST['channelID']) ? (int)$_REQUEST['channelID'] : null; - $this->_requestVars['channelName'] = isset($_REQUEST['channelName']) ? $_REQUEST['channelName'] : null; - $this->_requestVars['text'] = isset($_POST['text']) ? $_POST['text'] : null; - $this->_requestVars['lastID'] = isset($_REQUEST['lastID']) ? (int)$_REQUEST['lastID'] : 0; - $this->_requestVars['login'] = isset($_REQUEST['login']) ? true : false; - $this->_requestVars['logout'] = isset($_POST['logout']) ? true : false; - $this->_requestVars['password'] = isset($_REQUEST['password']) ? $_REQUEST['password'] : null; - $this->_requestVars['view'] = isset($_REQUEST['view']) ? $_REQUEST['view'] : null; - $this->_requestVars['year'] = isset($_REQUEST['year']) ? (int)$_REQUEST['year'] : null; - $this->_requestVars['month'] = isset($_REQUEST['month']) ? (int)$_REQUEST['month'] : null; - $this->_requestVars['day'] = isset($_REQUEST['day']) ? (int)$_REQUEST['day'] : null; - $this->_requestVars['hour'] = isset($_REQUEST['hour']) ? (int)$_REQUEST['hour'] : null; - $this->_requestVars['search'] = isset($_REQUEST['search']) ? $_REQUEST['search'] : null; - $this->_requestVars['shoutbox'] = isset($_REQUEST['shoutbox']) ? true : false; - $this->_requestVars['getInfos'] = isset($_REQUEST['getInfos']) ? $_REQUEST['getInfos'] : null; - $this->_requestVars['lang'] = isset($_REQUEST['lang']) ? $_REQUEST['lang'] : null; - $this->_requestVars['delete'] = isset($_REQUEST['delete']) ? (int)$_REQUEST['delete'] : null; - - // Initialize custom request variables: - $this->initCustomRequestVars(); - - // Remove slashes which have been added to user input strings if magic_quotes_gpc is On: - /*if(get_magic_quotes_gpc()) { - // It is safe to remove the slashes as we escape user data ourself - array_walk( - $this->_requestVars, - create_function( - '&$value, $key', - 'if(is_string($value)) $value = stripslashes($value);' - ) - ); - }*/ - } - - function initDataBaseConnection() { - // Create a new database object: - $this->db = new AJAXChatDataBase( - $this->_config['dbConnection'] - ); - // Use a new database connection if no existing is given: - if(!$this->_config['dbConnection']['link']) { - // Connect to the database server: - $this->db->connect($this->_config['dbConnection']); - if($this->db->error()) { - echo $this->db->getError(); - die(); - } - // Select the database: - $this->db->select($this->_config['dbConnection']['name']); - if($this->db->error()) { - echo $this->db->getError(); - die(); - } - } - // Unset the dbConnection array for safety purposes: - unset($this->_config['dbConnection']); - } - - function getDataBaseTable($table) { - return ($this->db->getName() ? $this->db->getName().'.'.$this->getConfig('dbTableNames',$table) : $this->getConfig('dbTableNames',$table)); - } - - function initSession() { - // Start the PHP session (if not already started): - $this->startSession(); - - if($this->isLoggedIn()) { - // Logout if we receive a logout request, the chat has been closed or the userID could not be revalidated: - if($this->getRequestVar('logout') || !$this->isChatOpen() || !$this->revalidateUserID()) { - $this->logout(); - return; - } - // Logout if the Session IP is not the same when logged in and ipCheck is enabled: - if($this->getConfig('ipCheck') && ($this->getSessionIP() === null || $this->getSessionIP() != $_SERVER['REMOTE_ADDR'])) { - $this->logout('IP'); - return; - } - } else if( - // Login if auto-login enabled or a login, userName or shoutbox parameter is given: - $this->getConfig('forceAutoLogin') || - $this->getRequestVar('login') || - $this->getRequestVar('userName') || - $this->getRequestVar('shoutbox') - ) { - $this->login(); - } - - // Initialize the view: - $this->initView(); - - if($this->getView() == 'chat') { - $this->initChatViewSession(); - } else if($this->getView() == 'logs') { - $this->initLogsViewSession(); - } - - if(!$this->getRequestVar('ajax') && !headers_sent()) { - // Set style cookie: - $this->setStyle(); - // Set langCode cookie: - $this->setLangCodeCookie(); - } - - $this->initCustomSession(); - } - - function initLogsViewSession() { - if($this->getConfig('socketServerEnabled')) { - if(!$this->getSessionVar('logsViewSocketAuthenticated')) { - $this->updateLogsViewSocketAuthentication(); - $this->setSessionVar('logsViewSocketAuthenticated', true); - } - } - } - - function updateLogsViewSocketAuthentication() { - if($this->getUserRole() != AJAX_CHAT_ADMIN) { - $channels = array(); - foreach($this->getChannels() as $channel) { - if($this->getConfig('logsUserAccessChannelList') && !in_array($channel, $this->getConfig('logsUserAccessChannelList'))) { - continue; - } - array_push($channels, $channel); - } - array_push($channels, $this->getPrivateMessageID()); - array_push($channels, $this->getPrivateChannelID()); - } else { - // The channelID "ALL" authenticates for all channels: - $channels = array('ALL'); - } - $this->updateSocketAuthentication( - $this->getUserID(), - $this->getSocketRegistrationID(), - $channels - ); - } - - function initChatViewSession() { - // If channel is not null we are logged in to the chat view: - if($this->getChannel() !== null) { - // Check if the current user has been logged out due to inactivity: - if(!$this->isUserOnline()) { - $this->logout(); - return; - } - if($this->getRequestVar('ajax')) { - $this->initChannel(); - $this->updateOnlineStatus(); - $this->checkAndRemoveInactive(); - } - } else { - if($this->getRequestVar('ajax')) { - // Set channel, insert login messages and add to online list on first ajax request in chat view: - $this->chatViewLogin(); - } - } - } - - function isChatOpen() { - if($this->getUserRole() == AJAX_CHAT_ADMIN) - return true; - if($this->getConfig('chatClosed')) - return false; - $time = time(); - if($this->getConfig('timeZoneOffset') !== null) { - // Subtract the server timezone offset and add the config timezone offset: - $time -= date('Z', $time); - $time += $this->getConfig('timeZoneOffset'); - } - // Check the opening hours: - if($this->getConfig('openingHour') < $this->getConfig('closingHour')) - { - if(($this->getConfig('openingHour') > date('G', $time)) || ($this->getConfig('closingHour') <= date('G', $time))) - return false; - } - else - { - if(($this->getConfig('openingHour') > date('G', $time)) && ($this->getConfig('closingHour') <= date('G', $time))) - return false; - } - // Check the opening weekdays: - if(!in_array(date('w', $time), $this->getConfig('openingWeekDays'))) - return false; - return true; - } - - function handleRequest() { - if($this->getRequestVar('ajax')) { - if($this->isLoggedIn()) { - // Parse info requests (for current userName, etc.): - $this->parseInfoRequests(); - - // Parse command requests (e.g. message deletion): - $this->parseCommandRequests(); - - // Parse message requests: - $this->initMessageHandling(); - } - // Send chat messages and online user list in XML format: - $this->sendXMLMessages(); - } else { - // Display XHTML content for non-ajax requests: - $this->sendXHTMLContent(); - } - } - - function parseCommandRequests() { - if($this->getRequestVar('delete') !== null) { - $this->deleteMessage($this->getRequestVar('delete')); - } - } - - function parseInfoRequests() { - if($this->getRequestVar('getInfos')) { - $infoRequests = explode(',', $this->getRequestVar('getInfos')); - foreach($infoRequests as $infoRequest) { - $this->parseInfoRequest($infoRequest); - } - } - } - - function parseInfoRequest($infoRequest) { - switch($infoRequest) { - case 'userID': - $this->addInfoMessage($this->getUserID(), 'userID'); - break; - case 'userName': - $this->addInfoMessage($this->getUserName(), 'userName'); - break; - case 'userRole': - $this->addInfoMessage($this->getUserRole(), 'userRole'); - break; - case 'channelID': - $this->addInfoMessage($this->getChannel(), 'channelID'); - break; - case 'channelName': - $this->addInfoMessage($this->getChannelName(), 'channelName'); - break; - case 'socketRegistrationID': - $this->addInfoMessage($this->getSocketRegistrationID(), 'socketRegistrationID'); - break; - default: - $this->parseCustomInfoRequest($infoRequest); - } - } - - function sendXHTMLContent() { - $httpHeader = new AJAXChatHTTPHeader($this->getConfig('contentEncoding'), $this->getConfig('contentType')); - - $template = new AJAXChatTemplate($this, $this->getTemplateFileName(), $httpHeader->getContentType()); - - // Send HTTP header: - $httpHeader->send(); - - // Send parsed template content: - echo $template->getParsedContent(); - } - - function getTemplateFileName() { - switch($this->getView()) { - case 'chat': - return AJAX_CHAT_PATH.'lib/template/loggedIn.html'; - case 'logs': - return AJAX_CHAT_PATH.'lib/template/logs.html'; - case 'mobile': - return AJAX_CHAT_PATH.'lib/template/mobile.html'; - case 'legacy': - return AJAX_CHAT_PATH.'lib/template/legacyLogin.html'; - case 'banned': - return AJAX_CHAT_PATH.'lib/template/banned.html'; - case 'legacy1': - return AJAX_CHAT_PATH.'lib/template/~loggedOut.html'; - case 'legacy2': - return AJAX_CHAT_PATH.'lib/template/loggedOut~.html'; - case 'legacy3': - return AJAX_CHAT_PATH.'lib/template/loggedOutFA.html'; - default: - return AJAX_CHAT_PATH.'lib/template/loggedOut.html'; - } - } - - function initView() { - $this->_view = null; - // "chat" is the default view: - $view = ($this->getRequestVar('view') === null) ? 'chat' : $this->getRequestVar('view'); - if($this->hasAccessTo($view)) { - $this->_view = $view; - } - } - - function getView() { - return $this->_view; - } - - function hasAccessTo($view) { - if(substr($view, 0, 6) === 'legacy') - return !$this->isLoggedIn(); - - switch($view) { - case 'legacy': - if($this->isLoggedIn()) { - return false; - } - return true; - case 'banned': - return true; - case 'chat': - case 'mobile': - case 'teaser': - if($this->isLoggedIn()) { - return true; - } - return false; - case 'logs': - if($this->isLoggedIn() && ($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == CMOD || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == PURPLE || $this->getUserRole() == DONATOR || - ($this->getConfig('logsUserAccess') && - ($this->getUserRole() == AJAX_CHAT_USER)) - )) { - return true; - } - return false; - default: - return false; - } - } - - function login() { - // Retrieve valid login user data (from request variables or session data): - $userData = $this->getValidLoginUserData(); - - if(!$userData) { - $this->addInfoMessage('errorInvalidUser'); - return false; - } - - // If the chat is closed, only the admin may login: - if(!$this->isChatOpen() && $userData['userRole'] != AJAX_CHAT_ADMIN) { - $this->addInfoMessage('errorChatClosed'); - return false; - } - - if(!$this->getConfig('allowGuestLogins') && $userData['userRole'] == AJAX_CHAT_GUEST) { - return false; - } - - // Check if userID or userName are already listed online: - if($this->isUserOnline($userData['userID']) || $this->isUserNameInUse($userData['userName'])) { - // Set the registered user inactive and remove the inactive users so the user can be logged in again: - $this->setInactive($userData['userID'], $userData['userName']); - $this->removeInactive(); - } - - // Check if user is banned: - if($userData['userRole'] != AJAX_CHAT_ADMIN && $this->isUserBanned($userData['userName'], $userData['userID'], $_SERVER['REMOTE_ADDR'])) { - $this->addInfoMessage('errorBanned'); - return false; - } - - // Check if the max number of users is logged in (not affecting moderators or admins): - if(!($userData['userRole'] == AJAX_CHAT_MODERATOR || $userData['userRole'] == PURPLE || $userData['userRole'] == AJAX_CHAT_ADMIN) && $this->isMaxUsersLoggedIn()) { - $this->addInfoMessage('errorMaxUsersLoggedIn'); - return false; - } - - // Use a new session id (if session has been started by the chat): - $this->regenerateSessionID(); - - // Log in: - $this->setUserID($userData['userID']); - $this->setUserName($userData['userName']); - $this->setLoginUserName($userData['userName']); - $this->setUserRole($userData['userRole']); - $this->setLoggedIn(true); - $this->setLoginTimeStamp(time()); - - // IP Security check variable: - $this->setSessionIP($_SERVER['REMOTE_ADDR']); - - // The client authenticates to the socket server using a socketRegistrationID: - if($this->getConfig('socketServerEnabled')) { - $this->setSocketRegistrationID( - md5(uniqid(rand(), true)) - ); - } - - // Add userID, userName and userRole to info messages: - $this->addInfoMessage($this->getUserID(), 'userID'); - $this->addInfoMessage($this->getUserName(), 'userName'); - $this->addInfoMessage($this->getUserRole(), 'userRole'); - - // Purge logs: - if($this->getConfig('logsPurgeLogs')) { - $this->purgeLogs(); - } - - // Report login to Satori: - /*$boatcom = @fsockopen('marie.railgun.sh', 9064, $errno, $errstr, 5); - if($boatcom) { - $message = sprintf('{sock}[i][url=https://flashii.net/profile.php?u=%d][b]%s[/b][/url] logged into [url=https://flash.moe/chat/]Flashii Chat Legacy[/url].[/i]', $userData['userID'], $userData['userName']); - $message = chr(0xF) . hash_hmac('sha256', $message, 'lol glad i caught this, that could\'ve been pretty funny if i forgot to remove this') . $message . chr(0xF); - fwrite($boatcom, $message); - fflush($boatcom); - fclose($boatcom); - }*/ - - return true; - } - - function chatViewLogin() { - $this->setChannel($this->getValidRequestChannelID()); - $this->addToOnlineList(); - - // Add channelID and channelName to info messages: - $this->addInfoMessage($this->getChannel(), 'channelID'); - $this->addInfoMessage($this->getChannelName(), 'channelName'); - - // Login message: - $text = '/login '.$this->getUserName(); - $this->insertChatBotMessage( - $this->getChannel(), - $text, - null, - 1 - ); - } - - function getValidRequestChannelID() { - $channelID = $this->getRequestVar('channelID'); - $channelName = $this->getRequestVar('channelName'); - // Check the given channelID, or get channelID from channelName: - if($channelID === null) { - if($channelName !== null) { - $channelID = $this->getChannelIDFromChannelName($channelName); - // channelName might need encoding conversion: - if($channelID === null) { - $channelID = $this->getChannelIDFromChannelName( - $this->trimChannelName($channelName, $this->getConfig('contentEncoding')) - ); - } - } - } - // Validate the resulting channelID: - if(!$this->validateChannel($channelID)) { - if($this->getChannel() !== null) { - return $this->getChannel(); - } - return $this->getConfig('defaultChannelID'); - } - return $channelID; - } - - function initChannel() { - $channelID = $this->getRequestVar('channelID'); - $channelName = $this->getRequestVar('channelName'); - if($channelID !== null) { - $this->switchChannel($this->getChannelNameFromChannelID($channelID)); - } else if($channelName !== null) { - if($this->getChannelIDFromChannelName($channelName) === null) { - // channelName might need encoding conversion: - $channelName = $this->trimChannelName($channelName, $this->getConfig('contentEncoding')); - } - $this->switchChannel($channelName); - } - } - - function logout($type=null) { - // Update the socket server authentication for the user: - if($this->getConfig('socketServerEnabled')) { - $this->updateSocketAuthentication($this->getUserID()); - } - if($this->isUserOnline()) { - $this->chatViewLogout($type); - } - $this->setLoggedIn(false); - $this->destroySession(); - - // Re-initialize the view: - $this->initView(); - } - - function chatViewLogout($type) { - $this->removeFromOnlineList(); - if($type !== null) { - $type = ' '.$type; - } - // Logout message - $text = '/logout '.$this->getUserName().$type; - $this->insertChatBotMessage( - $this->getChannel(), - $text, - null, - 1 - ); - } - - function switchChannel($channelName) { - $channelID = $this->getChannelIDFromChannelName($channelName); - - if($channelID !== null && $this->getChannel() == $channelID) { - // User is already in the given channel, return: - return; - } - - // Check if we have a valid channel: - if(!$this->validateChannel($channelID)) { - // Invalid channel: - $text = '/error InvalidChannelName '.$channelName; - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - $text - ); - return; - } - - $oldChannel = $this->getChannel(); - - $this->setChannel($channelID); - $this->updateOnlineList(); - - // Channel leave message - $text = '/channelLeave '.$this->getUserName(); - $this->insertChatBotMessage( - $oldChannel, - $text, - null, - 1 - ); - - // Channel enter message - $text = '/channelEnter '.$this->getUserName(); - $this->insertChatBotMessage( - $this->getChannel(), - $text, - null, - 1 - ); - - $this->addInfoMessage($channelName, 'channelSwitch'); - $this->addInfoMessage($channelID, 'channelID'); - $this->_requestVars['lastID'] = 0; - } - - function addToOnlineList() { - $sql = 'INSERT INTO '.$this->getDataBaseTable('online').'( - userID, - userName, - userRole, - channel, - dateTime, - ip - ) - VALUES ( - '.$this->db->makeSafe($this->getUserID()).', - '.$this->db->makeSafe($this->getUserName()).', - '.$this->db->makeSafe($this->getUserRole()).', - '.$this->db->makeSafe($this->getChannel()).', - NOW(), - '.$this->db->makeSafe($this->ipToStorageFormat($_SERVER['REMOTE_ADDR'])).' - );'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - $this->resetOnlineUsersData(); - } - - function removeFromOnlineList() { - $sql = 'DELETE FROM - '.$this->getDataBaseTable('online').' - WHERE - userID = '.$this->db->makeSafe($this->getUserID()).';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - $this->removeUserFromOnlineUsersData(); - } - - function updateOnlineList() { - $sql = 'UPDATE - '.$this->getDataBaseTable('online').' - SET - userName = '.$this->db->makeSafe($this->getUserName()).', - channel = '.$this->db->makeSafe($this->getChannel()).', - dateTime = NOW(), - ip = '.$this->db->makeSafe($this->ipToStorageFormat($_SERVER['REMOTE_ADDR'])).' - WHERE - userID = '.$this->db->makeSafe($this->getUserID()).';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - $this->resetOnlineUsersData(); - } - - function initMessageHandling() { - // Don't handle messages if we are not in chat view: - if($this->getView() != 'chat') { - return; - } - - // Check if we have been uninvited from a private or restricted channel: - if(!$this->validateChannel($this->getChannel())) { - // Switch to the default channel: - $this->switchChannel($this->getChannelNameFromChannelID($this->getConfig('defaultChannelID'))); - return; - } - - if($this->getRequestVar('text') !== null) { - $this->insertMessage($this->getRequestVar('text')); - } - } - - function insertParsedMessage($text) { - // Replace Unicode character - $text = preg_replace("/\xEF\xBF\xBF/im", " ", $text); - - $gtParse = preg_replace('/\\[(?:\\/)?(\\w+)(?:=([^<>]*?))?\\]/ms', '', $text); - - // Auto greentext - if(preg_match("/>(.*?)$/im", $gtParse)) { - $text = preg_replace("/>(.*?)$/im", "[color=Green]>$1[/color]", $gtParse); - } - if(preg_match("/(.*?)<$/im", $gtParse)) { - $text = preg_replace("/(.*?)<$/im", "[color=Red]$1<[/color]", $gtParse); - } - - // Emoticon Limiting - $emoticons = array(':happy:', ':lmao:', ':angry:', ':angrier:', ':evil:', ':glare:', ':eat:', ':lol:', ':dizzy:', ':yay:', ':wtf:', ':sigh:', ':omg:', ':ouch:', ':tired:', ':kiss:', ':love:', ':sweat:', ':suspicious:', ':crying:', ':blank:', ':puke:', ':ruse:', ':meow:'); - $emoticonCount = 0; - - foreach($emoticons as $emoticon) { - // Increase Emoticon count - $emoticonCount += substr_count($text, $emoticon); - - // If higher than 10 replace then - if($emoticonCount > 10) - $text = str_replace($emoticon, '', $text); - } - - if($this->getQueryUserName() !== null && strpos($text, '/') !== 0) { - // If a queryUserName is set, sent all messages as private messages to this userName: - $text = '/msg '.$this->getQueryUserName().' '.$text; - } - - if(strpos($text, '/') === 0) { - // Parse IRC-style commands: - $textParts = explode(' ', $text); - - switch($textParts[0]) { - // Channel switch: - case '/join': - $this->insertParsedMessageJoin($textParts); - break; - - // Logout: - case '/quit': - case '/suicide': - $this->logout(); - break; - - // Private message: - case '/msg': - case '/describe': - $this->insertParsedMessagePrivMsg($textParts); - break; - - // Invitation: - case '/invite': - $this->insertParsedMessageInvite($textParts); - break; - - // Uninvitation: - case '/uninvite': - $this->insertParsedMessageUninvite($textParts); - break; - - // Private messaging: - case '/query': - $this->insertParsedMessageQuery($textParts); - break; - - // Kicking offending users from the chat: - case '/kick': - $this->insertParsedMessageKick($textParts); - break; - - // Listing banned users: - case '/bans': - $this->insertParsedMessageBans($textParts); - break; - - // Unban user (remove from ban list): - case '/unban': - $this->insertParsedMessageUnban($textParts); - break; - - // Describing actions: - case '/me': - case '/action': - $this->insertParsedMessageAction($textParts); - break; - - // Listing online Users: - case '/who': - $this->insertParsedMessageWho($textParts); - break; - - // Listing available channels: - case '/list': - $this->insertParsedMessageList($textParts); - break; - - // Retrieving the channel of a User: - case '/whereis': - $this->insertParsedMessageWhereis($textParts); - break; - - // Listing information about a User: - case '/whois': - $this->insertParsedMessageWhois($textParts); - break; - - // Rolling dice: - case '/roll': - $this->insertParsedMessageRoll($textParts); - break; - - // Switching userName: - case '/nick': - $this->insertParsedMessageNick($textParts); - break; - - // Switching userName: - case '/saibatekuisagoodsite': - $this->insertParsedMessageChangeNick($textParts); - break; - - // Custom or unknown command: - default: - if(!$this->parseCustomCommands($text, $textParts)) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UnknownCommand '.$textParts[0] - ); - } - } - - } else { - // No command found, just insert the plain message: - $this->insertCustomMessage( - $this->getUserID(), - $this->getUserName(), - $this->getUserRole(), - $this->getChannel(), - $text - ); - } - include_once 'satori.php'; - } - - function insertParsedMessageJoin($textParts) { - if(count($textParts) == 1) { - // join with no arguments is the own private channel, if allowed: - if($this->isAllowedToCreatePrivateChannel()) { - // Private channels are identified by square brackets: - $this->switchChannel($this->getChannelNameFromChannelID($this->getPrivateChannelID())); - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingChannelName' - ); - } - } else { - $this->switchChannel($textParts[1]); - } - } - - function insertParsedMessagePrivMsg($textParts) { - if($this->isAllowedToSendPrivateMessage()) { - if(count($textParts) < 3) { - if(count($textParts) == 2) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingText' - ); - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingUserName' - ); - } - } else { - // Get UserID from UserName: - $toUserID = $this->getIDFromName($textParts[1]); - if($toUserID === null) { - if($this->getQueryUserName() !== null) { - // Close the current query: - $this->insertMessage('/query'); - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UserNameNotFound '.$textParts[1] - ); - } - } else { - // Insert /privaction command if /describe is used: - $command = ($textParts[0] == '/describe') ? '/privaction' : '/privmsg'; - // Copy of private message to current User: - $this->insertCustomMessage( - $this->getUserID(), - $this->getUserName(), - $this->getUserRole(), - $this->getPrivateMessageID(), - $command.'to '.$textParts[1].' '.implode(' ', array_slice($textParts, 2)) - ); - // Private message to requested User: - $this->insertCustomMessage( - $this->getUserID(), - $this->getUserName(), - $this->getUserRole(), - $this->getPrivateMessageID($toUserID), - $command.' '.implode(' ', array_slice($textParts, 2)) - ); - } - } - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error PrivateMessageNotAllowed' - ); - } - } - - function insertParsedMessageInvite($textParts) { - if($this->getChannel() == $this->getPrivateChannelID() || in_array($this->getChannel(), $this->getChannels())) { - if(count($textParts) == 1) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingUserName' - ); - } else { - $toUserID = $this->getIDFromName($textParts[1]); - if($toUserID === null) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UserNameNotFound '.$textParts[1] - ); - } else { - // Add the invitation to the database: - $this->addInvitation($toUserID); - $invitationChannelName = $this->getChannelNameFromChannelID($this->getChannel()); - // Copy of invitation to current User: - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/inviteto '.$textParts[1].' '.$invitationChannelName - ); - // Invitation to requested User: - $this->insertChatBotMessage( - $this->getPrivateMessageID($toUserID), - '/invite '.$this->getUserName().' '.$invitationChannelName - ); - } - } - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error InviteNotAllowed' - ); - } - } - - function insertParsedMessageUninvite($textParts) { - if($this->getChannel() == $this->getPrivateChannelID() || in_array($this->getChannel(), $this->getChannels())) { - if(count($textParts) == 1) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingUserName' - ); - } else { - $toUserID = $this->getIDFromName($textParts[1]); - if($toUserID === null) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UserNameNotFound '.$textParts[1] - ); - } else { - // Remove the invitation from the database: - $this->removeInvitation($toUserID); - $invitationChannelName = $this->getChannelNameFromChannelID($this->getChannel()); - // Copy of uninvitation to current User: - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/uninviteto '.$textParts[1].' '.$invitationChannelName - ); - // Uninvitation to requested User: - $this->insertChatBotMessage( - $this->getPrivateMessageID($toUserID), - '/uninvite '.$this->getUserName().' '.$invitationChannelName - ); - } - } - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UninviteNotAllowed' - ); - } - } - - function insertParsedMessageQuery($textParts) { - if($this->isAllowedToSendPrivateMessage()) { - if(count($textParts) == 1) { - if($this->getQueryUserName() !== null) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/queryClose '.$this->getQueryUserName() - ); - // Close the current query: - $this->setQueryUserName(null); - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error NoOpenQuery' - ); - } - } else { - if($this->getIDFromName($textParts[1]) === null) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UserNameNotFound '.$textParts[1] - ); - } else { - if($this->getQueryUserName() !== null) { - // Close the current query: - $this->insertMessage('/query'); - } - // Open a query to the requested user: - $this->setQueryUserName($textParts[1]); - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/queryOpen '.$textParts[1] - ); - } - } - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error PrivateMessageNotAllowed' - ); - } - } - - function insertParsedMessageKick($textParts) { - // Only moderators/admins may kick users: - if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == CMOD || $this->getUserID() == 11) { - if(count($textParts) == 1) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingUserName' - ); - } else { - // Get UserID from UserName: - $kickUserID = $this->getIDFromName($textParts[1]); - if($kickUserID === null) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UserNameNotFound '.$textParts[1] - ); - } else { - // Check the role of the user to kick: - $kickUserRole = $this->getRoleFromID($kickUserID); - if( - $kickUserRole == AJAX_CHAT_ADMIN || - ( - ( - $kickUserID == 11 - && - $this->getUserRole() != AJAX_CHAT_ADMIN - && - $this->getUserID() != 11 - ) - || - ( - $kickUserRole == CMOD - && - $this->getUserRole() != AJAX_CHAT_MODERATOR - && - $this->getUserRole() != PURPLE - && - $this->getUserRole() != AJAX_CHAT_ADMIN - && - $this->getUserID() != 11 - ) - || - ( - $kickUserRole == AJAX_CHAT_MODERATOR - && - $this->getUserRole() != PURPLE - && - $this->getUserRole() != AJAX_CHAT_ADMIN - && - $this->getUserID() != 11 - ) - ) - ) { - // Admins and moderators may not be kicked: - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error KickNotAllowed '.$textParts[1] - ); - } else { - // Kick user and insert message: - $channel = $this->getChannelFromID($kickUserID); - $banMinutes = (count($textParts) > 2) ? $textParts[2] : null; - $this->kickUser($textParts[1], $banMinutes, $kickUserID); - // If no channel found, user logged out before he could be kicked - if($channel !== null) { - $this->insertChatBotMessage( - $channel, - '/kick '.$textParts[1], - null, - 1 - ); - // Send a copy of the message to the current user, if not in the channel: - if($channel != $this->getChannel()) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/kick '.$textParts[1], - null, - 1 - ); - } - } - } - } - } - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error CommandNotAllowed '.$textParts[0] - ); - } - } - - function insertParsedMessageBans($textParts) { - // Only moderators/admins may see the list of banned users: - if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == CMOD) { - $this->removeExpiredBans(); - $bannedUsers = $this->getBannedUsers(); - if(count($bannedUsers) > 0) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/bans '.implode(' ', $bannedUsers) - ); - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/bansEmpty -' - ); - } - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error CommandNotAllowed '.$textParts[0] - ); - } - } - - function insertParsedMessageUnban($textParts) { - // Only moderators/admins may unban users: - if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == CMOD) { - $this->removeExpiredBans(); - if(count($textParts) == 1) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingUserName' - ); - } else { - if(!in_array($textParts[1], $this->getBannedUsers())) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UserNameNotFound '.$textParts[1] - ); - } else { - // Unban user and insert message: - $this->unbanUser($textParts[1]); - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/unban '.$textParts[1] - ); - } - } - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error CommandNotAllowed '.$textParts[0] - ); - } - } - - function insertParsedMessageAction($textParts) { - if(count($textParts) == 1) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingText' - ); - } else { - if($this->getQueryUserName() !== null) { - // If we are in query mode, sent the action to the query user: - $this->insertMessage('/describe '.$this->getQueryUserName().' '.implode(' ', array_slice($textParts, 1))); - } else { - $this->insertCustomMessage( - $this->getUserID(), - $this->getUserName(), - $this->getUserRole(), - $this->getChannel(), - implode(' ', $textParts) - ); - } - } - } - - function insertParsedMessageWho($textParts) { - if(count($textParts) == 1) { - if($this->isAllowedToListHiddenUsers()) { - // List online users from any channel: - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/who '.implode(' ', $this->getOnlineUsers()) - ); - } else { - // Get online users for all accessible channels: - $channels = $this->getChannels(); - // Add the own private channel if allowed: - if($this->isAllowedToCreatePrivateChannel()) { - array_push($channels, $this->getPrivateChannelID()); - } - // Add the invitation channels: - foreach($this->getInvitations() as $channelID) { - if(!in_array($channelID, $channels)) { - array_push($channels, $channelID); - } - } - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/who '.implode(' ', $this->getOnlineUsers($channels)) - ); - } - } else { - $channelName = $textParts[1]; - $channelID = $this->getChannelIDFromChannelName($channelName); - if(!$this->validateChannel($channelID)) { - // Invalid channel: - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error InvalidChannelName '.$channelName - ); - } else { - // Get online users for the given channel: - $onlineUsers = $this->getOnlineUsers(array($channelID)); - if(count($onlineUsers) > 0) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/whoChannel '.$channelName.' '.implode(' ', $onlineUsers) - ); - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/whoEmpty -' - ); - } - } - } - } - - function insertParsedMessageList($textParts) { - // Get the names of all accessible channels: - $channelNames = $this->getChannelNames(); - // Add the own private channel, if allowed: - if($this->isAllowedToCreatePrivateChannel()) { - array_push($channelNames, $this->getPrivateChannelName()); - } - // Add the invitation channels: - foreach($this->getInvitations() as $channelID) { - $channelName = $this->getChannelNameFromChannelID($channelID); - if($channelName !== null && !in_array($channelName, $channelNames)) { - array_push($channelNames, $channelName); - } - } - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/list '.implode(' ', $channelNames) - ); - } - - function insertParsedMessageWhereis($textParts) { - if(count($textParts) == 1) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingUserName' - ); - } else { - // Get UserID from UserName: - $whereisUserID = $this->getIDFromName($textParts[1]); - if($whereisUserID === null) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UserNameNotFound '.$textParts[1] - ); - } else { - $channelID = $this->getChannelFromID($whereisUserID); - if($this->validateChannel($channelID)) { - $channelName = $this->getChannelNameFromChannelID($channelID); - } else { - $channelName = null; - } - if($channelName === null) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UserNameNotFound '.$textParts[1] - ); - } else { - // List user information: - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/whereis '.$textParts[1].' '.$channelName - ); - } - } - } - } - - function insertParsedMessageWhois($textParts) { - // Only moderators/admins: - if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == PURPLE || $this->getUserRole() == CMOD) { -// if($this->getUserRole() == AJAX_CHAT_ADMIN) { - if(count($textParts) == 1) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingUserName' - ); - } else { - // Get UserID from UserName: - $whoisUserID = $this->getIDFromName($textParts[1]); - if($whoisUserID === null) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UserNameNotFound '.$textParts[1] - ); - } else { - // List user information: - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/whois '.$textParts[1].' '.$this->getIPFromID($whoisUserID) - ); - } - } - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error CommandNotAllowed '.$textParts[0] - ); - } - } - - function insertParsedMessageRoll($textParts) { - if(count($textParts) == 1) { - // default is one d6: - $text = '/roll '.$this->getUserName().' 1d6 '.$this->rollDice(6); - } else { - $diceParts = explode('d', $textParts[1]); - if(count($diceParts) == 2) { - $number = (int)$diceParts[0]; - $sides = (int)$diceParts[1]; - - // Dice number must be an integer between 1 and 100, else roll only one: - $number = ($number > -1 && $number < 100) ? $number : 1; - - // Sides must be an integer between 1 and 100, else take 6: - $sides = ($sides > -1 && $sides < 100) ? $sides : 6; - - $text = '/roll '.$this->getUserName().' '.$number.'d'.$sides.' '; - for($i=0; $i<$number; $i++) { - if($i != 0) - $text .= ','; - switch($this->getUserID()) { // snowflake - case 3://303: - $text .= str_shuffle('bird'); - break; - - case 0://230: - $text .= str_shuffle('portugal'); - break; - - case 15://21: - $text .= str_shuffle('divorce'); - break; - - case 2://8: - $text .= str_shuffle('mewow'); - break; - - default: - $text .= $this->rollDice($sides); - } - } - } else { - // if dice syntax is invalid, roll one d6: - $text = '/roll '.$this->getUserName().' 1d6 '.$this->rollDice(6); - } - } - $this->insertChatBotMessage( - $this->getChannel(), - $text - ); - } - - function insertParsedMessageNick($textParts) { - if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == PURPLE || $this->getUserRole() == CMOD || $this->getUserRole() == BOTS || $this->getUserRole() == DONATOR) { - if(!$this->getConfig('allowNickChange') || - (!$this->getConfig('allowGuestUserName') && $this->getUserRole() == AJAX_CHAT_GUEST)) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error CommandNotAllowed '.$textParts[0] - ); - } elseif(count($textParts) == 1) { - $oldUserName = $this->getUserName(); - $newUserName = $this->getLoginUserName(); - if($oldUserName != $newUserName) { - $this->setUserName($newUserName); - $this->updateOnlineList(); - // Add info message to update the client-side stored userName: - $this->addInfoMessage($this->getUserName(), 'userName'); - $this->insertChatBotMessage( - $this->getChannel(), - '/nick '.$oldUserName.' '.$newUserName, - null, - 2 - ); - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingUserName' - ); - } - } else { - $newUserName = implode(' ', array_slice($textParts, 1)); - if($newUserName == $this->getLoginUserName()) { - // Allow the user to regain the original login userName: - $prefix = ''; - $suffix = ''; - } else if($this->getUserRole() == AJAX_CHAT_GUEST) { - $prefix = $this->getConfig('guestUserPrefix'); - $suffix = $this->getConfig('guestUserSuffix'); - } else { - $prefix = $this->getConfig('changedNickPrefix'); - $suffix = $this->getConfig('changedNickSuffix'); - } - $maxLength = $this->getConfig('userNameMaxLength') - - $this->stringLength($prefix) - - $this->stringLength($suffix); - $newUserName = $this->trimString($newUserName, 'UTF-8', $maxLength, true); - if(!$newUserName) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error InvalidUserName' - ); - } else { - $newUserName = $prefix.$newUserName.$suffix; - if($this->isUserNameInUse($newUserName)) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error UserNameInUse' - ); - } else { - $oldUserName = $this->getUserName(); - $this->setUserName($newUserName); - $this->updateOnlineList(); - // Add info message to update the client-side stored userName: - $this->addInfoMessage($this->getUserName(), 'userName'); - $this->insertChatBotMessage( - $this->getChannel(), - '/nick '.$oldUserName.' '.$newUserName, - null, - 2 - ); - } - } - } - } else { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error CommandNotAllowed '.$textParts[0] - ); - } - } - - function insertParsedMessageChangeNick($textParts) { - if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR) { - if(count($textParts) == 1) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MissingUserName' - ); - } else { - $newUserName = implode(' ', array_slice($textParts, 1)); - $oldUserName = $this->getUserName(); - $this->setUserName($newUserName); - $this->updateOnlineList(); - $this->addInfoMessage($this->getUserName(), 'userName'); - } - } - } - - function insertMessage($text) { - if(!$this->isAllowedToWriteMessage()) - return; - - if(!$this->floodControl()) - return; - - $text = $this->trimMessageText($text); - if($text == '') - return; - - if(!$this->onNewMessage($text)) - return; - - $text = $this->replaceCustomText($text); - - $this->insertParsedMessage($text); - } - - function deleteMessage($messageID) { - // Retrieve the channel of the given message: - $sql = 'SELECT - channel - FROM - '.$this->getDataBaseTable('messages').' - WHERE - id='.$this->db->makeSafe($messageID).';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - $row = $result->fetch(); - - if($row['channel'] !== null) { - $channel = $row['channel']; - - if($this->getUserRole() == AJAX_CHAT_ADMIN) { - $condition = ''; - } else if($this->getUserRole() == CMOD || $this->getUserRole() == PURPLE) { - $condition = ' AND - NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_MODERATOR).') - AND - NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_ADMIN).') - AND - NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_CHATBOT).')'; - } else if($this->getUserRole() == AJAX_CHAT_MODERATOR) { - $condition = ' AND - NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_ADMIN).') - AND - NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_CHATBOT).')'; - } else if($this->getUserRole() == AJAX_CHAT_USER && $this->getConfig('allowUserMessageDelete')) { - $condition = 'AND - ( - userID='.$this->db->makeSafe($this->getUserID()).' - OR - ( - channel = '.$this->db->makeSafe($this->getPrivateMessageID()).' - OR - channel = '.$this->db->makeSafe($this->getPrivateChannelID()).' - ) - AND - NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_ADMIN).') - AND - NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_CHATBOT).') - )'; - } else { - return false; - } - - // Remove given message from the database: - $sql = 'DELETE FROM - '.$this->getDataBaseTable('messages').' - WHERE - id='.$this->db->makeSafe($messageID).' - '.$condition.';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - if($result->affectedRows() == 1) { - // Insert a deletion command to remove the message from the clients chatlists: - $this->insertChatBotMessage($channel, '/delete '.$messageID); - return true; - } - } - return false; - } - - function floodControl() { - // Admins can do whatever the fuck they want: - if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserID() == 11) { - return true; - } - $time = time(); - // Check the time of the last inserted message: - if($this->getInsertedMessagesRateTimeStamp()+60 < $time) { - $this->setInsertedMessagesRateTimeStamp($time); - $this->setInsertedMessagesRate(1); - } else { - // Increase the inserted messages rate: - $rate = $this->getInsertedMessagesRate()+1; - $this->setInsertedMessagesRate($rate); - // Check if message rate is too high: - if($rate > $this->getConfig('maxMessageRate')) { - $this->insertChatBotMessage( - $this->getPrivateMessageID(), - '/error MaxMessageRate' - ); - $this->kickUser($this->getUserName(), 10, $this->getUserID()); - $this->insertChatBotMessage($this->getChannel(), "[i][b]".$this->getUsername()."[/b] exceeded the message limit and will now be kicked for 10 minutes.[/i]"); - $this->insertChatBotMessage($this->getChannel(), "/kick ". $this->getUsername()); - // Return false so the message is not inserted: - return false; - } - } - return true; - } - - function isAllowedToWriteMessage() { - if($this->getUserRole() != AJAX_CHAT_GUEST) - return true; - if($this->getConfig('allowGuestWrite')) - return true; - return false; - } - - function insertChatBotMessage($channelID, $messageText, $ip=null, $mode=0) { - $this->insertCustomMessage( - $this->getConfig('chatBotID'), - $this->getConfig('chatBotName'), - AJAX_CHAT_CHATBOT, - $channelID, - $messageText, - $ip, - $mode - ); - } - - function insertCustomMessage($userID, $userName, $userRole, $channelID, $text, $ip=null, $mode=0) { - // The $mode parameter is used for socket updates: - // 0 = normal messages - // 1 = channel messages (e.g. login/logout, channel enter/leave, kick) - // 2 = messages with online user updates (nick) - - $ip = $ip ? $ip : $_SERVER['REMOTE_ADDR']; - - $sql = 'INSERT INTO '.$this->getDataBaseTable('messages').'( - userID, - userName, - userRole, - channel, - dateTime, - ip, - text - ) - VALUES ( - '.$this->db->makeSafe($userID).', - '.$this->db->makeSafe($userName).', - '.$this->db->makeSafe($userRole).', - '.$this->db->makeSafe($channelID).', - NOW(), - '.$this->db->makeSafe($this->ipToStorageFormat($ip)).', - '.$this->db->makeSafe($text).' - );'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - if($this->getConfig('socketServerEnabled')) { - $this->sendSocketMessage( - $this->getSocketBroadcastMessage( - $this->db->getLastInsertedID(), - time(), - $userID, - $userName, - $userRole, - $channelID, - $text, - $mode - ) - ); - } - } - - function getSocketBroadcastMessage( - $messageID, - $timeStamp, - $userID, - $userName, - $userRole, - $channelID, - $text, - $mode - ) { - // The $mode parameter: - // 0 = normal messages - // 1 = channel messages (e.g. login/logout, channel enter/leave, kick) - // 2 = messages with online user updates (nick) - - // Get the message XML content: - $xml = ''; - if($mode) { - // Add the list of online users if the user list has been updated ($mode > 0): - $xml .= $this->getChatViewOnlineUsersXML(array($channelID)); - } - if($mode != 1 || $this->getConfig('showChannelMessages')) { - $xml .= ''; - $xml .= $this->getChatViewMessageXML( - $messageID, - $timeStamp, - $userID, - $userName, - $userRole, - $channelID, - $text - ); - $xml .= ''; - } - $xml .= ''; - return $xml; - } - - function sendSocketMessage($message) { - // Open a TCP socket connection to the socket server: - if($socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) { - if(@socket_connect($socket, $this->getConfig('socketServerIP'), $this->getConfig('socketServerPort'))) { - // Append a null-byte to the string as EOL (End Of Line) character - // which is required by Flash XML socket communication: - $message .= "\0"; - @socket_write( - $socket, - $message, - strlen($message) // Using strlen to count the bytes instead of the number of UTF-8 characters - ); - } - @socket_close($socket); - } - } - - function updateSocketAuthentication($userID, $socketRegistrationID=null, $channels=null) { - // If no $socketRegistrationID or no $channels are given the authentication is removed for the given user: - $authentication = ''; - if($channels) { - foreach($channels as $channelID) { - $authentication .= ''; - } - } - $authentication .= ''; - $this->sendSocketMessage($authentication); - } - - function setSocketRegistrationID($value) { - $this->setSessionVar('SocketRegistrationID', $value); - } - - function getSocketRegistrationID() { - return $this->getSessionVar('SocketRegistrationID'); - } - - function rollDice($sides) { - // seed with microseconds since last "whole" second: - //mt_srand((double)microtime()*1000000); - - return mt_rand(1, $sides); - } - - function kickUser($userName, $banMinutes=null, $userID=null) { - if($userID === null) { - $userID = $this->getIDFromName($userName); - } - if($userID === null) { - return; - } - - $banMinutes = ($banMinutes !== null) ? $banMinutes : $this->getConfig('defaultBanTime'); - - if($banMinutes) { - // Ban User for the given time in minutes: - $this->banUser($userName, $banMinutes, $userID); - } - - // Remove given User from online list: - $sql = 'DELETE FROM - '.$this->getDataBaseTable('online').' - WHERE - userID = '.$this->db->makeSafe($userID).';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - // Update the socket server authentication for the kicked user: - if($this->getConfig('socketServerEnabled')) { - $this->updateSocketAuthentication($userID); - } - - $this->removeUserFromOnlineUsersData($userID); - } - - function getBannedUsersData($key=null, $value=null) { - if($this->_bannedUsersData === null) { - $this->_bannedUsersData = array(); - - $sql = 'SELECT - userID, - userName, - ip - FROM - '.$this->getDataBaseTable('bans').' - WHERE - NOW() < dateTime;'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - while($row = $result->fetch()) { - $row['ip'] = $this->ipFromStorageFormat($row['ip']); - array_push($this->_bannedUsersData, $row); - } - - $result->free(); - } - - if($key) { - $bannedUsersData = array(); - foreach($this->_bannedUsersData as $bannedUserData) { - if(!isset($bannedUserData[$key])) { - return $bannedUsersData; - } - if($value) { - if($bannedUserData[$key] == $value) { - array_push($bannedUsersData, $bannedUserData); - } else { - continue; - } - } else { - array_push($bannedUsersData, $bannedUserData[$key]); - } - } - return $bannedUsersData; - } - - return $this->_bannedUsersData; - } - - function getBannedUsers() { - return $this->getBannedUsersData('userName'); - } - - function banUser($userName, $banMinutes=null, $userID=null) { - if($userID === null) { - $userID = $this->getIDFromName($userName); - } - $ip = $this->getIPFromID($userID); - if(!$ip || $userID === null) { - return; - } - - // Remove expired bans: - $this->removeExpiredBans(); - - $banMinutes = (int)$banMinutes; - if(!$banMinutes) { - // If banMinutes is not a valid integer, use the defaultBanTime: - $banMinutes = $this->getConfig('defaultBanTime'); - } - - $sql = 'INSERT INTO '.$this->getDataBaseTable('bans').'( - userID, - userName, - dateTime, - ip - ) - VALUES ( - '.$this->db->makeSafe($userID).', - '.$this->db->makeSafe($userName).', - DATE_ADD(NOW(), interval '.$this->db->makeSafe($banMinutes).' MINUTE), - '.$this->db->makeSafe($this->ipToStorageFormat($ip)).' - );'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - } - - function unbanUser($userName) { - $sql = 'DELETE FROM - '.$this->getDataBaseTable('bans').' - WHERE - userName = '.$this->db->makeSafe($userName).';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - } - - function removeExpiredBans() { - $sql = 'DELETE FROM - '.$this->getDataBaseTable('bans').' - WHERE - dateTime < NOW();'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - } - - function setInactive($userID, $userName=null) { - $condition = 'userID='.$this->db->makeSafe($userID); - if($userName !== null) { - $condition .= ' OR userName='.$this->db->makeSafe($userName); - } - $sql = 'UPDATE - '.$this->getDataBaseTable('online').' - SET - dateTime = DATE_SUB(NOW(), interval '.(intval($this->getConfig('inactiveTimeout'))+1).' MINUTE) - WHERE - '.$condition.';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - $this->resetOnlineUsersData(); - } - - function removeInactive() { - $sql = 'SELECT - userID, - userName, - channel - FROM - '.$this->getDataBaseTable('online').' - WHERE - NOW() > DATE_ADD(dateTime, interval '.$this->getConfig('inactiveTimeout').' MINUTE);'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - if($result->numRows() > 0) { - $condition = ''; - while($row = $result->fetch()) { - if(!empty($condition)) - $condition .= ' OR '; - // Add userID to condition for removal: - $condition .= 'userID='.$this->db->makeSafe($row['userID']); - - // Update the socket server authentication for the kicked user: - if($this->getConfig('socketServerEnabled')) { - $this->updateSocketAuthentication($row['userID']); - } - - $this->removeUserFromOnlineUsersData($row['userID']); - - // Insert logout timeout message: - $text = '/logout '.$row['userName'].' Timeout'; - $this->insertChatBotMessage( - $row['channel'], - $text, - null, - 1 - ); - } - - $result->free(); - - $sql = 'DELETE FROM - '.$this->getDataBaseTable('online').' - WHERE - '.$condition.';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - } - } - - function updateOnlineStatus() { - // Update online status every 50 seconds (this allows update requests to be in time): - if(!$this->getStatusUpdateTimeStamp() || ((time() - $this->getStatusUpdateTimeStamp()) > 50)) { - $this->updateOnlineList(); - $this->setStatusUpdateTimeStamp(time()); - } - } - - function checkAndRemoveInactive() { - // Remove inactive users every inactiveCheckInterval: - if(!$this->getInactiveCheckTimeStamp() || ((time() - $this->getInactiveCheckTimeStamp()) > $this->getConfig('inactiveCheckInterval')*60)) { - $this->removeInactive(); - $this->setInactiveCheckTimeStamp(time()); - } - } - - function sendXMLMessages() { - $httpHeader = new AJAXChatHTTPHeader('UTF-8', 'text/xml'); - - // Send HTTP header: - $httpHeader->send(); - - // Output XML messages: - echo $this->getXMLMessages(); - } - - function getXMLMessages() { - switch($this->getView()) { - case 'chat': - return $this->getChatViewXMLMessages(); - case 'teaser': - return $this->getTeaserViewXMLMessages(); - case 'logs': - return $this->getLogsViewXMLMessages(); - default: - return $this->getLogoutXMLMessage(); - } - } - - function getMessageCondition() { - $condition = 'id > '.$this->db->makeSafe($this->getRequestVar('lastID')).' - AND ( - channel = '.$this->db->makeSafe($this->getChannel()).' - OR - channel = '.$this->db->makeSafe($this->getPrivateMessageID()).' - ) - AND - '; - if($this->getConfig('requestMessagesPriorChannelEnter') || - ($this->getConfig('requestMessagesPriorChannelEnterList') && in_array($this->getChannel(), $this->getConfig('requestMessagesPriorChannelEnterList')))) { - $condition .= 'NOW() < DATE_ADD(dateTime, interval '.$this->getConfig('requestMessagesTimeDiff').' HOUR)'; - } else { - $condition .= 'dateTime >= \''.date('Y-m-d H:i:s', $this->getChannelEnterTimeStamp()).'\''; - } - return $condition; - } - - function getMessageFilter() { - $filterChannelMessages = ''; - if(!$this->getConfig('showChannelMessages') || $this->getRequestVar('shoutbox')) { - $filterChannelMessages = ' AND NOT ( - text LIKE (\'/login%\') - OR - text LIKE (\'/logout%\') - OR - text LIKE (\'/channelEnter%\') - OR - text LIKE (\'/channelLeave%\') - OR - text LIKE (\'/kick%\') - )'; - } - return $filterChannelMessages; - } - - function getInfoMessagesXML() { - $xml = ''; - // Go through the info messages: - foreach($this->getInfoMessages() as $type=>$infoArray) { - foreach($infoArray as $info) { - $xml .= ''; - $xml .= 'encodeSpecialChars($info).']]>'; - $xml .= ''; - } - } - $xml .= ''; - return $xml; - } - - function getChatViewOnlineUsersXML($channelIDs) { - // Get the online users for the given channels: - $onlineUsersData = $this->getOnlineUsersData($channelIDs); - $xml = ''; - foreach($onlineUsersData as $onlineUserData) { - $xml .= 'encodeSpecialChars($onlineUserData['userName']).']]>'; - $xml .= ''; - } - $xml .= ''; - return $xml; - } - - function getLogoutXMLMessage() { - $xml = ''; - $xml .= ''; - $xml .= ''; - $xml .= ''; - $xml .= 'encodeSpecialChars($this->getConfig('logoutData')).']]>'; - $xml .= ''; - $xml .= ''; - $xml .= ''; - return $xml; - } - - function getChatViewMessageXML( - $messageID, - $timeStamp, - $userID, - $userName, - $userRole, - $channelID, - $text - ) { - $message = 'encodeSpecialChars($userName).']]>'; - $message .= 'encodeSpecialChars($text).']]>'; - $message .= ''; - return $message; - } - - function getChatViewMessagesXML() { - // Get the last messages in descending order (this optimises the LIMIT usage): - $sql = 'SELECT - id, - userID, - userName, - userRole, - channel AS channelID, - UNIX_TIMESTAMP(dateTime) AS timeStamp, - text - FROM - '.$this->getDataBaseTable('messages').' - WHERE - '.$this->getMessageCondition().' - '.$this->getMessageFilter().' - ORDER BY - id - DESC - LIMIT '.$this->getConfig('requestMessagesLimit').';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - $messages = ''; - - // Add the messages in reverse order so it is ascending again: - while($row = $result->fetch()) { - $message = $this->getChatViewMessageXML( - $row['id'], - $row['timeStamp'], - $row['userID'], - $row['userName'], - $row['userRole'], - $row['channelID'], - $row['text'] - ); - $messages = $message.$messages; - } - $result->free(); - - $messages = ''.$messages.''; - return $messages; - } - - function getChatViewXMLMessages() { - $xml = ''; - $xml .= ''; - $xml .= $this->getInfoMessagesXML(); - $xml .= $this->getChatViewOnlineUsersXML(array($this->getChannel())); - $xml .= $this->getChatViewMessagesXML(); - $xml .= ''; - return $xml; - } - - function getTeaserMessageCondition() { - $channelID = $this->getValidRequestChannelID(); - $condition = 'channel = '.$this->db->makeSafe($channelID).' - AND - '; - if($this->getConfig('requestMessagesPriorChannelEnter') || - ($this->getConfig('requestMessagesPriorChannelEnterList') && in_array($channelID, $this->getConfig('requestMessagesPriorChannelEnterList')))) { - $condition .= 'NOW() < DATE_ADD(dateTime, interval '.$this->getConfig('requestMessagesTimeDiff').' HOUR)'; - } else { - // Teaser content may not be shown for this channel: - $condition .= '0 = 1'; - } - return $condition; - } - - function getTeaserViewMessagesXML() { - // Get the last messages in descending order (this optimises the LIMIT usage): - $sql = 'SELECT - id, - userID, - userName, - userRole, - channel AS channelID, - UNIX_TIMESTAMP(dateTime) AS timeStamp, - text - FROM - '.$this->getDataBaseTable('messages').' - WHERE - '.$this->getTeaserMessageCondition().' - '.$this->getMessageFilter().' - ORDER BY - id - DESC - LIMIT '.$this->getConfig('requestMessagesLimit').';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - $messages = ''; - - // Add the messages in reverse order so it is ascending again: - while($row = $result->fetch()) { - $message = ''; - $message .= 'encodeSpecialChars($row['userName']).']]>'; - $message .= 'encodeSpecialChars($row['text']).']]>'; - $message .= ''; - $messages = $message.$messages; - } - $result->free(); - - $messages = ''.$messages.''; - return $messages; - } - - function getTeaserViewXMLMessages() { - $xml = ''; - $xml .= ''; - $xml .= $this->getInfoMessagesXML(); - $xml .= $this->getTeaserViewMessagesXML(); - $xml .= ''; - return $xml; - } - - function getLogsViewCondition() { - $condition = 'id > '.$this->db->makeSafe($this->getRequestVar('lastID')); - - // Check the channel condition: - switch($this->getRequestVar('channelID')) { - case '-3': - // Just display messages from all accessible channels - if($this->getUserRole() != AJAX_CHAT_ADMIN) { - $condition .= ' AND (channel = '.$this->db->makeSafe($this->getPrivateMessageID()); - $condition .= ' OR channel = '.$this->db->makeSafe($this->getPrivateChannelID()); - foreach($this->getChannels() as $channel) { - if($this->getConfig('logsUserAccessChannelList') && !in_array($channel, $this->getConfig('logsUserAccessChannelList'))) { - continue; - } - $condition .= ' OR channel = '.$this->db->makeSafe($channel); - } - $condition .= ')'; - } - break; - case '-2': - if($this->getUserRole() != AJAX_CHAT_ADMIN) { - $condition .= ' AND channel = '.($this->getPrivateMessageID()); - } else { - $condition .= ' AND channel > '.($this->getConfig('privateMessageDiff')-1); - } - break; - case '-1': - if($this->getUserRole() != AJAX_CHAT_ADMIN) { - $condition .= ' AND channel = '.($this->getPrivateChannelID()); - } else { - $condition .= ' AND (channel > '.($this->getConfig('privateChannelDiff')-1).' AND channel < '.($this->getConfig('privateMessageDiff')).')'; - } - break; - default: - if(($this->getUserRole() == AJAX_CHAT_ADMIN || !$this->getConfig('logsUserAccessChannelList') || in_array($this->getRequestVar('channelID'), $this->getConfig('logsUserAccessChannelList'))) - && $this->validateChannel($this->getRequestVar('channelID'))) { - $condition .= ' AND channel = '.$this->db->makeSafe($this->getRequestVar('channelID')); - } else { - // No valid channel: - $condition .= ' AND 0 = 1'; - } - } - - // Check the period condition: - $hour = ($this->getRequestVar('hour') === null || $this->getRequestVar('hour') > 23 || $this->getRequestVar('hour') < 0) ? null : $this->getRequestVar('hour'); - $day = ($this->getRequestVar('day') === null || $this->getRequestVar('day') > 31 || $this->getRequestVar('day') < 1) ? null : $this->getRequestVar('day'); - $month = ($this->getRequestVar('month') === null || $this->getRequestVar('month') > 12 || $this->getRequestVar('month') < 1) ? null : $this->getRequestVar('month'); - $year = ($this->getRequestVar('year') === null || $this->getRequestVar('year') > date('Y') || $this->getRequestVar('year') < $this->getConfig('logsFirstYear')) ? null : $this->getRequestVar('year'); - - // If a time (hour) is given but no date (year, month, day), use the current date: - if($hour !== null) { - if($day === null) - $day = date('j'); - if($month === null) - $month = date('n'); - if($year === null) - $year = date('Y'); - } - - if($year === null) { - // No year given, so no period condition - } else if($month === null) { - // Define the given year as period: - $periodStart = mktime(0, 0, 0, 1, 1, $year); - // The last day in a month can be expressed by using 0 for the day of the next month: - $periodEnd = mktime(23, 59, 59, 13, 0, $year); - } else if($day === null) { - // Define the given month as period: - $periodStart = mktime(0, 0, 0, $month, 1, $year); - // The last day in a month can be expressed by using 0 for the day of the next month: - $periodEnd = mktime(23, 59, 59, $month+1, 0, $year); - } else if($hour === null){ - // Define the given day as period: - $periodStart = mktime(0, 0, 0, $month, $day, $year); - $periodEnd = mktime(23, 59, 59, $month, $day, $year); - } else { - // Define the given hour as period: - $periodStart = mktime($hour, 0, 0, $month, $day, $year); - $periodEnd = mktime($hour, 59, 59, $month, $day, $year); - } - - if(isset($periodStart)) - $condition .= ' AND dateTime > \''.date('Y-m-d H:i:s', $periodStart).'\' AND dateTime <= \''.date('Y-m-d H:i:s', $periodEnd).'\''; - - // Check the search condition: - if($this->getRequestVar('search')) { - if(($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == PURPLE || $this->getUserRole() == CMOD) && strpos($this->getRequestVar('search'), 'ip=') === 0) { - // Search for messages with the given IP: - $ip = substr($this->getRequestVar('search'), 3); - $condition .= ' AND (ip = '.$this->db->makeSafe($this->ipToStorageFormat($ip)).')'; - } else if(strpos($this->getRequestVar('search'), 'userID=') === 0) { - // Search for messages with the given userID: - $userID = substr($this->getRequestVar('search'), 7); - $condition .= ' AND (userID = '.$this->db->makeSafe($userID).')'; - } else { - // Use the search value as regular expression on message text and username: - $condition .= ' AND (userName REGEXP '.$this->db->makeSafe($this->getRequestVar('search')).' OR text REGEXP '.$this->db->makeSafe($this->getRequestVar('search')).')'; - } - } - - // If no period or search condition is given, just monitor the last messages on the given channel: - if(!isset($periodStart) && !$this->getRequestVar('search')) { - $condition .= ' AND NOW() < DATE_ADD(dateTime, interval '.$this->getConfig('logsRequestMessagesTimeDiff').' HOUR)'; - } - - return $condition; - } - - function getLogsViewMessagesXML() { - $sql = 'SELECT - id, - userID, - userName, - userRole, - channel AS channelID, - UNIX_TIMESTAMP(dateTime) AS timeStamp, - ip, - text - FROM - '.$this->getDataBaseTable('messages').' - WHERE - '.$this->getLogsViewCondition().' - ORDER BY - id - LIMIT '.$this->getConfig('logsRequestMessagesLimit').';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - $xml = ''; - while($row = $result->fetch()) { - $xml .= 'getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == PURPLE) { - $xml .= ' ip="'.$this->ipFromStorageFormat($row['ip']).'"'; - } - $xml .= '>'; - $xml .= 'encodeSpecialChars($row['userName']).']]>'; - $xml .= 'encodeSpecialChars($row['text']).']]>'; - $xml .= ''; - } - $result->free(); - - $xml .= ''; - - return $xml; - } - - function getLogsViewXMLMessages() { - $xml = ''; - $xml .= ''; - $xml .= $this->getInfoMessagesXML(); - $xml .= $this->getLogsViewMessagesXML(); - $xml .= ''; - return $xml; - } - - function purgeLogs() { - $sql = 'DELETE FROM - '.$this->getDataBaseTable('messages').' - WHERE - dateTime < DATE_SUB(NOW(), interval '.$this->getConfig('logsPurgeTimeDiff').' DAY);'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - } - - function getInfoMessages($type=null) { - if(!isset($this->_infoMessages)) { - $this->_infoMessages = array(); - } - if($type) { - if(!isset($this->_infoMessages[$type])) { - $this->_infoMessages[$type] = array(); - } - return $this->_infoMessages[$type]; - } else { - return $this->_infoMessages; - } - } - - function addInfoMessage($info, $type='error') { - if(!isset($this->_infoMessages)) { - $this->_infoMessages = array(); - } - if(!isset($this->_infoMessages[$type])) { - $this->_infoMessages[$type] = array(); - } - if(!in_array($info, $this->_infoMessages[$type])) { - array_push($this->_infoMessages[$type], $info); - } - } - - function getRequestVars() { - return $this->_requestVars; - } - - function getRequestVar($key) { - if($this->_requestVars && isset($this->_requestVars[$key])) { - return $this->_requestVars[$key]; - } - return null; - } - - function setRequestVar($key, $value) { - if(!$this->_requestVars) { - $this->_requestVars = array(); - } - $this->_requestVars[$key] = $value; - } - - function getOnlineUsersData($channelIDs=null, $key=null, $value=null) { - if($this->_onlineUsersData === null) { - $this->_onlineUsersData = array(); - - $sql = 'SELECT - userID, - userName, - userRole, - channel, - UNIX_TIMESTAMP(dateTime) AS timeStamp, - ip - FROM - '.$this->getDataBaseTable('online').' - ORDER BY - userName;'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - while($row = $result->fetch()) { - $row['ip'] = $this->ipFromStorageFormat($row['ip']); - array_push($this->_onlineUsersData, $row); - } - - $result->free(); - } - - if($channelIDs || $key) { - $onlineUsersData = array(); - foreach($this->_onlineUsersData as $userData) { - if($channelIDs && !in_array($userData['channel'], $channelIDs)) { - continue; - } - if($key) { - if(!isset($userData[$key])) { - return $onlineUsersData; - } - if($value !== null) { - if($userData[$key] == $value) { - array_push($onlineUsersData, $userData); - } else { - continue; - } - } else { - array_push($onlineUsersData, $userData[$key]); - } - } else { - array_push($onlineUsersData, $userData); - } - } - return $onlineUsersData; - } - - return $this->_onlineUsersData; - } - - function removeUserFromOnlineUsersData($userID=null) { - if(!$this->_onlineUsersData) { - return; - } - $userID = ($userID === null) ? $this->getUserID() : $userID; - for($i=0; $i_onlineUsersData); $i++) { - if($this->_onlineUsersData[$i]['userID'] == $userID) { - array_splice($this->_onlineUsersData, $i, 1); - break; - } - } - } - - function resetOnlineUsersData() { - $this->_onlineUsersData = null; - } - - function getOnlineUsers($channelIDs=null) { - return $this->getOnlineUsersData($channelIDs, 'userName'); - } - - function getOnlineUserIDs($channelIDs=null) { - return $this->getOnlineUsersData($channelIDs, 'userID'); - } - - function startSession() { - if(!session_id()) { - // Set the session name: - session_name($this->getConfig('sessionName')); - - // Set session cookie parameters: - session_set_cookie_params( - 0, // The session is destroyed on logout anyway, so no use to set this - $this->getConfig('sessionCookiePath'), - $this->getConfig('sessionCookieDomain'), - $this->getConfig('sessionCookieSecure') - ); - - // Start the session: - session_start(); - - // We started a new session: - $this->_sessionNew = true; - } - } - - function destroySession() { - if($this->_sessionNew) { - // Delete all session variables: - $_SESSION = array(); - - // Delete the session cookie: - if (isset($_COOKIE[session_name()])) { - setcookie( - session_name(), - '', - time()-42000, - $this->getConfig('sessionCookiePath'), - $this->getConfig('sessionCookieDomain'), - $this->getConfig('sessionCookieSecure') - ); - } - - // Destroy the session: - session_destroy(); - } else { - // Unset all session variables starting with the sessionKeyPrefix: - foreach($_SESSION as $key=>$value) { - if(strpos($key, $this->getConfig('sessionKeyPrefix')) === 0) { - unset($_SESSION[$key]); - } - } - } - } - - function regenerateSessionID() { - if($this->_sessionNew) { - // Regenerate session id: - @session_regenerate_id(true); - } - } - - function getSessionVar($key, $prefix=null) { - if($prefix === null) - $prefix = $this->getConfig('sessionKeyPrefix'); - - // Return the session value if existing: - if(isset($_SESSION[$prefix.$key])) - return $_SESSION[$prefix.$key]; - else - return null; - } - - function setSessionVar($key, $value, $prefix=null) { - if($prefix === null) - $prefix = $this->getConfig('sessionKeyPrefix'); - - // Set the session value: - $_SESSION[$prefix.$key] = $value; - } - - function getSessionIP() { - return $this->getSessionVar('IP'); - } - - function setSessionIP($ip) { - $this->setSessionVar('IP', $ip); - } - - function getQueryUserName() { - return $this->getSessionVar('QueryUserName'); - } - - function setQueryUserName($userName) { - $this->setSessionVar('QueryUserName', $userName); - } - - function getInvitations() { - if($this->_invitations === null) { - $this->_invitations = array(); - - $sql = 'SELECT - channel - FROM - '.$this->getDataBaseTable('invitations').' - WHERE - userID='.$this->db->makeSafe($this->getUserID()).' - AND - DATE_SUB(NOW(), interval 1 DAY) < dateTime;'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - - while($row = $result->fetch()) { - array_push($this->_invitations, $row['channel']); - } - - $result->free(); - } - return $this->_invitations; - } - - function removeExpiredInvitations() { - $sql = 'DELETE FROM - '.$this->getDataBaseTable('invitations').' - WHERE - DATE_SUB(NOW(), interval 1 DAY) > dateTime;'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - } - - function addInvitation($userID, $channelID=null) { - $this->removeExpiredInvitations(); - - $channelID = ($channelID === null) ? $this->getChannel() : $channelID; - - $sql = 'INSERT INTO '.$this->getDataBaseTable('invitations').'( - userID, - channel, - dateTime - ) - VALUES ( - '.$this->db->makeSafe($userID).', - '.$this->db->makeSafe($channelID).', - NOW() - );'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - } - - function removeInvitation($userID, $channelID=null) { - $channelID = ($channelID === null) ? $this->getChannel() : $channelID; - - $sql = 'DELETE FROM - '.$this->getDataBaseTable('invitations').' - WHERE - userID='.$this->db->makeSafe($userID).' - AND - channel='.$this->db->makeSafe($channelID).';'; - - // Create a new SQL query: - $result = $this->db->sqlQuery($sql); - - // Stop if an error occurs: - if($result->error()) { - echo $result->getError(); - die(); - } - } - - function getUserID() { - return $this->getSessionVar('UserID'); - } - - function setUserID($id) { - $this->setSessionVar('UserID', $id); - } - - function getUserName() { - return $this->getSessionVar('UserName'); - } - - function setUserName($name) { - $this->setSessionVar('UserName', $name); - } - - function getLoginUserName() { - return $this->getSessionVar('LoginUserName'); - } - - function setLoginUserName($name) { - $this->setSessionVar('LoginUserName', $name); - } - - function getUserRole() { - $userRole = $this->getSessionVar('UserRole'); - if($userRole === null) - return AJAX_CHAT_GUEST; - return $userRole; - } - - function setUserRole($role) { - $this->setSessionVar('UserRole', $role); - } - - function getChannel() { - return $this->getSessionVar('Channel'); - } - - function setChannel($channel) { - $this->setSessionVar('Channel', $channel); - - // Save the channel enter timestamp: - $this->setChannelEnterTimeStamp(time()); - - // Update the channel authentication for the socket server: - if($this->getConfig('socketServerEnabled')) { - $this->updateSocketAuthentication( - $this->getUserID(), - $this->getSocketRegistrationID(), - array($channel,$this->getPrivateMessageID()) - ); - } - - // Reset the logs view socket authentication session var: - if($this->getSessionVar('logsViewSocketAuthenticated')) { - $this->setSessionVar('logsViewSocketAuthenticated', false); - } - } - - function isLoggedIn() { - return (bool)$this->getSessionVar('LoggedIn'); - } - - function setLoggedIn($bool) { - $this->setSessionVar('LoggedIn', $bool); - } - - function getLoginTimeStamp() { - return $this->getSessionVar('LoginTimeStamp'); - } - - function setLoginTimeStamp($time) { - $this->setSessionVar('LoginTimeStamp', $time); - } - - function getChannelEnterTimeStamp() { - return $this->getSessionVar('ChannelEnterTimeStamp'); - } - - function setChannelEnterTimeStamp($time) { - $this->setSessionVar('ChannelEnterTimeStamp', $time); - } - - function getStatusUpdateTimeStamp() { - return $this->getSessionVar('StatusUpdateTimeStamp'); - } - - function setStatusUpdateTimeStamp($time) { - $this->setSessionVar('StatusUpdateTimeStamp', $time); - } - - function getInactiveCheckTimeStamp() { - return $this->getSessionVar('InactiveCheckTimeStamp'); - } - - function setInactiveCheckTimeStamp($time) { - $this->setSessionVar('InactiveCheckTimeStamp', $time); - } - - function getInsertedMessagesRate() { - return $this->getSessionVar('InsertedMessagesRate'); - } - - function setInsertedMessagesRate($rate) { - $this->setSessionVar('InsertedMessagesRate', $rate); - } - - function getInsertedMessagesRateTimeStamp() { - return $this->getSessionVar('InsertedMessagesRateTimeStamp'); - } - - function setInsertedMessagesRateTimeStamp($time) { - $this->setSessionVar('InsertedMessagesRateTimeStamp', $time); - } - - function getLangCode() { - // Get the langCode from request or cookie: - $langCodeCookie = isset($_COOKIE[$this->getConfig('sessionName').'_lang']) ? $_COOKIE[$this->getConfig('sessionName').'_lang'] : null; - $langCode = $this->getRequestVar('lang') ? $this->getRequestVar('lang') : $langCodeCookie; - // Check if the langCode is valid: - if(!in_array($langCode, $this->getConfig('langAvailable'))) { - // Determine the user language: - $language = new AJAXChatLanguage($this->getConfig('langAvailable'), $this->getConfig('langDefault')); - $langCode = $language->getLangCode(); - } - return $langCode; - } - - function setLangCodeCookie() { - setcookie( - $this->getConfig('sessionName').'_lang', - $this->getLangCode(), - time()+60*60*24*$this->getConfig('sessionCookieLifeTime'), - $this->getConfig('sessionCookiePath'), - $this->getConfig('sessionCookieDomain'), - $this->getConfig('sessionCookieSecure') - ); - } - - function removeUnsafeCharacters($str) { - // Remove NO-WS-CTL, non-whitespace control characters (RFC 2822), decimal 1–8, 11–12, 14–31, and 127: - return AJAXChatEncoding::removeUnsafeCharacters($str); - } - - function subString($str, $start=0, $length=null, $encoding='UTF-8') { - return AJAXChatString::subString($str, $start, $length, $encoding); - } - - function stringLength($str, $encoding='UTF-8') { - return AJAXChatString::stringLength($str, $encoding); - } - - function trimMessageText($text) { - return $this->trimString($text, 'UTF-8', $this->getConfig('messageTextMaxLength')); - } - - function trimUserName($userName) { - return $this->trimString($userName, null, $this->getConfig('userNameMaxLength'), true, true); - } - - function trimChannelName($channelName) { - return $this->trimString($channelName, null, null, true, true); - } - - function trimString($str, $sourceEncoding=null, $maxLength=null, $replaceWhitespace=false, $decodeEntities=false, $htmlEntitiesMap=null) { - // Make sure the string contains valid unicode: - $str = $this->convertToUnicode($str, $sourceEncoding); - - // Make sure the string contains no unsafe characters: - $str = $this->removeUnsafeCharacters($str); - - // Strip whitespace from the beginning and end of the string: - $str = trim($str); - - if($replaceWhitespace) { - // Replace any whitespace in the userName with the underscore "_": - $str = preg_replace('/\s/u', '_', $str); - } - - if($decodeEntities) { - // Decode entities: - $str = $this->decodeEntities($str, 'UTF-8', $htmlEntitiesMap); - } - - if($maxLength) { - // Cut the string to the allowed length: - $str = $this->subString($str, 0, $maxLength); - } - - return $str; - } - - function convertToUnicode($str, $sourceEncoding=null) { - if($sourceEncoding === null) { - $sourceEncoding = $this->getConfig('sourceEncoding'); - } - return $this->convertEncoding($str, $sourceEncoding, 'UTF-8'); - } - - function convertFromUnicode($str, $contentEncoding=null) { - if($contentEncoding === null) { - $contentEncoding = $this->getConfig('contentEncoding'); - } - return $this->convertEncoding($str, 'UTF-8', $contentEncoding); - } - - function convertEncoding($str, $charsetFrom, $charsetTo) { - return AJAXChatEncoding::convertEncoding($str, $charsetFrom, $charsetTo); - } - - function encodeEntities($str, $encoding='UTF-8', $convmap=null) { - return AJAXChatEncoding::encodeEntities($str, $encoding, $convmap); - } - - function decodeEntities($str, $encoding='UTF-8', $htmlEntitiesMap=null) { - return AJAXChatEncoding::decodeEntities($str, $encoding, $htmlEntitiesMap); - } - - function htmlEncode($str) { - return AJAXChatEncoding::htmlEncode($str, $this->getConfig('contentEncoding')); - } - - function encodeSpecialChars($str) { - return AJAXChatEncoding::encodeSpecialChars($str); - } - - function decodeSpecialChars($str) { - return AJAXChatEncoding::decodeSpecialChars($str); - } - - function ipToStorageFormat($ip) { - if(function_exists('inet_pton')) { - // ipv4 & ipv6: - return @inet_pton($ip); - } - // Only ipv4: - return @pack('N',@ip2long($ip)); - } - - function ipFromStorageFormat($ip) { - if(function_exists('inet_ntop')) { - // ipv4 & ipv6: - return @inet_ntop($ip); - } - // Only ipv4: - $unpacked = @unpack('Nlong',$ip); - if(isset($unpacked['long'])) { - return @long2ip($unpacked['long']); - } - return null; - } - - function getConfig($key, $subkey=null) { - if($subkey) - return $this->_config[$key][$subkey]; - else - return $this->_config[$key]; - } - - function setConfig($key, $subkey, $value) { - if($subkey) { - if(!isset($this->_config[$key])) { - $this->_config[$key] = array(); - } - $this->_config[$key][$subkey] = $value; - } else { - $this->_config[$key] = $value; - } - } - - function getLang($key=null) { - if(!$this->_lang) { - // Include the language file: - $lang = null; - require(AJAX_CHAT_PATH.'lib/lang/'.$this->getLangCode().'.php'); - $this->_lang = &$lang; - } - if($key === null) - return $this->_lang; - if(isset($this->_lang[$key])) - return $this->_lang[$key]; - return null; - } - - function getChatURL() { - if(defined('AJAX_CHAT_URL')) { - return AJAX_CHAT_URL; - } - - return - (isset($_SERVER['HTTPS']) ? 'https://' : 'http://'). - (isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : ''). - (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME']. - (isset($_SERVER['HTTPS']) && $_SERVER['SERVER_PORT'] == 443 || $_SERVER['SERVER_PORT'] == 80 ? '' : ':'.$_SERVER['SERVER_PORT']))). - substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/')+1); - } - - function getIDFromName($userName) { - $userDataArray = $this->getOnlineUsersData(null,'userName',$userName); - if($userDataArray && isset($userDataArray[0])) { - return $userDataArray[0]['userID']; - } - return null; - } - - function getNameFromID($userID) { - $userDataArray = $this->getOnlineUsersData(null,'userID',$userID); - if($userDataArray && isset($userDataArray[0])) { - return $userDataArray[0]['userName']; - } - return null; - } - - function getChannelFromID($userID) { - $userDataArray = $this->getOnlineUsersData(null,'userID',$userID); - if($userDataArray && isset($userDataArray[0])) { - return $userDataArray[0]['channel']; - } - return null; - } - - function getIPFromID($userID) { - $userDataArray = $this->getOnlineUsersData(null,'userID',$userID); - if($userDataArray && isset($userDataArray[0])) { - return $userDataArray[0]['ip']; - } - return null; - } - - function getRoleFromID($userID) { - $userDataArray = $this->getOnlineUsersData(null,'userID',$userID); - if($userDataArray && isset($userDataArray[0])) { - return $userDataArray[0]['userRole']; - } - return null; - } - - function getChannelNames() { - return array_flip($this->getChannels()); - } - - function getChannelIDFromChannelName($channelName) { - if(!$channelName) - return null; - $channels = $this->getAllChannels(); - if(array_key_exists($channelName,$channels)) { - return $channels[$channelName]; - } - $channelID = null; - // Check if the requested channel is the own private channel: - if($channelName == $this->getPrivateChannelName()) { - return $this->getPrivateChannelID(); - } - // Try to retrieve a private room ID: - $strlenChannelName = $this->stringLength($channelName); - $strlenPrefix = $this->stringLength($this->getConfig('privateChannelPrefix')); - $strlenSuffix = $this->stringLength($this->getConfig('privateChannelSuffix')); - if($this->subString($channelName,0,$strlenPrefix) == $this->getConfig('privateChannelPrefix') - && $this->subString($channelName,$strlenChannelName-$strlenSuffix) == $this->getConfig('privateChannelSuffix')) { - $userName = $this->subString( - $channelName, - $strlenPrefix, - $strlenChannelName-($strlenPrefix+$strlenSuffix) - ); - $userID = $this->getIDFromName($userName); - if($userID !== null) { - $channelID = $this->getPrivateChannelID($userID); - } - } - return $channelID; - } - - function getChannelNameFromChannelID($channelID) { - foreach($this->getAllChannels() as $key=>$value) { - if($value == $channelID) { - return $key; - } - } - // Try to retrieve a private room name: - if($channelID == $this->getPrivateChannelID()) { - return $this->getPrivateChannelName(); - } - $userName = $this->getNameFromID($channelID-$this->getConfig('privateChannelDiff')); - if($userName === null) { - return null; - } - return $this->getPrivateChannelName($userName); - } - - function getChannelName() { - return $this->getChannelNameFromChannelID($this->getChannel()); - } - - function getPrivateChannelName($userName=null) { - if($userName === null) { - $userName = $this->getUserName(); - } - return $this->getConfig('privateChannelPrefix').$userName.$this->getConfig('privateChannelSuffix'); - } - - function getPrivateChannelID($userID=null) { - if($userID === null) { - $userID = $this->getUserID(); - } - return $userID + $this->getConfig('privateChannelDiff'); - } - - function getPrivateMessageID($userID=null) { - if($userID === null) { - $userID = $this->getUserID(); - } - return $userID + $this->getConfig('privateMessageDiff'); - } - - function isAllowedToSendPrivateMessage() { - if($this->getConfig('allowPrivateMessages') || $this->getUserRole() == AJAX_CHAT_ADMIN) { - return true; - } - return false; - } - - function isAllowedToCreatePrivateChannel() { - if($this->getConfig('allowPrivateChannels')) { - switch($this->getUserRole()) { - case DONATOR: - return true; - case BOTS: - return true; - case PURPLE: - return true; - case CMOD: - return true; - case AJAX_CHAT_MODERATOR: - return true; - case AJAX_CHAT_ADMIN: - return true; - default: - return false; - } - } - return false; - } - - function isAllowedToListHiddenUsers() { - // Hidden users are users within private or restricted channels: - switch($this->getUserRole()) { - case CMOD: - return true; - case PURPLE: - return true; - case AJAX_CHAT_MODERATOR: - return true; - case AJAX_CHAT_ADMIN: - return true; - default: - return false; - } - } - - function isUserOnline($userID=null) { - $userID = ($userID === null) ? $this->getUserID() : $userID; - $userDataArray = $this->getOnlineUsersData(null,'userID',$userID); - if($userDataArray && count($userDataArray) > 0) { - return true; - } - return false; - } - - function isUserNameInUse($userName=null) { - $userName = ($userName === null) ? $this->getUserName() : $userName; - $userDataArray = $this->getOnlineUsersData(null,'userName',$userName); - if($userDataArray && count($userDataArray) > 0) { - return true; - } - return false; - } - - function isUserBanned($userName, $userID=null, $ip=null) { - if($userID !== null) { - $bannedUserDataArray = $this->getBannedUsersData('userID',$userID); - if($bannedUserDataArray && isset($bannedUserDataArray[0])) { - return true; - } - } - if($ip !== null) { - $bannedUserDataArray = $this->getBannedUsersData('ip',$ip); - if($bannedUserDataArray && isset($bannedUserDataArray[0])) { - return true; - } - } - $bannedUserDataArray = $this->getBannedUsersData('userName',$userName); - if($bannedUserDataArray && isset($bannedUserDataArray[0])) { - return true; - } - return false; - } - - function isMaxUsersLoggedIn() { - if(count($this->getOnlineUsersData()) >= $this->getConfig('maxUsersLoggedIn')) { - return true; - } - return false; - } - - function validateChannel($channelID) { - if($channelID === null) { - return false; - } - // Return true for normal channels the user has acces to: - if(in_array($channelID, $this->getChannels())) { - return true; - } - // Return true if the user is allowed to join his own private channel: - if($channelID == $this->getPrivateChannelID() && $this->isAllowedToCreatePrivateChannel()) { - return true; - } - // Return true if the user has been invited to a restricted or private channel: - if(in_array($channelID, $this->getInvitations())) { - return true; - } - // No valid channel, return false: - return false; - } - - function createGuestUserName() { - $maxLength = $this->getConfig('userNameMaxLength') - - $this->stringLength($this->getConfig('guestUserPrefix')) - - $this->stringLength($this->getConfig('guestUserSuffix')); - - // seed with microseconds since last "whole" second: - mt_srand((double)microtime()*1000000); - - // Create a random userName using numbers between 100000 and 999999: - $userName = substr(mt_rand(100000, 999999), 0, $maxLength); - - return $this->getConfig('guestUserPrefix').$userName.$this->getConfig('guestUserSuffix'); - } - - // Guest userIDs must not interfere with existing userIDs and must be lower than privateChannelDiff: - function createGuestUserID() { - // seed with microseconds since last "whole" second: - mt_srand((double)microtime()*1000000); - - return mt_rand($this->getConfig('minGuestUserID'), $this->getConfig('privateChannelDiff')-1); - } - - function getGuestUser() { - if(!$this->getConfig('allowGuestLogins')) - return null; - - if($this->getConfig('allowGuestUserName')) { - $maxLength = $this->getConfig('userNameMaxLength') - - $this->stringLength($this->getConfig('guestUserPrefix')) - - $this->stringLength($this->getConfig('guestUserSuffix')); - - // Trim guest userName: - $userName = $this->trimString($this->getRequestVar('userName'), null, $maxLength, true, true); - - // If given userName is invalid, create one: - if(!$userName) { - $userName = $this->createGuestUserName(); - } else { - // Add the guest users prefix and suffix to the given userName: - $userName = $this->getConfig('guestUserPrefix').$userName.$this->getConfig('guestUserSuffix'); - } - } else { - $userName = $this->createGuestUserName(); - } - - $userData = array(); - $userData['userID'] = $this->createGuestUserID(); - $userData['userName'] = $userName; - $userData['userRole'] = AJAX_CHAT_GUEST; - return $userData; - } - - function getCustomVar($key) { - if(!isset($this->_customVars)) - $this->_customVars = array(); - if(!isset($this->_customVars[$key])) - return null; - return $this->_customVars[$key]; - } - - function setCustomVar($key, $value) { - if(!isset($this->_customVars)) - $this->_customVars = array(); - $this->_customVars[$key] = $value; - } - - // Override to replace custom template tags: - // Return the replacement for the given tag (and given tagContent) - function replaceCustomTemplateTags($tag, $tagContent) { - return null; - } - - // Override to initialize custom configuration settings: - function initCustomConfig() { - } - - // Override to add custom request variables: - // Add values to the request variables array: $this->_requestVars['customVariable'] = null; - function initCustomRequestVars() { - } - - // Override to add custom session code right after the session has been started: - function initCustomSession() { - } - - // Override, to parse custom info requests: - // $infoRequest contains the current info request - // Add info responses using the method addInfoMessage($info, $type) - function parseCustomInfoRequest($infoRequest) { - } - - // Override to replace custom text: - // Return replaced text - // $text contains the whole message - function replaceCustomText(&$text) { - return $text; - } - - // Override to add custom commands: - // Return true if a custom command has been successfully parsed, else false - // $text contains the whole message, $textParts the message split up as words array - function parseCustomCommands($text, $textParts) { - return false; - } - - // Override to perform custom actions on new messages: - // Return true if message may be inserted, else false - // $text contains the whole message - function onNewMessage($text) { - return true; - } - - // Override to perform custom actions on new messages: - // Method to set the style cookie depending on user data - function setStyle() { - } - - // Override: - // Returns true if the userID of the logged in user is identical to the userID of the authentication system - // or the user is authenticated as guest in the chat and the authentication system - function revalidateUserID() { - return true; - } - - // Override: - // Returns an associative array containing userName, userID and userRole - // Returns null if login is invalid - function getValidLoginUserData() { - // Check if we have a valid registered user: - if(false) { - // Here is the place to check user authentication - } else { - // Guest users: - return $this->getGuestUser(); - } - } - - // Override: - // Store the channels the current user has access to - // Make sure channel names don't contain any whitespace - function &getChannels() { - if($this->_channels === null) { - $this->_channels = $this->getAllChannels(); - } - return $this->_channels; - } - - // Override: - // Store all existing channels - // Make sure channel names don't contain any whitespace - function &getAllChannels() { - if($this->_allChannels === null) { - $this->_allChannels = array(); - - // Default channel, public to everyone: - $this->_allChannels[$this->trimChannelName($this->getConfig('defaultChannelName'))] = $this->getConfig('defaultChannelID'); - } - return $this->_allChannels; - } - -} diff --git a/public/lib/class/AJAXChatDataBase.php b/public/lib/class/AJAXChatDataBase.php deleted file mode 100644 index e4d4024..0000000 --- a/public/lib/class/AJAXChatDataBase.php +++ /dev/null @@ -1,81 +0,0 @@ -_db = new AJAXChatDatabaseMySQLi($dbConnectionConfig); - break; - case 'mysql': - $this->_db = new AJAXChatDatabaseMySQL($dbConnectionConfig); - break; - default: - // Use MySQLi if available, else MySQL (and check the type of a given database connection object): - if(function_exists('mysqli_connect') && (!$dbConnectionConfig['link'] || is_object($dbConnectionConfig['link']))) { - $this->_db = new AJAXChatDatabaseMySQLi($dbConnectionConfig); - } else { - $this->_db = new AJAXChatDatabaseMySQL($dbConnectionConfig); - } - } - } - - // Method to connect to the DataBase server: - function connect(&$dbConnectionConfig) { - return $this->_db->connect($dbConnectionConfig); - } - - // Method to select the DataBase: - function select($dbName) { - return $this->_db->select($dbName); - } - - // Method to determine if an error has occured: - function error() { - return $this->_db->error(); - } - - // Method to return the error report: - function getError() { - return $this->_db->getError(); - } - - // Method to return the connection identifier: - function &getConnectionID() { - return $this->_db->getConnectionID(); - } - - // Method to prevent SQL injections: - function makeSafe($value) { - return $this->_db->makeSafe($value); - } - - // Method to perform SQL queries: - function sqlQuery($sql) { - return $this->_db->sqlQuery($sql); - } - - // Method to retrieve the current DataBase name: - function getName() { - return $this->_db->getName(); - //If your database has hyphens ( - ) in it, try using this instead: - //return '`'.$this->_db->getName().'`'; - } - - // Method to retrieve the last inserted ID: - function getLastInsertedID() { - return $this->_db->getLastInsertedID(); - } - -} -?> \ No newline at end of file diff --git a/public/lib/class/AJAXChatEncoding.php b/public/lib/class/AJAXChatEncoding.php deleted file mode 100644 index 0707120..0000000 --- a/public/lib/class/AJAXChatEncoding.php +++ /dev/null @@ -1,138 +0,0 @@ -'&', '<'=>'<', '>'=>'>', "'"=>''', '"'=>'"'); - } - return $specialChars; - } - - // Helper function to store Regular expression for NO-WS-CTL as we cannot use static class members in PHP4: - public static function getRegExp_NO_WS_CTL() { - static $regExp_NO_WS_CTL; - if(!$regExp_NO_WS_CTL) { - // Regular expression for NO-WS-CTL, non-whitespace control characters (RFC 2822), decimal 1–8, 11–12, 14–31, and 127: - $regExp_NO_WS_CTL = '/[\x0\x1\x2\x3\x4\x5\x6\x7\x8\xB\xC\xE\xF\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F]/'; - } - return $regExp_NO_WS_CTL; - } - - public static function convertEncoding($str, $charsetFrom, $charsetTo) { - if(function_exists('mb_convert_encoding')) { - return mb_convert_encoding($str, $charsetTo, $charsetFrom); - } - if(function_exists('iconv')) { - return iconv($charsetFrom, $charsetTo, $str); - } - if(($charsetFrom == 'UTF-8') && ($charsetTo == 'ISO-8859-1')) { - return utf8_decode($str); - } - if(($charsetFrom == 'ISO-8859-1') && ($charsetTo == 'UTF-8')) { - return utf8_encode($str); - } - return $str; - } - - public static function htmlEncode($str, $contentCharset='UTF-8') { - switch($contentCharset) { - case 'UTF-8': - // Encode only special chars (&, <, >, ', ") as entities: - return AJAXChatEncoding::encodeSpecialChars($str); - break; - case 'ISO-8859-1': - case 'ISO-8859-15': - // Encode special chars and all extended characters above ISO-8859-1 charset as entities, then convert to content charset: - return AJAXChatEncoding::convertEncoding(AJAXChatEncoding::encodeEntities($str, 'UTF-8', array( - 0x26, 0x26, 0, 0xFFFF, // & - 0x3C, 0x3C, 0, 0xFFFF, // < - 0x3E, 0x3E, 0, 0xFFFF, // > - 0x27, 0x27, 0, 0xFFFF, // ' - 0x22, 0x22, 0, 0xFFFF, // " - 0x100, 0x2FFFF, 0, 0xFFFF // above ISO-8859-1 - )), 'UTF-8', $contentCharset); - break; - default: - // Encode special chars and all characters above ASCII charset as entities, then convert to content charset: - return AJAXChatEncoding::convertEncoding(AJAXChatEncoding::encodeEntities($str, 'UTF-8', array( - 0x26, 0x26, 0, 0xFFFF, // & - 0x3C, 0x3C, 0, 0xFFFF, // < - 0x3E, 0x3E, 0, 0xFFFF, // > - 0x27, 0x27, 0, 0xFFFF, // ' - 0x22, 0x22, 0, 0xFFFF, // " - 0x80, 0x2FFFF, 0, 0xFFFF // above ASCII - )), 'UTF-8', $contentCharset); - } - } - - public static function encodeSpecialChars($str) { - return strtr($str, AJAXChatEncoding::getSpecialChars()); - } - - public static function decodeSpecialChars($str) { - return strtr($str, array_flip(AJAXChatEncoding::getSpecialChars())); - } - - public static function encodeEntities($str, $encoding='UTF-8', $convmap=null) { - if($convmap && function_exists('mb_encode_numericentity')) { - return mb_encode_numericentity($str, $convmap, $encoding); - } - return htmlentities($str, ENT_QUOTES, $encoding); - } - - public static function decodeEntities($str, $encoding='UTF-8', $htmlEntitiesMap=null) { - // Due to PHP bug #25670, html_entity_decode does not work with UTF-8 for PHP versions < 5: - if(function_exists('html_entity_decode') && version_compare(phpversion(), 5, '>=')) { - // Replace numeric and literal entities: - $str = html_entity_decode($str, ENT_QUOTES, $encoding); - // Replace additional literal HTML entities if an HTML entities map is given: - if($htmlEntitiesMap) { - $str = strtr($str, $htmlEntitiesMap); - } - } else { - // Replace numeric entities: - $str = preg_replace('~&#([0-9]+);~e', 'AJAXChatEncoding::unicodeChar("\\1")', $str); - $str = preg_replace('~&#x([0-9a-f]+);~ei', 'AJAXChatEncoding::unicodeChar(hexdec("\\1"))', $str); - // Replace literal entities: - $htmlEntitiesMap = $htmlEntitiesMap ? $htmlEntitiesMap : array_flip(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES)); - $str = strtr($str, $htmlEntitiesMap); - } - return $str; - } - - public static function unicodeChar($c) { - if($c <= 0x7F) { - return chr($c); - } else if($c <= 0x7FF) { - return chr(0xC0 | $c >> 6) . chr(0x80 | $c & 0x3F); - } else if($c <= 0xFFFF) { - return chr(0xE0 | $c >> 12) . chr(0x80 | $c >> 6 & 0x3F) - . chr(0x80 | $c & 0x3F); - } else if($c <= 0x10FFFF) { - return chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F) - . chr(0x80 | $c >> 6 & 0x3F) - . chr(0x80 | $c & 0x3F); - } else { - return null; - } - } - - public static function removeUnsafeCharacters($str) { - // Remove NO-WS-CTL, non-whitespace control characters (RFC 2822), decimal 1–8, 11–12, 14–31, and 127: - return preg_replace(AJAXChatEncoding::getRegExp_NO_WS_CTL(), '', $str); - } - -} -?> \ No newline at end of file diff --git a/public/lib/class/AJAXChatHTTPHeader.php b/public/lib/class/AJAXChatHTTPHeader.php deleted file mode 100644 index f97a8d8..0000000 --- a/public/lib/class/AJAXChatHTTPHeader.php +++ /dev/null @@ -1,56 +0,0 @@ -_contentType = $contentType.'; charset='.$encoding; - $this->_constant = true; - } else { - if(isset($_SERVER['HTTP_ACCEPT']) && (strpos($_SERVER['HTTP_ACCEPT'],'application/xhtml+xml') !== false)) { - $this->_contentType = 'application/xhtml+xml; charset='.$encoding; - } else { - $this->_contentType = 'text/html; charset='.$encoding; - } - $this->_constant = false; - } - $this->_noCache = $noCache; - } - - // Method to send the HTTP header: - function send() { - // Prevent caching: - if($this->_noCache) { - header('Cache-Control: no-cache, must-revalidate'); - header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); - } - - // Send the content-type-header: - header('Content-Type: '.$this->_contentType); - - // Send vary header if content-type varies (important for proxy-caches): - if(!$this->_constant) { - header('Vary: Accept'); - } - } - - // Method to return the content-type string: - function getContentType() { - // Return the content-type string: - return $this->_contentType; - } - -} -?> \ No newline at end of file diff --git a/public/lib/class/AJAXChatLanguage.php b/public/lib/class/AJAXChatLanguage.php deleted file mode 100644 index 70c3513..0000000 --- a/public/lib/class/AJAXChatLanguage.php +++ /dev/null @@ -1,102 +0,0 @@ -_regExpAcceptLangCode = '/^([a-z]{1,8}(?:-[a-z]{1,8})*)(?:;\s*q=(0(?:\.[0-9]{1,3})?|1(?:\.0{1,3})?))?$/i'; - $this->_availableLangCodes = $availableLangCodes; - $this->_defaultLangCode = $defaultLangCode; - if($langCode && in_array($langCode, $availableLangCodes)) { - $this->_langCode = $langCode; - } - $this->_strictMode = $strictMode; - } - - // Method to detect the language code from the HTTP_ACCEPT_LANGUAGE header: - function detectLangCode() { - // If HTTP_ACCEPT_LANGUAGE is empty use defaultLangCode: - if(empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { - $this->_langCode = $this->_defaultLangCode; - return; - } - - // Split up the HTTP_ACCEPT_LANGUAGE header: - $acceptedLanguages = preg_split('/,\s*/', $_SERVER['HTTP_ACCEPT_LANGUAGE']); - - $currentLangCode = $this->_defaultLangCode; - $currentLangQuality = 0.0; - - foreach($acceptedLanguages as $acceptedLanguage) { - // Parse the language string: - $match = preg_match($this->_regExpAcceptLangCode, $acceptedLanguage, $matches); - // Check if the syntax is valid: - if(!$match) { - continue; - } - - // Get and split the language code: - $langCodeParts = explode ('-', $matches[1]); - - // Get the language quality given as float value: - if(isset($matches[2])) { - $langQuality = (float)$matches[2]; - } else { - // Missing language quality value is maximum quality: - $langQuality = 1.0; - } - - // Go through it until the language code is empty: - while(count($langCodeParts)) { - // Join the current langCodeParts: - $langCode = strtolower(join('-', $langCodeParts)); - // Check if the langCode is in the available list: - if(in_array($langCode, $this->_availableLangCodes)) { - // Check the quality setting: - if ($langQuality > $currentLangQuality) { - $currentLangCode = $langCode; - $currentLangQuality = $langQuality; - break; - } - } - // If strict mode is set, don't minimalize the language code: - if($this->_strictMode) { - break; - } - // else chop off the right part: - array_pop($langCodeParts); - } - } - - $this->_langCode = $currentLangCode; - } - - function getLangCode() { - if(!$this->_langCode) { - $this->detectLangCode(); - } - return $this->_langCode; - } - - function setLangCode($langCode) { - $this->_langCode = $langCode; - } - - function getLangCodes() { - return $this->_availableLangCodes; - } - -} -?> \ No newline at end of file diff --git a/public/lib/class/AJAXChatMySQLDataBase.php b/public/lib/class/AJAXChatMySQLDataBase.php deleted file mode 100644 index e6f0c7b..0000000 --- a/public/lib/class/AJAXChatMySQLDataBase.php +++ /dev/null @@ -1,92 +0,0 @@ -_connectionID = $dbConnectionConfig['link']; - $this->_dbName = $dbConnectionConfig['name']; - } - - // Method to connect to the DataBase server: - function connect(&$dbConnectionConfig) { - $this->_connectionID = @mysql_connect( - $dbConnectionConfig['host'], - $dbConnectionConfig['user'], - $dbConnectionConfig['pass'], - true - ); - if(!$this->_connectionID) { - $this->_errno = null; - $this->_error = 'Database connection failed.'; - return false; - } - return true; - } - - // Method to select the DataBase: - function select($dbName) { - if(!@mysql_select_db($dbName, $this->_connectionID)) { - $this->_errno = mysql_errno($this->_connectionID); - $this->_error = mysql_error($this->_connectionID); - return false; - } - $this->_dbName = $dbName; - return true; - } - - // Method to determine if an error has occured: - function error() { - return (bool)$this->_error; - } - - // Method to return the error report: - function getError() { - if($this->error()) { - $str = 'Error-Report: ' .$this->_error."\n"; - $str .= 'Error-Code: '.$this->_errno."\n"; - } else { - $str = 'No errors.'."\n"; - } - return $str; - } - - // Method to return the connection identifier: - function &getConnectionID() { - return $this->_connectionID; - } - - // Method to prevent SQL injections: - function makeSafe($value) { - return "'".mysql_real_escape_string($value, $this->_connectionID)."'"; - } - - // Method to perform SQL queries: - function sqlQuery($sql) { - return new AJAXChatMySQLQuery($sql, $this->_connectionID); - } - - // Method to retrieve the current DataBase name: - function getName() { - return $this->_dbName; - } - - // Method to retrieve the last inserted ID: - function getLastInsertedID() { - return mysql_insert_id($this->_connectionID); - } - -} -?> \ No newline at end of file diff --git a/public/lib/class/AJAXChatMySQLQuery.php b/public/lib/class/AJAXChatMySQLQuery.php deleted file mode 100644 index 5c8f715..0000000 --- a/public/lib/class/AJAXChatMySQLQuery.php +++ /dev/null @@ -1,89 +0,0 @@ -_sql = trim($sql); - $this->_connectionID = $connectionID; - if($this->_connectionID) { - $this->_result = mysql_query($this->_sql, $this->_connectionID); - if(!$this->_result) { - $this->_errno = mysql_errno($this->_connectionID); - $this->_error = mysql_error($this->_connectionID); - } - } else { - $this->_result = mysql_query($this->_sql); - if(!$this->_result) { - $this->_errno = mysql_errno(); - $this->_error = mysql_error(); - } - } - } - - // Returns true if an error occured: - function error() { - // Returns true if the Result-ID is valid: - return !(bool)($this->_result); - } - - // Returns an Error-String: - function getError() { - if($this->error()) { - $str = 'Query: ' .$this->_sql ."\n"; - $str .= 'Error-Report: ' .$this->_error."\n"; - $str .= 'Error-Code: '.$this->_errno; - } else { - $str = "No errors."; - } - return $str; - } - - // Returns the content: - function fetch() { - if($this->error()) { - return null; - } else { - return mysql_fetch_assoc($this->_result); - } - } - - // Returns the number of rows (SELECT or SHOW): - function numRows() { - if($this->error()) { - return null; - } else { - return mysql_num_rows($this->_result); - } - } - - // Returns the number of affected rows (INSERT, UPDATE, REPLACE or DELETE): - function affectedRows() { - if($this->error()) { - return null; - } else { - return mysql_affected_rows($this->_connectionID); - } - } - - // Frees the memory: - function free() { - @mysql_free_result($this->_result); - } - -} -?> \ No newline at end of file diff --git a/public/lib/class/AJAXChatMySQLiDataBase.php b/public/lib/class/AJAXChatMySQLiDataBase.php deleted file mode 100644 index 6b7c6d5..0000000 --- a/public/lib/class/AJAXChatMySQLiDataBase.php +++ /dev/null @@ -1,91 +0,0 @@ -_connectionID = $dbConnectionConfig['link']; - $this->_dbName = $dbConnectionConfig['name']; - } - - // Method to connect to the DataBase server: - function connect(&$dbConnectionConfig) { - $this->_connectionID = new mysqli( - $dbConnectionConfig['host'], - $dbConnectionConfig['user'], - $dbConnectionConfig['pass'] - ); - if(!$this->_connectionID) { - $this->_errno = mysqli_connect_errno(); - $this->_error = mysqli_connect_error(); - return false; - } - return true; - } - - // Method to select the DataBase: - function select($dbName) { - if(!$this->_connectionID->select_db($dbName)) { - $this->_errno = $this->_connectionID->errno; - $this->_error = $this->_connectionID->error; - return false; - } - $this->_dbName = $dbName; - return true; - } - - // Method to determine if an error has occured: - function error() { - return (bool)$this->_error; - } - - // Method to return the error report: - function getError() { - if($this->error()) { - $str = 'Error-Report: ' .$this->_error."\n"; - $str .= 'Error-Code: '.$this->_errno."\n"; - } else { - $str = 'No errors.'."\n"; - } - return $str; - } - - // Method to return the connection identifier: - function &getConnectionID() { - return $this->_connectionID; - } - - // Method to prevent SQL injections: - function makeSafe($value) { - return "'".$this->_connectionID->escape_string($value)."'"; - } - - // Method to perform SQL queries: - function sqlQuery($sql) { - return new AJAXChatMySQLiQuery($sql, $this->_connectionID); - } - - // Method to retrieve the current DataBase name: - function getName() { - return $this->_dbName; - } - - // Method to retrieve the last inserted ID: - function getLastInsertedID() { - return $this->_connectionID->insert_id; - } - -} -?> \ No newline at end of file diff --git a/public/lib/class/AJAXChatMySQLiQuery.php b/public/lib/class/AJAXChatMySQLiQuery.php deleted file mode 100644 index cbce97e..0000000 --- a/public/lib/class/AJAXChatMySQLiQuery.php +++ /dev/null @@ -1,81 +0,0 @@ -_sql = trim($sql); - $this->_connectionID = $connectionID; - $this->_result = $this->_connectionID->query($this->_sql); - if(!$this->_result) { - $this->_errno = $this->_connectionID->errno; - $this->_error = $this->_connectionID->error; - } - } - - // Returns true if an error occured: - function error() { - // Returns true if the Result-ID is valid: - return !(bool)($this->_result); - } - - // Returns an Error-String: - function getError() { - if($this->error()) { - $str = 'Query: ' .$this->_sql ."\n"; - $str .= 'Error-Report: ' .$this->_error."\n"; - $str .= 'Error-Code: '.$this->_errno; - } else { - $str = "No errors."; - } - return $str; - } - - // Returns the content: - function fetch() { - if($this->error()) { - return null; - } else { - return $this->_result->fetch_assoc(); - } - } - - // Returns the number of rows (SELECT or SHOW): - function numRows() { - if($this->error()) { - return null; - } else { - return $this->_result->num_rows; - } - } - - // Returns the number of affected rows (INSERT, UPDATE, REPLACE or DELETE): - function affectedRows() { - if($this->error()) { - return null; - } else { - return $this->_connectionID->affected_rows; - } - } - - // Frees the memory: - function free() { - $this->_result->free(); - } - -} -?> \ No newline at end of file diff --git a/public/lib/class/AJAXChatString.php b/public/lib/class/AJAXChatString.php deleted file mode 100644 index 606240a..0000000 --- a/public/lib/class/AJAXChatString.php +++ /dev/null @@ -1,37 +0,0 @@ - \ No newline at end of file diff --git a/public/lib/class/AJAXChatTemplate.php b/public/lib/class/AJAXChatTemplate.php deleted file mode 100644 index 1ec0841..0000000 --- a/public/lib/class/AJAXChatTemplate.php +++ /dev/null @@ -1,359 +0,0 @@ -ajaxChat = $ajaxChat; - $this->_regExpTemplateTags = '/\[(\w+?)(?:(?:\/)|(?:\](.+?)\[\/\1))\]/s'; - $this->_templateFile = $templateFile; - $this->_contentType = $contentType; - } - - function getParsedContent() { - if(!$this->_parsedContent) { - $this->parseContent(); - } - return $this->_parsedContent; - } - - function getContent() { - if(!$this->_content) { - $this->_content = AJAXChatFileSystem::getFileContents($this->_templateFile); - } - return $this->_content; - } - - function parseContent() { - $this->_parsedContent = $this->getContent(); - - // Remove the XML declaration if the content-type is not xml: - if($this->_contentType && (strpos($this->_contentType,'xml') === false)) { - $doctypeStart = strpos($this->_parsedContent, '_parsedContent = substr($this->_parsedContent, $doctypeStart); - } - } - - // Replace template tags ([TAG/] and [TAG]content[/TAG]) and return parsed template content: - $this->_parsedContent = preg_replace_callback($this->_regExpTemplateTags, array($this, 'replaceTemplateTags'), $this->_parsedContent); - } - - function replaceTemplateTags($tagData) { - switch($tagData[1]) { - case 'AJAX_CHAT_URL': - return $this->ajaxChat->htmlEncode($this->ajaxChat->getChatURL()); - - case 'LANG': - return $this->ajaxChat->htmlEncode($this->ajaxChat->getLang($tagData[2])); - case 'LANG_CODE': - return $this->ajaxChat->getLangCode(); - - case 'BASE_DIRECTION': - return $this->getBaseDirectionAttribute(); - - case 'CONTENT_ENCODING': - return $this->ajaxChat->getConfig('contentEncoding'); - - case 'CONTENT_TYPE': - return $this->_contentType; - - case 'LOGIN_URL': - return ($this->ajaxChat->getRequestVar('view') == 'logs') ? './?view=logs' : './'; - - case 'USER_NAME_MAX_LENGTH': - return $this->ajaxChat->getConfig('userNameMaxLength'); - case 'MESSAGE_TEXT_MAX_LENGTH': - return $this->ajaxChat->getConfig('messageTextMaxLength'); - - case 'LOGIN_CHANNEL_ID': - return $this->ajaxChat->getValidRequestChannelID(); - - case 'SESSION_NAME': - return $this->ajaxChat->getConfig('sessionName'); - - case 'COOKIE_EXPIRATION': - return $this->ajaxChat->getConfig('sessionCookieLifeTime'); - case 'COOKIE_PATH': - return $this->ajaxChat->getConfig('sessionCookiePath'); - case 'COOKIE_DOMAIN': - return $this->ajaxChat->getConfig('sessionCookieDomain'); - case 'COOKIE_SECURE': - return $this->ajaxChat->getConfig('sessionCookieSecure'); - - case 'CHAT_BOT_NAME': - return rawurlencode($this->ajaxChat->getConfig('chatBotName')); - case 'CHAT_BOT_ID': - return $this->ajaxChat->getConfig('chatBotID'); - - case 'ALLOW_USER_MESSAGE_DELETE': - if($this->ajaxChat->getConfig('allowUserMessageDelete')) - return 1; - else - return 0; - - case 'INACTIVE_TIMEOUT': - return $this->ajaxChat->getConfig('inactiveTimeout'); - - case 'PRIVATE_CHANNEL_DIFF': - return $this->ajaxChat->getConfig('privateChannelDiff'); - case 'PRIVATE_MESSAGE_DIFF': - return $this->ajaxChat->getConfig('privateMessageDiff'); - - case 'SHOW_CHANNEL_MESSAGES': - if($this->ajaxChat->getConfig('showChannelMessages')) - return 1; - else - return 0; - - case 'SOCKET_SERVER_ENABLED': - if($this->ajaxChat->getConfig('socketServerEnabled')) - return 1; - else - return 0; - - case 'SOCKET_SERVER_HOST': - if($this->ajaxChat->getConfig('socketServerHost')) { - $socketServerHost = $this->ajaxChat->getConfig('socketServerHost'); - } else { - $socketServerHost = (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']); - } - return rawurlencode($socketServerHost); - - case 'SOCKET_SERVER_PORT': - return $this->ajaxChat->getConfig('socketServerPort'); - - case 'SOCKET_SERVER_CHAT_ID': - return $this->ajaxChat->getConfig('socketServerChatID'); - - case 'STYLE_SHEETS': - return $this->getStyleSheetLinkTags(); - - case 'CHANNEL_OPTIONS': - return $this->getChannelOptionTags(); - case 'STYLE_OPTIONS': - return $this->getStyleOptionTags(); - case 'LANGUAGE_OPTIONS': - return $this->getLanguageOptionTags(); - - case 'ERROR_MESSAGES': - return $this->getErrorMessageTags(); - - case 'LOGS_CHANNEL_OPTIONS': - return $this->getLogsChannelOptionTags(); - case 'LOGS_YEAR_OPTIONS': - return $this->getLogsYearOptionTags(); - case 'LOGS_MONTH_OPTIONS': - return $this->getLogsMonthOptionTags(); - case 'LOGS_DAY_OPTIONS': - return $this->getLogsDayOptionTags(); - case 'LOGS_HOUR_OPTIONS': - return $this->getLogsHourOptionTags(); - case 'MENU_BAR': - return << -
  • Home
  • -
  • News
  • -
  • Chat
  • -
  • Members
  • -
  • Donate
  • -
  • Status
  • - -EOF; - case 'COPYRIGHT': - return << - Copyright © 2013-2015 Flashwave -
    AJAX Chat © blueimp.net -
    - Feedback | - Changelog | - Rules & Info | - Terms of Service | - Contact | - DevSite | - Legacy Login -
    -EOF; - case 'SANDSTORM': - if(date('md') === '0127' || !empty($_GET['sandstorm'])) - return << - -
    -HTML; - else - return ''; - default: - return $this->ajaxChat->replaceCustomTemplateTags($tagData[1], (isset($tagData[2]) ? $tagData[2] : null)); - } - } - - // Function to display alternating table row colors: - function alternateRow($rowOdd='rowOdd', $rowEven='rowEven') { - static $i; - $i += 1; - if($i % 2 == 0) { - return $rowEven; - } else { - return $rowOdd; - } - } - - function getBaseDirectionAttribute() { - $langCodeParts = explode('-', $this->ajaxChat->getLangCode()); - switch($langCodeParts[0]) { - case 'ar': - case 'fa': - case 'he': - return 'rtl'; - default: - return 'ltr'; - } - } - - function getStyleSheetLinkTags() { - $styleSheets = ''; - foreach($this->ajaxChat->getConfig('styleAvailable') as $style) { - $alternate = ($style == $this->ajaxChat->getConfig('styleDefault')) ? '' : 'alternate '; - $styleSheets .= ''; - } - return $styleSheets; - } - - function getChannelOptionTags() { - $channelOptions = ''; - $channelSelected = false; - foreach($this->ajaxChat->getChannels() as $key=>$value) { - if($this->ajaxChat->isLoggedIn()) { - $selected = ($value == $this->ajaxChat->getChannel()) ? ' selected="selected"' : ''; - } else { - $selected = ($value == $this->ajaxChat->getConfig('defaultChannelID')) ? ' selected="selected"' : ''; - } - if($selected) { - $channelSelected = true; - } - $channelOptions .= ''; - } - if($this->ajaxChat->isLoggedIn() && $this->ajaxChat->isAllowedToCreatePrivateChannel()) { - // Add the private channel of the user to the options list: - if(!$channelSelected && $this->ajaxChat->getPrivateChannelID() == $this->ajaxChat->getChannel()) { - $selected = ' selected="selected"'; - $channelSelected = true; - } else { - $selected = ''; - } - $privateChannelName = $this->ajaxChat->getPrivateChannelName(); - $channelOptions .= ''; - } - // If current channel is not in the list, try to retrieve the channelName: - if(!$channelSelected) { - $channelName = $this->ajaxChat->getChannelName(); - if($channelName !== null) { - $channelOptions .= ''; - } else { - // Show an empty selection: - $channelOptions .= ''; - } - } - return $channelOptions; - } - - function getStyleOptionTags() { - $styleOptions = ''; - foreach($this->ajaxChat->getConfig('styleAvailable') as $style) { - $selected = ($style == $this->ajaxChat->getConfig('styleDefault')) ? ' selected="selected"' : ''; - $styleOptions .= ''; - } - return $styleOptions; - } - - function getLanguageOptionTags() { - $languageOptions = ''; - $languageNames = $this->ajaxChat->getConfig('langNames'); - foreach($this->ajaxChat->getConfig('langAvailable') as $langCode) { - $selected = ($langCode == $this->ajaxChat->getLangCode()) ? ' selected="selected"' : ''; - $languageOptions .= ''; - } - return $languageOptions; - } - - function getErrorMessageTags() { - $errorMessages = ''; - foreach($this->ajaxChat->getInfoMessages('error') as $error) { - $errorMessages .= '

    '.$this->ajaxChat->htmlEncode($this->ajaxChat->getLang($error)).'

    '; - } - return $errorMessages; - } - - function getLogsChannelOptionTags() { - $channelOptions = ''; - $channelOptions .= ''; - foreach($this->ajaxChat->getChannels() as $key=>$value) { - if($this->ajaxChat->getUserRole() != AJAX_CHAT_ADMIN && $this->ajaxChat->getConfig('logsUserAccessChannelList') && !in_array($value, $this->ajaxChat->getConfig('logsUserAccessChannelList'))) { - continue; - } - $channelOptions .= ''; - } - $channelOptions .= ''; - $channelOptions .= ''; - return $channelOptions; - } - - function getLogsYearOptionTags() { - $yearOptions = ''; - $yearOptions .= ''; - for($year=date('Y'); $year>=$this->ajaxChat->getConfig('logsFirstYear'); $year--) { - $yearOptions .= ''; - } - return $yearOptions; - } - - function getLogsMonthOptionTags() { - $monthOptions = ''; - $monthOptions .= ''; - for($month=1; $month<=12; $month++) { - $monthOptions .= ''; - } - return $monthOptions; - } - - function getLogsDayOptionTags() { - $dayOptions = ''; - $dayOptions .= ''; - for($day=1; $day<=31; $day++) { - $dayOptions .= ''; - } - return $dayOptions; - } - - function getLogsHourOptionTags() { - $hourOptions = ''; - $hourOptions .= ''; - for($hour=0; $hour<=23; $hour++) { - $hourOptions .= ''; - } - return $hourOptions; - } - -} -?> \ No newline at end of file diff --git a/public/lib/class/CustomAJAXChatShoutBox.php b/public/lib/class/CustomAJAXChatShoutBox.php deleted file mode 100644 index 453357b..0000000 --- a/public/lib/class/CustomAJAXChatShoutBox.php +++ /dev/null @@ -1,25 +0,0 @@ -initConfig(); - } - - function getShoutBoxContent() { - $template = new AJAXChatTemplate($this, AJAX_CHAT_PATH.'lib/template/shoutbox.html'); - - // Return parsed template content: - return $template->getParsedContent(); - } - -} -?> \ No newline at end of file diff --git a/public/lib/class/satori.php b/public/lib/class/satori.php deleted file mode 100644 index ea82b1f..0000000 --- a/public/lib/class/satori.php +++ /dev/null @@ -1,239 +0,0 @@ -]*?))?\\]/ms', '', $satoriParse); -$textParts = explode(' ', $satoriParse); - - -// Random Stuff -$defaultResponseArray = ['What do you want?', 'Kindly fuck off.', 'Don\'t know how to "%s" something.', 'Come again?', 'Satori returned an empty result set (i.e. zero rows).']; -$defaultResponse = sprintf($defaultResponseArray[array_rand($defaultResponseArray)], $textParts[0]); - - -// Actions -if(preg_match('/^k$/im', $satoriParse)) { - $satoriResp = ['Thank you for your amazing and insightful message. It is truly an honour to have this message in my database. I can\'t thank you more than to say go fuck yourself. You truly touched me... Thank you.']; -} -if(preg_match('/^time to break the chat$/im', $satoriParse)) { - $satoriResp = ['Stay away from me!']; -} -if(preg_match('/^all aboard the sailboat$/im', $satoriParse)) { - $satoriResp = ['Why would we get on something that is about to sink :^)']; -} - - -// Reactions -if(preg_match('/^satori/im', $textParts[0])) { - switch($satoriInput = preg_replace('/^satori? ?/', '', $satoriParse)) { - case 'version': - $satoriResp = ['[b][color=Red]S[/color][color=Ruby]a[/color][color=Citrine]t[/color][color=Green]o[/color][color=Teal]r[/color][color=Cobalt]i[/color][/b] Version not [b]6[/b]']; - break; - case 'what are you': - $satoriResp = ['I am nice girl for nice chat.', '[img]http://i.imgur.com/NcFitL2.jpg[/img]']; - break; - case 'hi': - $satoriResp = ['sup']; - break; - case 'help': - $satoriResp = ['If you need help with things refer to the [url=http://flashii.net/r/faq]FAQ[/url].', 'If this didn\'t help you don\'t hesitate to ask an active user.']; - break; - case 'why do you exist': - $satoriResp = ['So you have someone to hate. <3']; - break; - case 'suck my dick': - $satoriResp = ['Do you even have one? Can\'t see it.']; - break; - case 'make me admin': - $satoriResp = ['Why the fuck would you WANT admin? It\'s nothing more than extra work for an ugly red username! Look now the colour for deactivated user, that one\'s fucking hot.']; - break; - case 'anime': - $satoriResp = ['Oh god, i wish i could leave this chat but i\'m stuck in here ;__;']; - break; - case 'e': - $satoriResp = ['Do I look like Nasbot or something?']; - break; - case 'meow': - $satoriResp = ['Mewow!']; - break; - case 'puush': - $satoriResp = ['Something you should be using.']; - break; - case 'what is flash\'s password': - case 'what is flashwave\'s password': - case 'what is moka\'s password': - $satoriResp = ['/suicide', 'I do recommend sending it in chat right now.']; - break; - case 'what do you think about snailmush': - case 'what do you like snailmush': - case 'snailmush': - $satoriResp = ['I-it\'s not like I like him or-or any-anything...... ;_;']; - break; - case 'x snailmush': - case 'loves snailmush': - case 'do you love snailmush': - case 'do you love snailmush?': - $satoriResp = ['NO!', '[s]Trigger Kick']; - break; - case 'saibateku': - $satoriResp = ['That place is still up?']; - break; - case 'titanic': - $satoriResp = ['Did you mean Sailboat?']; - break; - case 'did sailboat sink yet': - $satoriResp = ['No but I wish it would. Fuck that place. Seems to be getting pretty close however...']; - break; - case 'malwareup': - $satoriResp = ['Good malware discussion forum.']; - break; - case 'flashii': - $satoriResp = ['Mediocre shithole. 0/10']; - break; - case 'cybernetics': - $satoriResp = ['Did you mean "Saibateku"?']; - break; - case 'nathat': - $satoriResp = ['shut up']; - break; - case 'waifu': - case 'inori aizawa': - case 'internet explorer tan': - $satoriResp = ['Inori Aizawa Is Mai Waifu.', 'Welcome To Mai Web Browser Is Mai Waifu Land!']; - break; - case 'webkit': - case 'safari': - case 'blink': - case 'chrome': - $satoriResp = [':puke::puke::puke:']; - break; - case 'gecko': - case 'trident': - case 'internet explorer': - case 'iexplore': - case 'firefox': - case 'mozilla firefox': - $satoriResp = [':love::love::love:']; - break; - case 'bribob': - case 'bribob4': - $satoriResp = ['Mediocre faggot. 0/10']; - break; - case 'kelopez': - case 'brante': - $satoriResp = ['http://en.wikipedia.org/wiki/Mexican']; - break; - case 'kamil': - case 'rakowski': - case 'kamilrakowski': - $satoriResp = ['http://en.wikipedia.org/wiki/Jews']; - break; - case 'secret': - $satoriResp = ['I\'m not a secret ripoff, what are you talking about?', '[i]My code is better, time to kill yourself![/i]']; - break; - case 'koishi': - $satoriResp = ['Don\'t fuck with Koishi.']; - break; - case ':^)': - $satoriResp = ['8^)']; - break; - case 'nookls': - $satoriResp = ['HOOOOLLLLLYYYYYYYYYYYYY CRAP NOOKLS IS SO AMAZING WOWOWOWOWOWOW HE\'S ACTUALLY ON THIS SITE WORSHIP WORSHIP AMAZING BRILLIANT I LOVE YOU NOOKLS WE ALL LOVE YOU WE LOVE YOU AS MUCH AS FANGIRLS LOVE JUSTIN BIEBER AAAAAAAAHHHHHHHHHHHH THIS IS THE BEST MOMENT!']; - break; - case 'zeniea': - $satoriResp = ['For whatever reason I have the urge to say "This place smells like a catholic church on crack"...']; - break; - case 'zquest': - $satoriResp = ['Good comic 10/10']; - break; - case 'fuck me': - $satoriResp = [':wtf:']; - break; - case 'satori': - $satoriResp = ['Wait, what are you trying to do?']; - break; - case 'satori satori': - $satoriResp = ['Don\'t fucking do this to me...']; - break; - case 'satori satori satori': - $satoriResp = ['[b][i]I\'ll fucking murder you![/i][/b]']; - break; - case 'satori satori satori satori': - $satoriResp = ['no don\'t']; - break; - case 'satori satori satori satori satori': - $satoriResp = ['please don\'t do this to me']; - break; - case 'satori satori satori satori satori satori': - $satoriResp = ['i have a waifu and kids']; - break; - case 'satori satori satori satori satori satori satori': - $satoriResp = ['okay i was kidding about the kids part']; - break; - case 'satori satori satori satori satori satori satori satori': - $satoriResp = ['rip life']; - break; - case 'you are annoying': - case 'please die': - case 'die': - $satoriResp = ['Well I\'m God and you can\'t do shit.']; - break; - case 'misaka-20001': - $satoriResp = ['We\'ll have to move one of these days...', 'The good ol\' Pentium 4 doesn\'t seem to be able to handle shit anymore...']; - break; - case 'how old are you': - case 'how old is flashii': - case 'how old is koishi': - $satoriResp = [date_diff(date_create('2013-01-27 22:14:44 UTC'), date_create(date('Y-m-d H:i:s e')))->format('%y year(s), %m month(s), %d day(s), %H hour(s), %i minute(s) and %s second(s)')]; - break; - case 'how old is zeniea': - case 'how old is secret': - $satoriResp = [date_diff(date_create('2011-07-07 00:00:00 UTC'), date_create(date('Y-m-d H:i:s e')))->format('%y year(s), %m month(s), %d day(s), %H hour(s), %i minute(s) and %s second(s)')]; - break; - case 'how old is zquest': - $satoriResp = [date_diff(date_create('2013-11-16 00:00:00 UTC'), date_create(date('Y-m-d H:i:s e')))->format('%y year(s), %m month(s), %d day(s), %H hour(s), %i minute(s) and %s second(s)')]; - break; - case 'are you broken': - case 'are you broken?': - case 'is flashii broken': - case 'is flashii broken?': - $satoriResp = ['yes']; - break; - default: - $satoriResp = [$defaultResponse]; - break; - } -} - - -// Check if disabled -if(!$satoriSetting['enabled']) - $satoriResp = null; - - -// Bring the process of sending a message down to one if -if(isset($satoriResp)) { - foreach($satoriResp as $directives => $response) { - if($response == '[s]Trigger Kick') { - $this->logout('Kicked'); - } else { - $this->insertCustomMessage( - $satoriSetting['userID'], - $satoriSetting['userName'], - $satoriSetting['userRank'], - $this->getChannel(), - vsprintf($response, $directives), - $satoriSetting['userIP'], - 0 - ); - } - } -} diff --git a/public/lib/classes.php b/public/lib/classes.php deleted file mode 100644 index 9648fa5..0000000 --- a/public/lib/classes.php +++ /dev/null @@ -1,26 +0,0 @@ - \ No newline at end of file diff --git a/public/lib/custom.php b/public/lib/custom.php deleted file mode 100644 index 1809bc2..0000000 --- a/public/lib/custom.php +++ /dev/null @@ -1,11 +0,0 @@ - \ No newline at end of file diff --git a/public/lib/lang/en.php b/public/lib/lang/en.php deleted file mode 100644 index 7694360..0000000 --- a/public/lib/lang/en.php +++ /dev/null @@ -1,120 +0,0 @@ -initConfig(); + + // Initialize the DataBase connection: + $this->initDataBaseConnection(); + + // Initialize request variables: + $this->initRequestVars(); + + // Initialize the chat session: + $this->initSession(); + + // Handle the browser request and send the response content: + $this->handleRequest(); + } + + function initConfig() { + $config = null; + if(!include_once AJAX_CHAT_PATH . '/config/config.php')) { + print('Error: Configuration file could not be loaded.'); + exit; + } + $this->_config = &$config; + + // Initialize custom configuration settings: + $this->initCustomConfig(); + } + + function initRequestVars() { + $this->_requestVars = array(); + $this->_requestVars['ajax'] = isset($_REQUEST['ajax']) ? true : false; + $this->_requestVars['userID'] = isset($_REQUEST['userID']) ? (int)$_REQUEST['userID'] : null; + $this->_requestVars['userName'] = isset($_REQUEST['userName']) ? $_REQUEST['userName'] : null; + $this->_requestVars['channelID'] = isset($_REQUEST['channelID']) ? (int)$_REQUEST['channelID'] : null; + $this->_requestVars['channelName'] = isset($_REQUEST['channelName']) ? $_REQUEST['channelName'] : null; + $this->_requestVars['text'] = isset($_POST['text']) ? $_POST['text'] : null; + $this->_requestVars['lastID'] = isset($_REQUEST['lastID']) ? (int)$_REQUEST['lastID'] : 0; + $this->_requestVars['login'] = isset($_REQUEST['login']) ? true : false; + $this->_requestVars['logout'] = isset($_POST['logout']) ? true : false; + $this->_requestVars['password'] = isset($_REQUEST['password']) ? $_REQUEST['password'] : null; + $this->_requestVars['view'] = isset($_REQUEST['view']) ? $_REQUEST['view'] : null; + $this->_requestVars['year'] = isset($_REQUEST['year']) ? (int)$_REQUEST['year'] : null; + $this->_requestVars['month'] = isset($_REQUEST['month']) ? (int)$_REQUEST['month'] : null; + $this->_requestVars['day'] = isset($_REQUEST['day']) ? (int)$_REQUEST['day'] : null; + $this->_requestVars['hour'] = isset($_REQUEST['hour']) ? (int)$_REQUEST['hour'] : null; + $this->_requestVars['search'] = isset($_REQUEST['search']) ? $_REQUEST['search'] : null; + $this->_requestVars['shoutbox'] = isset($_REQUEST['shoutbox']) ? true : false; + $this->_requestVars['getInfos'] = isset($_REQUEST['getInfos']) ? $_REQUEST['getInfos'] : null; + $this->_requestVars['lang'] = isset($_REQUEST['lang']) ? $_REQUEST['lang'] : null; + $this->_requestVars['delete'] = isset($_REQUEST['delete']) ? (int)$_REQUEST['delete'] : null; + + // Initialize custom request variables: + $this->initCustomRequestVars(); + + // Remove slashes which have been added to user input strings if magic_quotes_gpc is On: + /*if(get_magic_quotes_gpc()) { + // It is safe to remove the slashes as we escape user data ourself + array_walk( + $this->_requestVars, + create_function( + '&$value, $key', + 'if(is_string($value)) $value = stripslashes($value);' + ) + ); + }*/ + } + + function initDataBaseConnection() { + // Create a new database object: + $this->db = new AJAXChatDataBase( + $this->_config['dbConnection'] + ); + // Use a new database connection if no existing is given: + if(!$this->_config['dbConnection']['link']) { + // Connect to the database server: + $this->db->connect($this->_config['dbConnection']); + if($this->db->error()) { + echo $this->db->getError(); + die(); + } + // Select the database: + $this->db->select($this->_config['dbConnection']['name']); + if($this->db->error()) { + echo $this->db->getError(); + die(); + } + } + // Unset the dbConnection array for safety purposes: + unset($this->_config['dbConnection']); + } + + function getDataBaseTable($table) { + return ($this->db->getName() ? $this->db->getName().'.'.$this->getConfig('dbTableNames',$table) : $this->getConfig('dbTableNames',$table)); + } + + function initSession() { + // Start the PHP session (if not already started): + $this->startSession(); + + if($this->isLoggedIn()) { + // Logout if we receive a logout request, the chat has been closed or the userID could not be revalidated: + if($this->getRequestVar('logout') || !$this->isChatOpen() || !$this->revalidateUserID()) { + $this->logout(); + return; + } + // Logout if the Session IP is not the same when logged in and ipCheck is enabled: + if($this->getConfig('ipCheck') && ($this->getSessionIP() === null || $this->getSessionIP() != $_SERVER['REMOTE_ADDR'])) { + $this->logout('IP'); + return; + } + } else if( + // Login if auto-login enabled or a login, userName or shoutbox parameter is given: + $this->getConfig('forceAutoLogin') || + $this->getRequestVar('login') || + $this->getRequestVar('userName') || + $this->getRequestVar('shoutbox') + ) { + $this->login(); + } + + // Initialize the view: + $this->initView(); + + if($this->getView() == 'chat') { + $this->initChatViewSession(); + } else if($this->getView() == 'logs') { + $this->initLogsViewSession(); + } + + if(!$this->getRequestVar('ajax') && !headers_sent()) { + // Set style cookie: + $this->setStyle(); + // Set langCode cookie: + $this->setLangCodeCookie(); + } + + $this->initCustomSession(); + } + + function initLogsViewSession() { + if($this->getConfig('socketServerEnabled')) { + if(!$this->getSessionVar('logsViewSocketAuthenticated')) { + $this->updateLogsViewSocketAuthentication(); + $this->setSessionVar('logsViewSocketAuthenticated', true); + } + } + } + + function updateLogsViewSocketAuthentication() { + if($this->getUserRole() != AJAX_CHAT_ADMIN) { + $channels = array(); + foreach($this->getChannels() as $channel) { + if($this->getConfig('logsUserAccessChannelList') && !in_array($channel, $this->getConfig('logsUserAccessChannelList'))) { + continue; + } + array_push($channels, $channel); + } + array_push($channels, $this->getPrivateMessageID()); + array_push($channels, $this->getPrivateChannelID()); + } else { + // The channelID "ALL" authenticates for all channels: + $channels = array('ALL'); + } + $this->updateSocketAuthentication( + $this->getUserID(), + $this->getSocketRegistrationID(), + $channels + ); + } + + function initChatViewSession() { + // If channel is not null we are logged in to the chat view: + if($this->getChannel() !== null) { + // Check if the current user has been logged out due to inactivity: + if(!$this->isUserOnline()) { + $this->logout(); + return; + } + if($this->getRequestVar('ajax')) { + $this->initChannel(); + $this->updateOnlineStatus(); + $this->checkAndRemoveInactive(); + } + } else { + if($this->getRequestVar('ajax')) { + // Set channel, insert login messages and add to online list on first ajax request in chat view: + $this->chatViewLogin(); + } + } + } + + function isChatOpen() { + if($this->getUserRole() == AJAX_CHAT_ADMIN) + return true; + if($this->getConfig('chatClosed')) + return false; + $time = time(); + if($this->getConfig('timeZoneOffset') !== null) { + // Subtract the server timezone offset and add the config timezone offset: + $time -= date('Z', $time); + $time += $this->getConfig('timeZoneOffset'); + } + // Check the opening hours: + if($this->getConfig('openingHour') < $this->getConfig('closingHour')) + { + if(($this->getConfig('openingHour') > date('G', $time)) || ($this->getConfig('closingHour') <= date('G', $time))) + return false; + } + else + { + if(($this->getConfig('openingHour') > date('G', $time)) && ($this->getConfig('closingHour') <= date('G', $time))) + return false; + } + // Check the opening weekdays: + if(!in_array(date('w', $time), $this->getConfig('openingWeekDays'))) + return false; + return true; + } + + function handleRequest() { + if($this->getRequestVar('ajax')) { + if($this->isLoggedIn()) { + // Parse info requests (for current userName, etc.): + $this->parseInfoRequests(); + + // Parse command requests (e.g. message deletion): + $this->parseCommandRequests(); + + // Parse message requests: + $this->initMessageHandling(); + } + // Send chat messages and online user list in XML format: + $this->sendXMLMessages(); + } else { + // Display XHTML content for non-ajax requests: + $this->sendXHTMLContent(); + } + } + + function parseCommandRequests() { + if($this->getRequestVar('delete') !== null) { + $this->deleteMessage($this->getRequestVar('delete')); + } + } + + function parseInfoRequests() { + if($this->getRequestVar('getInfos')) { + $infoRequests = explode(',', $this->getRequestVar('getInfos')); + foreach($infoRequests as $infoRequest) { + $this->parseInfoRequest($infoRequest); + } + } + } + + function parseInfoRequest($infoRequest) { + switch($infoRequest) { + case 'userID': + $this->addInfoMessage($this->getUserID(), 'userID'); + break; + case 'userName': + $this->addInfoMessage($this->getUserName(), 'userName'); + break; + case 'userRole': + $this->addInfoMessage($this->getUserRole(), 'userRole'); + break; + case 'channelID': + $this->addInfoMessage($this->getChannel(), 'channelID'); + break; + case 'channelName': + $this->addInfoMessage($this->getChannelName(), 'channelName'); + break; + case 'socketRegistrationID': + $this->addInfoMessage($this->getSocketRegistrationID(), 'socketRegistrationID'); + break; + default: + $this->parseCustomInfoRequest($infoRequest); + } + } + + function sendXHTMLContent() { + $httpHeader = new AJAXChatHTTPHeader($this->getConfig('contentEncoding'), $this->getConfig('contentType')); + + $template = new AJAXChatTemplate($this, $this->getTemplateFileName(), $httpHeader->getContentType()); + + // Send HTTP header: + $httpHeader->send(); + + // Send parsed template content: + echo $template->getParsedContent(); + } + + function getTemplateFileName() { + switch($this->getView()) { + case 'chat': + return AJAX_CHAT_PATH . '/template/loggedIn.html'; + case 'logs': + return AJAX_CHAT_PATH . '/template/logs.html'; + case 'mobile': + return AJAX_CHAT_PATH . '/template/mobile.html'; + case 'legacy': + return AJAX_CHAT_PATH . '/template/legacyLogin.html'; + case 'banned': + return AJAX_CHAT_PATH . '/template/banned.html'; + case 'legacy1': + return AJAX_CHAT_PATH . '/template/~loggedOut.html'; + case 'legacy2': + return AJAX_CHAT_PATH . '/template/loggedOut~.html'; + case 'legacy3': + return AJAX_CHAT_PATH . '/template/loggedOutFA.html'; + default: + return AJAX_CHAT_PATH . '/template/loggedOut.html'; + } + } + + function initView() { + $this->_view = null; + // "chat" is the default view: + $view = ($this->getRequestVar('view') === null) ? 'chat' : $this->getRequestVar('view'); + if($this->hasAccessTo($view)) { + $this->_view = $view; + } + } + + function getView() { + return $this->_view; + } + + function hasAccessTo($view) { + if(substr($view, 0, 6) === 'legacy') + return !$this->isLoggedIn(); + + switch($view) { + case 'legacy': + if($this->isLoggedIn()) { + return false; + } + return true; + case 'banned': + return true; + case 'chat': + case 'mobile': + case 'teaser': + if($this->isLoggedIn()) { + return true; + } + return false; + case 'logs': + if($this->isLoggedIn() && ($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == CMOD || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == PURPLE || $this->getUserRole() == DONATOR || + ($this->getConfig('logsUserAccess') && + ($this->getUserRole() == AJAX_CHAT_USER)) + )) { + return true; + } + return false; + default: + return false; + } + } + + function login() { + // Retrieve valid login user data (from request variables or session data): + $userData = $this->getValidLoginUserData(); + + if(!$userData) { + $this->addInfoMessage('errorInvalidUser'); + return false; + } + + // If the chat is closed, only the admin may login: + if(!$this->isChatOpen() && $userData['userRole'] != AJAX_CHAT_ADMIN) { + $this->addInfoMessage('errorChatClosed'); + return false; + } + + if(!$this->getConfig('allowGuestLogins') && $userData['userRole'] == AJAX_CHAT_GUEST) { + return false; + } + + // Check if userID or userName are already listed online: + if($this->isUserOnline($userData['userID']) || $this->isUserNameInUse($userData['userName'])) { + // Set the registered user inactive and remove the inactive users so the user can be logged in again: + $this->setInactive($userData['userID'], $userData['userName']); + $this->removeInactive(); + } + + // Check if user is banned: + if($userData['userRole'] != AJAX_CHAT_ADMIN && $this->isUserBanned($userData['userName'], $userData['userID'], $_SERVER['REMOTE_ADDR'])) { + $this->addInfoMessage('errorBanned'); + return false; + } + + // Check if the max number of users is logged in (not affecting moderators or admins): + if(!($userData['userRole'] == AJAX_CHAT_MODERATOR || $userData['userRole'] == PURPLE || $userData['userRole'] == AJAX_CHAT_ADMIN) && $this->isMaxUsersLoggedIn()) { + $this->addInfoMessage('errorMaxUsersLoggedIn'); + return false; + } + + // Use a new session id (if session has been started by the chat): + $this->regenerateSessionID(); + + // Log in: + $this->setUserID($userData['userID']); + $this->setUserName($userData['userName']); + $this->setLoginUserName($userData['userName']); + $this->setUserRole($userData['userRole']); + $this->setLoggedIn(true); + $this->setLoginTimeStamp(time()); + + // IP Security check variable: + $this->setSessionIP($_SERVER['REMOTE_ADDR']); + + // The client authenticates to the socket server using a socketRegistrationID: + if($this->getConfig('socketServerEnabled')) { + $this->setSocketRegistrationID( + md5(uniqid(rand(), true)) + ); + } + + // Add userID, userName and userRole to info messages: + $this->addInfoMessage($this->getUserID(), 'userID'); + $this->addInfoMessage($this->getUserName(), 'userName'); + $this->addInfoMessage($this->getUserRole(), 'userRole'); + + // Purge logs: + if($this->getConfig('logsPurgeLogs')) { + $this->purgeLogs(); + } + + // Report login to Satori: + /*$boatcom = @fsockopen('marie.railgun.sh', 9064, $errno, $errstr, 5); + if($boatcom) { + $message = sprintf('{sock}[i][url=https://flashii.net/profile.php?u=%d][b]%s[/b][/url] logged into [url=https://flash.moe/chat/]Flashii Chat Legacy[/url].[/i]', $userData['userID'], $userData['userName']); + $message = chr(0xF) . hash_hmac('sha256', $message, 'lol glad i caught this, that could\'ve been pretty funny if i forgot to remove this') . $message . chr(0xF); + fwrite($boatcom, $message); + fflush($boatcom); + fclose($boatcom); + }*/ + + return true; + } + + function chatViewLogin() { + $this->setChannel($this->getValidRequestChannelID()); + $this->addToOnlineList(); + + // Add channelID and channelName to info messages: + $this->addInfoMessage($this->getChannel(), 'channelID'); + $this->addInfoMessage($this->getChannelName(), 'channelName'); + + // Login message: + $text = '/login '.$this->getUserName(); + $this->insertChatBotMessage( + $this->getChannel(), + $text, + null, + 1 + ); + } + + function getValidRequestChannelID() { + $channelID = $this->getRequestVar('channelID'); + $channelName = $this->getRequestVar('channelName'); + // Check the given channelID, or get channelID from channelName: + if($channelID === null) { + if($channelName !== null) { + $channelID = $this->getChannelIDFromChannelName($channelName); + // channelName might need encoding conversion: + if($channelID === null) { + $channelID = $this->getChannelIDFromChannelName( + $this->trimChannelName($channelName, $this->getConfig('contentEncoding')) + ); + } + } + } + // Validate the resulting channelID: + if(!$this->validateChannel($channelID)) { + if($this->getChannel() !== null) { + return $this->getChannel(); + } + return $this->getConfig('defaultChannelID'); + } + return $channelID; + } + + function initChannel() { + $channelID = $this->getRequestVar('channelID'); + $channelName = $this->getRequestVar('channelName'); + if($channelID !== null) { + $this->switchChannel($this->getChannelNameFromChannelID($channelID)); + } else if($channelName !== null) { + if($this->getChannelIDFromChannelName($channelName) === null) { + // channelName might need encoding conversion: + $channelName = $this->trimChannelName($channelName, $this->getConfig('contentEncoding')); + } + $this->switchChannel($channelName); + } + } + + function logout($type=null) { + // Update the socket server authentication for the user: + if($this->getConfig('socketServerEnabled')) { + $this->updateSocketAuthentication($this->getUserID()); + } + if($this->isUserOnline()) { + $this->chatViewLogout($type); + } + $this->setLoggedIn(false); + $this->destroySession(); + + // Re-initialize the view: + $this->initView(); + } + + function chatViewLogout($type) { + $this->removeFromOnlineList(); + if($type !== null) { + $type = ' '.$type; + } + // Logout message + $text = '/logout '.$this->getUserName().$type; + $this->insertChatBotMessage( + $this->getChannel(), + $text, + null, + 1 + ); + } + + function switchChannel($channelName) { + $channelID = $this->getChannelIDFromChannelName($channelName); + + if($channelID !== null && $this->getChannel() == $channelID) { + // User is already in the given channel, return: + return; + } + + // Check if we have a valid channel: + if(!$this->validateChannel($channelID)) { + // Invalid channel: + $text = '/error InvalidChannelName '.$channelName; + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + $text + ); + return; + } + + $oldChannel = $this->getChannel(); + + $this->setChannel($channelID); + $this->updateOnlineList(); + + // Channel leave message + $text = '/channelLeave '.$this->getUserName(); + $this->insertChatBotMessage( + $oldChannel, + $text, + null, + 1 + ); + + // Channel enter message + $text = '/channelEnter '.$this->getUserName(); + $this->insertChatBotMessage( + $this->getChannel(), + $text, + null, + 1 + ); + + $this->addInfoMessage($channelName, 'channelSwitch'); + $this->addInfoMessage($channelID, 'channelID'); + $this->_requestVars['lastID'] = 0; + } + + function addToOnlineList() { + $sql = 'INSERT INTO '.$this->getDataBaseTable('online').'( + userID, + userName, + userRole, + channel, + dateTime, + ip + ) + VALUES ( + '.$this->db->makeSafe($this->getUserID()).', + '.$this->db->makeSafe($this->getUserName()).', + '.$this->db->makeSafe($this->getUserRole()).', + '.$this->db->makeSafe($this->getChannel()).', + NOW(), + '.$this->db->makeSafe($this->ipToStorageFormat($_SERVER['REMOTE_ADDR'])).' + );'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + $this->resetOnlineUsersData(); + } + + function removeFromOnlineList() { + $sql = 'DELETE FROM + '.$this->getDataBaseTable('online').' + WHERE + userID = '.$this->db->makeSafe($this->getUserID()).';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + $this->removeUserFromOnlineUsersData(); + } + + function updateOnlineList() { + $sql = 'UPDATE + '.$this->getDataBaseTable('online').' + SET + userName = '.$this->db->makeSafe($this->getUserName()).', + channel = '.$this->db->makeSafe($this->getChannel()).', + dateTime = NOW(), + ip = '.$this->db->makeSafe($this->ipToStorageFormat($_SERVER['REMOTE_ADDR'])).' + WHERE + userID = '.$this->db->makeSafe($this->getUserID()).';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + $this->resetOnlineUsersData(); + } + + function initMessageHandling() { + // Don't handle messages if we are not in chat view: + if($this->getView() != 'chat') { + return; + } + + // Check if we have been uninvited from a private or restricted channel: + if(!$this->validateChannel($this->getChannel())) { + // Switch to the default channel: + $this->switchChannel($this->getChannelNameFromChannelID($this->getConfig('defaultChannelID'))); + return; + } + + if($this->getRequestVar('text') !== null) { + $this->insertMessage($this->getRequestVar('text')); + } + } + + function insertParsedMessage($text) { + // Replace Unicode character + $text = preg_replace("/\xEF\xBF\xBF/im", " ", $text); + + $gtParse = preg_replace('/\\[(?:\\/)?(\\w+)(?:=([^<>]*?))?\\]/ms', '', $text); + + // Auto greentext + if(preg_match("/>(.*?)$/im", $gtParse)) { + $text = preg_replace("/>(.*?)$/im", "[color=Green]>$1[/color]", $gtParse); + } + if(preg_match("/(.*?)<$/im", $gtParse)) { + $text = preg_replace("/(.*?)<$/im", "[color=Red]$1<[/color]", $gtParse); + } + + // Emoticon Limiting + $emoticons = array(':happy:', ':lmao:', ':angry:', ':angrier:', ':evil:', ':glare:', ':eat:', ':lol:', ':dizzy:', ':yay:', ':wtf:', ':sigh:', ':omg:', ':ouch:', ':tired:', ':kiss:', ':love:', ':sweat:', ':suspicious:', ':crying:', ':blank:', ':puke:', ':ruse:', ':meow:'); + $emoticonCount = 0; + + foreach($emoticons as $emoticon) { + // Increase Emoticon count + $emoticonCount += substr_count($text, $emoticon); + + // If higher than 10 replace then + if($emoticonCount > 10) + $text = str_replace($emoticon, '', $text); + } + + if($this->getQueryUserName() !== null && strpos($text, '/') !== 0) { + // If a queryUserName is set, sent all messages as private messages to this userName: + $text = '/msg '.$this->getQueryUserName().' '.$text; + } + + if(strpos($text, '/') === 0) { + // Parse IRC-style commands: + $textParts = explode(' ', $text); + + switch($textParts[0]) { + // Channel switch: + case '/join': + $this->insertParsedMessageJoin($textParts); + break; + + // Logout: + case '/quit': + case '/suicide': + $this->logout(); + break; + + // Private message: + case '/msg': + case '/describe': + $this->insertParsedMessagePrivMsg($textParts); + break; + + // Invitation: + case '/invite': + $this->insertParsedMessageInvite($textParts); + break; + + // Uninvitation: + case '/uninvite': + $this->insertParsedMessageUninvite($textParts); + break; + + // Private messaging: + case '/query': + $this->insertParsedMessageQuery($textParts); + break; + + // Kicking offending users from the chat: + case '/kick': + $this->insertParsedMessageKick($textParts); + break; + + // Listing banned users: + case '/bans': + $this->insertParsedMessageBans($textParts); + break; + + // Unban user (remove from ban list): + case '/unban': + $this->insertParsedMessageUnban($textParts); + break; + + // Describing actions: + case '/me': + case '/action': + $this->insertParsedMessageAction($textParts); + break; + + // Listing online Users: + case '/who': + $this->insertParsedMessageWho($textParts); + break; + + // Listing available channels: + case '/list': + $this->insertParsedMessageList($textParts); + break; + + // Retrieving the channel of a User: + case '/whereis': + $this->insertParsedMessageWhereis($textParts); + break; + + // Listing information about a User: + case '/whois': + $this->insertParsedMessageWhois($textParts); + break; + + // Rolling dice: + case '/roll': + $this->insertParsedMessageRoll($textParts); + break; + + // Switching userName: + case '/nick': + $this->insertParsedMessageNick($textParts); + break; + + // Switching userName: + case '/saibatekuisagoodsite': + $this->insertParsedMessageChangeNick($textParts); + break; + + // Custom or unknown command: + default: + if(!$this->parseCustomCommands($text, $textParts)) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UnknownCommand '.$textParts[0] + ); + } + } + + } else { + // No command found, just insert the plain message: + $this->insertCustomMessage( + $this->getUserID(), + $this->getUserName(), + $this->getUserRole(), + $this->getChannel(), + $text + ); + } + include_once 'satori.php'; + } + + function insertParsedMessageJoin($textParts) { + if(count($textParts) == 1) { + // join with no arguments is the own private channel, if allowed: + if($this->isAllowedToCreatePrivateChannel()) { + // Private channels are identified by square brackets: + $this->switchChannel($this->getChannelNameFromChannelID($this->getPrivateChannelID())); + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingChannelName' + ); + } + } else { + $this->switchChannel($textParts[1]); + } + } + + function insertParsedMessagePrivMsg($textParts) { + if($this->isAllowedToSendPrivateMessage()) { + if(count($textParts) < 3) { + if(count($textParts) == 2) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingText' + ); + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingUserName' + ); + } + } else { + // Get UserID from UserName: + $toUserID = $this->getIDFromName($textParts[1]); + if($toUserID === null) { + if($this->getQueryUserName() !== null) { + // Close the current query: + $this->insertMessage('/query'); + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UserNameNotFound '.$textParts[1] + ); + } + } else { + // Insert /privaction command if /describe is used: + $command = ($textParts[0] == '/describe') ? '/privaction' : '/privmsg'; + // Copy of private message to current User: + $this->insertCustomMessage( + $this->getUserID(), + $this->getUserName(), + $this->getUserRole(), + $this->getPrivateMessageID(), + $command.'to '.$textParts[1].' '.implode(' ', array_slice($textParts, 2)) + ); + // Private message to requested User: + $this->insertCustomMessage( + $this->getUserID(), + $this->getUserName(), + $this->getUserRole(), + $this->getPrivateMessageID($toUserID), + $command.' '.implode(' ', array_slice($textParts, 2)) + ); + } + } + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error PrivateMessageNotAllowed' + ); + } + } + + function insertParsedMessageInvite($textParts) { + if($this->getChannel() == $this->getPrivateChannelID() || in_array($this->getChannel(), $this->getChannels())) { + if(count($textParts) == 1) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingUserName' + ); + } else { + $toUserID = $this->getIDFromName($textParts[1]); + if($toUserID === null) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UserNameNotFound '.$textParts[1] + ); + } else { + // Add the invitation to the database: + $this->addInvitation($toUserID); + $invitationChannelName = $this->getChannelNameFromChannelID($this->getChannel()); + // Copy of invitation to current User: + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/inviteto '.$textParts[1].' '.$invitationChannelName + ); + // Invitation to requested User: + $this->insertChatBotMessage( + $this->getPrivateMessageID($toUserID), + '/invite '.$this->getUserName().' '.$invitationChannelName + ); + } + } + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error InviteNotAllowed' + ); + } + } + + function insertParsedMessageUninvite($textParts) { + if($this->getChannel() == $this->getPrivateChannelID() || in_array($this->getChannel(), $this->getChannels())) { + if(count($textParts) == 1) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingUserName' + ); + } else { + $toUserID = $this->getIDFromName($textParts[1]); + if($toUserID === null) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UserNameNotFound '.$textParts[1] + ); + } else { + // Remove the invitation from the database: + $this->removeInvitation($toUserID); + $invitationChannelName = $this->getChannelNameFromChannelID($this->getChannel()); + // Copy of uninvitation to current User: + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/uninviteto '.$textParts[1].' '.$invitationChannelName + ); + // Uninvitation to requested User: + $this->insertChatBotMessage( + $this->getPrivateMessageID($toUserID), + '/uninvite '.$this->getUserName().' '.$invitationChannelName + ); + } + } + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UninviteNotAllowed' + ); + } + } + + function insertParsedMessageQuery($textParts) { + if($this->isAllowedToSendPrivateMessage()) { + if(count($textParts) == 1) { + if($this->getQueryUserName() !== null) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/queryClose '.$this->getQueryUserName() + ); + // Close the current query: + $this->setQueryUserName(null); + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error NoOpenQuery' + ); + } + } else { + if($this->getIDFromName($textParts[1]) === null) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UserNameNotFound '.$textParts[1] + ); + } else { + if($this->getQueryUserName() !== null) { + // Close the current query: + $this->insertMessage('/query'); + } + // Open a query to the requested user: + $this->setQueryUserName($textParts[1]); + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/queryOpen '.$textParts[1] + ); + } + } + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error PrivateMessageNotAllowed' + ); + } + } + + function insertParsedMessageKick($textParts) { + // Only moderators/admins may kick users: + if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == CMOD || $this->getUserID() == 11) { + if(count($textParts) == 1) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingUserName' + ); + } else { + // Get UserID from UserName: + $kickUserID = $this->getIDFromName($textParts[1]); + if($kickUserID === null) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UserNameNotFound '.$textParts[1] + ); + } else { + // Check the role of the user to kick: + $kickUserRole = $this->getRoleFromID($kickUserID); + if( + $kickUserRole == AJAX_CHAT_ADMIN || + ( + ( + $kickUserID == 11 + && + $this->getUserRole() != AJAX_CHAT_ADMIN + && + $this->getUserID() != 11 + ) + || + ( + $kickUserRole == CMOD + && + $this->getUserRole() != AJAX_CHAT_MODERATOR + && + $this->getUserRole() != PURPLE + && + $this->getUserRole() != AJAX_CHAT_ADMIN + && + $this->getUserID() != 11 + ) + || + ( + $kickUserRole == AJAX_CHAT_MODERATOR + && + $this->getUserRole() != PURPLE + && + $this->getUserRole() != AJAX_CHAT_ADMIN + && + $this->getUserID() != 11 + ) + ) + ) { + // Admins and moderators may not be kicked: + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error KickNotAllowed '.$textParts[1] + ); + } else { + // Kick user and insert message: + $channel = $this->getChannelFromID($kickUserID); + $banMinutes = (count($textParts) > 2) ? $textParts[2] : null; + $this->kickUser($textParts[1], $banMinutes, $kickUserID); + // If no channel found, user logged out before he could be kicked + if($channel !== null) { + $this->insertChatBotMessage( + $channel, + '/kick '.$textParts[1], + null, + 1 + ); + // Send a copy of the message to the current user, if not in the channel: + if($channel != $this->getChannel()) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/kick '.$textParts[1], + null, + 1 + ); + } + } + } + } + } + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error CommandNotAllowed '.$textParts[0] + ); + } + } + + function insertParsedMessageBans($textParts) { + // Only moderators/admins may see the list of banned users: + if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == CMOD) { + $this->removeExpiredBans(); + $bannedUsers = $this->getBannedUsers(); + if(count($bannedUsers) > 0) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/bans '.implode(' ', $bannedUsers) + ); + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/bansEmpty -' + ); + } + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error CommandNotAllowed '.$textParts[0] + ); + } + } + + function insertParsedMessageUnban($textParts) { + // Only moderators/admins may unban users: + if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == CMOD) { + $this->removeExpiredBans(); + if(count($textParts) == 1) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingUserName' + ); + } else { + if(!in_array($textParts[1], $this->getBannedUsers())) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UserNameNotFound '.$textParts[1] + ); + } else { + // Unban user and insert message: + $this->unbanUser($textParts[1]); + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/unban '.$textParts[1] + ); + } + } + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error CommandNotAllowed '.$textParts[0] + ); + } + } + + function insertParsedMessageAction($textParts) { + if(count($textParts) == 1) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingText' + ); + } else { + if($this->getQueryUserName() !== null) { + // If we are in query mode, sent the action to the query user: + $this->insertMessage('/describe '.$this->getQueryUserName().' '.implode(' ', array_slice($textParts, 1))); + } else { + $this->insertCustomMessage( + $this->getUserID(), + $this->getUserName(), + $this->getUserRole(), + $this->getChannel(), + implode(' ', $textParts) + ); + } + } + } + + function insertParsedMessageWho($textParts) { + if(count($textParts) == 1) { + if($this->isAllowedToListHiddenUsers()) { + // List online users from any channel: + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/who '.implode(' ', $this->getOnlineUsers()) + ); + } else { + // Get online users for all accessible channels: + $channels = $this->getChannels(); + // Add the own private channel if allowed: + if($this->isAllowedToCreatePrivateChannel()) { + array_push($channels, $this->getPrivateChannelID()); + } + // Add the invitation channels: + foreach($this->getInvitations() as $channelID) { + if(!in_array($channelID, $channels)) { + array_push($channels, $channelID); + } + } + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/who '.implode(' ', $this->getOnlineUsers($channels)) + ); + } + } else { + $channelName = $textParts[1]; + $channelID = $this->getChannelIDFromChannelName($channelName); + if(!$this->validateChannel($channelID)) { + // Invalid channel: + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error InvalidChannelName '.$channelName + ); + } else { + // Get online users for the given channel: + $onlineUsers = $this->getOnlineUsers(array($channelID)); + if(count($onlineUsers) > 0) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/whoChannel '.$channelName.' '.implode(' ', $onlineUsers) + ); + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/whoEmpty -' + ); + } + } + } + } + + function insertParsedMessageList($textParts) { + // Get the names of all accessible channels: + $channelNames = $this->getChannelNames(); + // Add the own private channel, if allowed: + if($this->isAllowedToCreatePrivateChannel()) { + array_push($channelNames, $this->getPrivateChannelName()); + } + // Add the invitation channels: + foreach($this->getInvitations() as $channelID) { + $channelName = $this->getChannelNameFromChannelID($channelID); + if($channelName !== null && !in_array($channelName, $channelNames)) { + array_push($channelNames, $channelName); + } + } + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/list '.implode(' ', $channelNames) + ); + } + + function insertParsedMessageWhereis($textParts) { + if(count($textParts) == 1) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingUserName' + ); + } else { + // Get UserID from UserName: + $whereisUserID = $this->getIDFromName($textParts[1]); + if($whereisUserID === null) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UserNameNotFound '.$textParts[1] + ); + } else { + $channelID = $this->getChannelFromID($whereisUserID); + if($this->validateChannel($channelID)) { + $channelName = $this->getChannelNameFromChannelID($channelID); + } else { + $channelName = null; + } + if($channelName === null) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UserNameNotFound '.$textParts[1] + ); + } else { + // List user information: + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/whereis '.$textParts[1].' '.$channelName + ); + } + } + } + } + + function insertParsedMessageWhois($textParts) { + // Only moderators/admins: + if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == PURPLE || $this->getUserRole() == CMOD) { +// if($this->getUserRole() == AJAX_CHAT_ADMIN) { + if(count($textParts) == 1) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingUserName' + ); + } else { + // Get UserID from UserName: + $whoisUserID = $this->getIDFromName($textParts[1]); + if($whoisUserID === null) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UserNameNotFound '.$textParts[1] + ); + } else { + // List user information: + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/whois '.$textParts[1].' '.$this->getIPFromID($whoisUserID) + ); + } + } + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error CommandNotAllowed '.$textParts[0] + ); + } + } + + function insertParsedMessageRoll($textParts) { + if(count($textParts) == 1) { + // default is one d6: + $text = '/roll '.$this->getUserName().' 1d6 '.$this->rollDice(6); + } else { + $diceParts = explode('d', $textParts[1]); + if(count($diceParts) == 2) { + $number = (int)$diceParts[0]; + $sides = (int)$diceParts[1]; + + // Dice number must be an integer between 1 and 100, else roll only one: + $number = ($number > -1 && $number < 100) ? $number : 1; + + // Sides must be an integer between 1 and 100, else take 6: + $sides = ($sides > -1 && $sides < 100) ? $sides : 6; + + $text = '/roll '.$this->getUserName().' '.$number.'d'.$sides.' '; + for($i=0; $i<$number; $i++) { + if($i != 0) + $text .= ','; + switch($this->getUserID()) { // snowflake + case 3://303: + $text .= str_shuffle('bird'); + break; + + case 0://230: + $text .= str_shuffle('portugal'); + break; + + case 15://21: + $text .= str_shuffle('divorce'); + break; + + case 2://8: + $text .= str_shuffle('mewow'); + break; + + default: + $text .= $this->rollDice($sides); + } + } + } else { + // if dice syntax is invalid, roll one d6: + $text = '/roll '.$this->getUserName().' 1d6 '.$this->rollDice(6); + } + } + $this->insertChatBotMessage( + $this->getChannel(), + $text + ); + } + + function insertParsedMessageNick($textParts) { + if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == PURPLE || $this->getUserRole() == CMOD || $this->getUserRole() == BOTS || $this->getUserRole() == DONATOR) { + if(!$this->getConfig('allowNickChange') || + (!$this->getConfig('allowGuestUserName') && $this->getUserRole() == AJAX_CHAT_GUEST)) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error CommandNotAllowed '.$textParts[0] + ); + } elseif(count($textParts) == 1) { + $oldUserName = $this->getUserName(); + $newUserName = $this->getLoginUserName(); + if($oldUserName != $newUserName) { + $this->setUserName($newUserName); + $this->updateOnlineList(); + // Add info message to update the client-side stored userName: + $this->addInfoMessage($this->getUserName(), 'userName'); + $this->insertChatBotMessage( + $this->getChannel(), + '/nick '.$oldUserName.' '.$newUserName, + null, + 2 + ); + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingUserName' + ); + } + } else { + $newUserName = implode(' ', array_slice($textParts, 1)); + if($newUserName == $this->getLoginUserName()) { + // Allow the user to regain the original login userName: + $prefix = ''; + $suffix = ''; + } else if($this->getUserRole() == AJAX_CHAT_GUEST) { + $prefix = $this->getConfig('guestUserPrefix'); + $suffix = $this->getConfig('guestUserSuffix'); + } else { + $prefix = $this->getConfig('changedNickPrefix'); + $suffix = $this->getConfig('changedNickSuffix'); + } + $maxLength = $this->getConfig('userNameMaxLength') + - $this->stringLength($prefix) + - $this->stringLength($suffix); + $newUserName = $this->trimString($newUserName, 'UTF-8', $maxLength, true); + if(!$newUserName) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error InvalidUserName' + ); + } else { + $newUserName = $prefix.$newUserName.$suffix; + if($this->isUserNameInUse($newUserName)) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error UserNameInUse' + ); + } else { + $oldUserName = $this->getUserName(); + $this->setUserName($newUserName); + $this->updateOnlineList(); + // Add info message to update the client-side stored userName: + $this->addInfoMessage($this->getUserName(), 'userName'); + $this->insertChatBotMessage( + $this->getChannel(), + '/nick '.$oldUserName.' '.$newUserName, + null, + 2 + ); + } + } + } + } else { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error CommandNotAllowed '.$textParts[0] + ); + } + } + + function insertParsedMessageChangeNick($textParts) { + if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR) { + if(count($textParts) == 1) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MissingUserName' + ); + } else { + $newUserName = implode(' ', array_slice($textParts, 1)); + $oldUserName = $this->getUserName(); + $this->setUserName($newUserName); + $this->updateOnlineList(); + $this->addInfoMessage($this->getUserName(), 'userName'); + } + } + } + + function insertMessage($text) { + if(!$this->isAllowedToWriteMessage()) + return; + + if(!$this->floodControl()) + return; + + $text = $this->trimMessageText($text); + if($text == '') + return; + + if(!$this->onNewMessage($text)) + return; + + $text = $this->replaceCustomText($text); + + $this->insertParsedMessage($text); + } + + function deleteMessage($messageID) { + // Retrieve the channel of the given message: + $sql = 'SELECT + channel + FROM + '.$this->getDataBaseTable('messages').' + WHERE + id='.$this->db->makeSafe($messageID).';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + $row = $result->fetch(); + + if($row['channel'] !== null) { + $channel = $row['channel']; + + if($this->getUserRole() == AJAX_CHAT_ADMIN) { + $condition = ''; + } else if($this->getUserRole() == CMOD || $this->getUserRole() == PURPLE) { + $condition = ' AND + NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_MODERATOR).') + AND + NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_ADMIN).') + AND + NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_CHATBOT).')'; + } else if($this->getUserRole() == AJAX_CHAT_MODERATOR) { + $condition = ' AND + NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_ADMIN).') + AND + NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_CHATBOT).')'; + } else if($this->getUserRole() == AJAX_CHAT_USER && $this->getConfig('allowUserMessageDelete')) { + $condition = 'AND + ( + userID='.$this->db->makeSafe($this->getUserID()).' + OR + ( + channel = '.$this->db->makeSafe($this->getPrivateMessageID()).' + OR + channel = '.$this->db->makeSafe($this->getPrivateChannelID()).' + ) + AND + NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_ADMIN).') + AND + NOT (userRole='.$this->db->makeSafe(AJAX_CHAT_CHATBOT).') + )'; + } else { + return false; + } + + // Remove given message from the database: + $sql = 'DELETE FROM + '.$this->getDataBaseTable('messages').' + WHERE + id='.$this->db->makeSafe($messageID).' + '.$condition.';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + if($result->affectedRows() == 1) { + // Insert a deletion command to remove the message from the clients chatlists: + $this->insertChatBotMessage($channel, '/delete '.$messageID); + return true; + } + } + return false; + } + + function floodControl() { + // Admins can do whatever the fuck they want: + if($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserID() == 11) { + return true; + } + $time = time(); + // Check the time of the last inserted message: + if($this->getInsertedMessagesRateTimeStamp()+60 < $time) { + $this->setInsertedMessagesRateTimeStamp($time); + $this->setInsertedMessagesRate(1); + } else { + // Increase the inserted messages rate: + $rate = $this->getInsertedMessagesRate()+1; + $this->setInsertedMessagesRate($rate); + // Check if message rate is too high: + if($rate > $this->getConfig('maxMessageRate')) { + $this->insertChatBotMessage( + $this->getPrivateMessageID(), + '/error MaxMessageRate' + ); + $this->kickUser($this->getUserName(), 10, $this->getUserID()); + $this->insertChatBotMessage($this->getChannel(), "[i][b]".$this->getUsername()."[/b] exceeded the message limit and will now be kicked for 10 minutes.[/i]"); + $this->insertChatBotMessage($this->getChannel(), "/kick ". $this->getUsername()); + // Return false so the message is not inserted: + return false; + } + } + return true; + } + + function isAllowedToWriteMessage() { + if($this->getUserRole() != AJAX_CHAT_GUEST) + return true; + if($this->getConfig('allowGuestWrite')) + return true; + return false; + } + + function insertChatBotMessage($channelID, $messageText, $ip=null, $mode=0) { + $this->insertCustomMessage( + $this->getConfig('chatBotID'), + $this->getConfig('chatBotName'), + AJAX_CHAT_CHATBOT, + $channelID, + $messageText, + $ip, + $mode + ); + } + + function insertCustomMessage($userID, $userName, $userRole, $channelID, $text, $ip=null, $mode=0) { + // The $mode parameter is used for socket updates: + // 0 = normal messages + // 1 = channel messages (e.g. login/logout, channel enter/leave, kick) + // 2 = messages with online user updates (nick) + + $ip = $ip ? $ip : $_SERVER['REMOTE_ADDR']; + + $sql = 'INSERT INTO '.$this->getDataBaseTable('messages').'( + userID, + userName, + userRole, + channel, + dateTime, + ip, + text + ) + VALUES ( + '.$this->db->makeSafe($userID).', + '.$this->db->makeSafe($userName).', + '.$this->db->makeSafe($userRole).', + '.$this->db->makeSafe($channelID).', + NOW(), + '.$this->db->makeSafe($this->ipToStorageFormat($ip)).', + '.$this->db->makeSafe($text).' + );'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + if($this->getConfig('socketServerEnabled')) { + $this->sendSocketMessage( + $this->getSocketBroadcastMessage( + $this->db->getLastInsertedID(), + time(), + $userID, + $userName, + $userRole, + $channelID, + $text, + $mode + ) + ); + } + } + + function getSocketBroadcastMessage( + $messageID, + $timeStamp, + $userID, + $userName, + $userRole, + $channelID, + $text, + $mode + ) { + // The $mode parameter: + // 0 = normal messages + // 1 = channel messages (e.g. login/logout, channel enter/leave, kick) + // 2 = messages with online user updates (nick) + + // Get the message XML content: + $xml = ''; + if($mode) { + // Add the list of online users if the user list has been updated ($mode > 0): + $xml .= $this->getChatViewOnlineUsersXML(array($channelID)); + } + if($mode != 1 || $this->getConfig('showChannelMessages')) { + $xml .= ''; + $xml .= $this->getChatViewMessageXML( + $messageID, + $timeStamp, + $userID, + $userName, + $userRole, + $channelID, + $text + ); + $xml .= ''; + } + $xml .= ''; + return $xml; + } + + function sendSocketMessage($message) { + // Open a TCP socket connection to the socket server: + if($socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) { + if(@socket_connect($socket, $this->getConfig('socketServerIP'), $this->getConfig('socketServerPort'))) { + // Append a null-byte to the string as EOL (End Of Line) character + // which is required by Flash XML socket communication: + $message .= "\0"; + @socket_write( + $socket, + $message, + strlen($message) // Using strlen to count the bytes instead of the number of UTF-8 characters + ); + } + @socket_close($socket); + } + } + + function updateSocketAuthentication($userID, $socketRegistrationID=null, $channels=null) { + // If no $socketRegistrationID or no $channels are given the authentication is removed for the given user: + $authentication = ''; + if($channels) { + foreach($channels as $channelID) { + $authentication .= ''; + } + } + $authentication .= ''; + $this->sendSocketMessage($authentication); + } + + function setSocketRegistrationID($value) { + $this->setSessionVar('SocketRegistrationID', $value); + } + + function getSocketRegistrationID() { + return $this->getSessionVar('SocketRegistrationID'); + } + + function rollDice($sides) { + // seed with microseconds since last "whole" second: + //mt_srand((double)microtime()*1000000); + + return mt_rand(1, $sides); + } + + function kickUser($userName, $banMinutes=null, $userID=null) { + if($userID === null) { + $userID = $this->getIDFromName($userName); + } + if($userID === null) { + return; + } + + $banMinutes = ($banMinutes !== null) ? $banMinutes : $this->getConfig('defaultBanTime'); + + if($banMinutes) { + // Ban User for the given time in minutes: + $this->banUser($userName, $banMinutes, $userID); + } + + // Remove given User from online list: + $sql = 'DELETE FROM + '.$this->getDataBaseTable('online').' + WHERE + userID = '.$this->db->makeSafe($userID).';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + // Update the socket server authentication for the kicked user: + if($this->getConfig('socketServerEnabled')) { + $this->updateSocketAuthentication($userID); + } + + $this->removeUserFromOnlineUsersData($userID); + } + + function getBannedUsersData($key=null, $value=null) { + if($this->_bannedUsersData === null) { + $this->_bannedUsersData = array(); + + $sql = 'SELECT + userID, + userName, + ip + FROM + '.$this->getDataBaseTable('bans').' + WHERE + NOW() < dateTime;'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + while($row = $result->fetch()) { + $row['ip'] = $this->ipFromStorageFormat($row['ip']); + array_push($this->_bannedUsersData, $row); + } + + $result->free(); + } + + if($key) { + $bannedUsersData = array(); + foreach($this->_bannedUsersData as $bannedUserData) { + if(!isset($bannedUserData[$key])) { + return $bannedUsersData; + } + if($value) { + if($bannedUserData[$key] == $value) { + array_push($bannedUsersData, $bannedUserData); + } else { + continue; + } + } else { + array_push($bannedUsersData, $bannedUserData[$key]); + } + } + return $bannedUsersData; + } + + return $this->_bannedUsersData; + } + + function getBannedUsers() { + return $this->getBannedUsersData('userName'); + } + + function banUser($userName, $banMinutes=null, $userID=null) { + if($userID === null) { + $userID = $this->getIDFromName($userName); + } + $ip = $this->getIPFromID($userID); + if(!$ip || $userID === null) { + return; + } + + // Remove expired bans: + $this->removeExpiredBans(); + + $banMinutes = (int)$banMinutes; + if(!$banMinutes) { + // If banMinutes is not a valid integer, use the defaultBanTime: + $banMinutes = $this->getConfig('defaultBanTime'); + } + + $sql = 'INSERT INTO '.$this->getDataBaseTable('bans').'( + userID, + userName, + dateTime, + ip + ) + VALUES ( + '.$this->db->makeSafe($userID).', + '.$this->db->makeSafe($userName).', + DATE_ADD(NOW(), interval '.$this->db->makeSafe($banMinutes).' MINUTE), + '.$this->db->makeSafe($this->ipToStorageFormat($ip)).' + );'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + } + + function unbanUser($userName) { + $sql = 'DELETE FROM + '.$this->getDataBaseTable('bans').' + WHERE + userName = '.$this->db->makeSafe($userName).';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + } + + function removeExpiredBans() { + $sql = 'DELETE FROM + '.$this->getDataBaseTable('bans').' + WHERE + dateTime < NOW();'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + } + + function setInactive($userID, $userName=null) { + $condition = 'userID='.$this->db->makeSafe($userID); + if($userName !== null) { + $condition .= ' OR userName='.$this->db->makeSafe($userName); + } + $sql = 'UPDATE + '.$this->getDataBaseTable('online').' + SET + dateTime = DATE_SUB(NOW(), interval '.(intval($this->getConfig('inactiveTimeout'))+1).' MINUTE) + WHERE + '.$condition.';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + $this->resetOnlineUsersData(); + } + + function removeInactive() { + $sql = 'SELECT + userID, + userName, + channel + FROM + '.$this->getDataBaseTable('online').' + WHERE + NOW() > DATE_ADD(dateTime, interval '.$this->getConfig('inactiveTimeout').' MINUTE);'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + if($result->numRows() > 0) { + $condition = ''; + while($row = $result->fetch()) { + if(!empty($condition)) + $condition .= ' OR '; + // Add userID to condition for removal: + $condition .= 'userID='.$this->db->makeSafe($row['userID']); + + // Update the socket server authentication for the kicked user: + if($this->getConfig('socketServerEnabled')) { + $this->updateSocketAuthentication($row['userID']); + } + + $this->removeUserFromOnlineUsersData($row['userID']); + + // Insert logout timeout message: + $text = '/logout '.$row['userName'].' Timeout'; + $this->insertChatBotMessage( + $row['channel'], + $text, + null, + 1 + ); + } + + $result->free(); + + $sql = 'DELETE FROM + '.$this->getDataBaseTable('online').' + WHERE + '.$condition.';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + } + } + + function updateOnlineStatus() { + // Update online status every 50 seconds (this allows update requests to be in time): + if(!$this->getStatusUpdateTimeStamp() || ((time() - $this->getStatusUpdateTimeStamp()) > 50)) { + $this->updateOnlineList(); + $this->setStatusUpdateTimeStamp(time()); + } + } + + function checkAndRemoveInactive() { + // Remove inactive users every inactiveCheckInterval: + if(!$this->getInactiveCheckTimeStamp() || ((time() - $this->getInactiveCheckTimeStamp()) > $this->getConfig('inactiveCheckInterval')*60)) { + $this->removeInactive(); + $this->setInactiveCheckTimeStamp(time()); + } + } + + function sendXMLMessages() { + $httpHeader = new AJAXChatHTTPHeader('UTF-8', 'text/xml'); + + // Send HTTP header: + $httpHeader->send(); + + // Output XML messages: + echo $this->getXMLMessages(); + } + + function getXMLMessages() { + switch($this->getView()) { + case 'chat': + return $this->getChatViewXMLMessages(); + case 'teaser': + return $this->getTeaserViewXMLMessages(); + case 'logs': + return $this->getLogsViewXMLMessages(); + default: + return $this->getLogoutXMLMessage(); + } + } + + function getMessageCondition() { + $condition = 'id > '.$this->db->makeSafe($this->getRequestVar('lastID')).' + AND ( + channel = '.$this->db->makeSafe($this->getChannel()).' + OR + channel = '.$this->db->makeSafe($this->getPrivateMessageID()).' + ) + AND + '; + if($this->getConfig('requestMessagesPriorChannelEnter') || + ($this->getConfig('requestMessagesPriorChannelEnterList') && in_array($this->getChannel(), $this->getConfig('requestMessagesPriorChannelEnterList')))) { + $condition .= 'NOW() < DATE_ADD(dateTime, interval '.$this->getConfig('requestMessagesTimeDiff').' HOUR)'; + } else { + $condition .= 'dateTime >= \''.date('Y-m-d H:i:s', $this->getChannelEnterTimeStamp()).'\''; + } + return $condition; + } + + function getMessageFilter() { + $filterChannelMessages = ''; + if(!$this->getConfig('showChannelMessages') || $this->getRequestVar('shoutbox')) { + $filterChannelMessages = ' AND NOT ( + text LIKE (\'/login%\') + OR + text LIKE (\'/logout%\') + OR + text LIKE (\'/channelEnter%\') + OR + text LIKE (\'/channelLeave%\') + OR + text LIKE (\'/kick%\') + )'; + } + return $filterChannelMessages; + } + + function getInfoMessagesXML() { + $xml = ''; + // Go through the info messages: + foreach($this->getInfoMessages() as $type=>$infoArray) { + foreach($infoArray as $info) { + $xml .= ''; + $xml .= 'encodeSpecialChars($info).']]>'; + $xml .= ''; + } + } + $xml .= ''; + return $xml; + } + + function getChatViewOnlineUsersXML($channelIDs) { + // Get the online users for the given channels: + $onlineUsersData = $this->getOnlineUsersData($channelIDs); + $xml = ''; + foreach($onlineUsersData as $onlineUserData) { + $xml .= 'encodeSpecialChars($onlineUserData['userName']).']]>'; + $xml .= ''; + } + $xml .= ''; + return $xml; + } + + function getLogoutXMLMessage() { + $xml = ''; + $xml .= ''; + $xml .= ''; + $xml .= ''; + $xml .= 'encodeSpecialChars($this->getConfig('logoutData')).']]>'; + $xml .= ''; + $xml .= ''; + $xml .= ''; + return $xml; + } + + function getChatViewMessageXML( + $messageID, + $timeStamp, + $userID, + $userName, + $userRole, + $channelID, + $text + ) { + $message = 'encodeSpecialChars($userName).']]>'; + $message .= 'encodeSpecialChars($text).']]>'; + $message .= ''; + return $message; + } + + function getChatViewMessagesXML() { + // Get the last messages in descending order (this optimises the LIMIT usage): + $sql = 'SELECT + id, + userID, + userName, + userRole, + channel AS channelID, + UNIX_TIMESTAMP(dateTime) AS timeStamp, + text + FROM + '.$this->getDataBaseTable('messages').' + WHERE + '.$this->getMessageCondition().' + '.$this->getMessageFilter().' + ORDER BY + id + DESC + LIMIT '.$this->getConfig('requestMessagesLimit').';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + $messages = ''; + + // Add the messages in reverse order so it is ascending again: + while($row = $result->fetch()) { + $message = $this->getChatViewMessageXML( + $row['id'], + $row['timeStamp'], + $row['userID'], + $row['userName'], + $row['userRole'], + $row['channelID'], + $row['text'] + ); + $messages = $message.$messages; + } + $result->free(); + + $messages = ''.$messages.''; + return $messages; + } + + function getChatViewXMLMessages() { + $xml = ''; + $xml .= ''; + $xml .= $this->getInfoMessagesXML(); + $xml .= $this->getChatViewOnlineUsersXML(array($this->getChannel())); + $xml .= $this->getChatViewMessagesXML(); + $xml .= ''; + return $xml; + } + + function getTeaserMessageCondition() { + $channelID = $this->getValidRequestChannelID(); + $condition = 'channel = '.$this->db->makeSafe($channelID).' + AND + '; + if($this->getConfig('requestMessagesPriorChannelEnter') || + ($this->getConfig('requestMessagesPriorChannelEnterList') && in_array($channelID, $this->getConfig('requestMessagesPriorChannelEnterList')))) { + $condition .= 'NOW() < DATE_ADD(dateTime, interval '.$this->getConfig('requestMessagesTimeDiff').' HOUR)'; + } else { + // Teaser content may not be shown for this channel: + $condition .= '0 = 1'; + } + return $condition; + } + + function getTeaserViewMessagesXML() { + // Get the last messages in descending order (this optimises the LIMIT usage): + $sql = 'SELECT + id, + userID, + userName, + userRole, + channel AS channelID, + UNIX_TIMESTAMP(dateTime) AS timeStamp, + text + FROM + '.$this->getDataBaseTable('messages').' + WHERE + '.$this->getTeaserMessageCondition().' + '.$this->getMessageFilter().' + ORDER BY + id + DESC + LIMIT '.$this->getConfig('requestMessagesLimit').';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + $messages = ''; + + // Add the messages in reverse order so it is ascending again: + while($row = $result->fetch()) { + $message = ''; + $message .= 'encodeSpecialChars($row['userName']).']]>'; + $message .= 'encodeSpecialChars($row['text']).']]>'; + $message .= ''; + $messages = $message.$messages; + } + $result->free(); + + $messages = ''.$messages.''; + return $messages; + } + + function getTeaserViewXMLMessages() { + $xml = ''; + $xml .= ''; + $xml .= $this->getInfoMessagesXML(); + $xml .= $this->getTeaserViewMessagesXML(); + $xml .= ''; + return $xml; + } + + function getLogsViewCondition() { + $condition = 'id > '.$this->db->makeSafe($this->getRequestVar('lastID')); + + // Check the channel condition: + switch($this->getRequestVar('channelID')) { + case '-3': + // Just display messages from all accessible channels + if($this->getUserRole() != AJAX_CHAT_ADMIN) { + $condition .= ' AND (channel = '.$this->db->makeSafe($this->getPrivateMessageID()); + $condition .= ' OR channel = '.$this->db->makeSafe($this->getPrivateChannelID()); + foreach($this->getChannels() as $channel) { + if($this->getConfig('logsUserAccessChannelList') && !in_array($channel, $this->getConfig('logsUserAccessChannelList'))) { + continue; + } + $condition .= ' OR channel = '.$this->db->makeSafe($channel); + } + $condition .= ')'; + } + break; + case '-2': + if($this->getUserRole() != AJAX_CHAT_ADMIN) { + $condition .= ' AND channel = '.($this->getPrivateMessageID()); + } else { + $condition .= ' AND channel > '.($this->getConfig('privateMessageDiff')-1); + } + break; + case '-1': + if($this->getUserRole() != AJAX_CHAT_ADMIN) { + $condition .= ' AND channel = '.($this->getPrivateChannelID()); + } else { + $condition .= ' AND (channel > '.($this->getConfig('privateChannelDiff')-1).' AND channel < '.($this->getConfig('privateMessageDiff')).')'; + } + break; + default: + if(($this->getUserRole() == AJAX_CHAT_ADMIN || !$this->getConfig('logsUserAccessChannelList') || in_array($this->getRequestVar('channelID'), $this->getConfig('logsUserAccessChannelList'))) + && $this->validateChannel($this->getRequestVar('channelID'))) { + $condition .= ' AND channel = '.$this->db->makeSafe($this->getRequestVar('channelID')); + } else { + // No valid channel: + $condition .= ' AND 0 = 1'; + } + } + + // Check the period condition: + $hour = ($this->getRequestVar('hour') === null || $this->getRequestVar('hour') > 23 || $this->getRequestVar('hour') < 0) ? null : $this->getRequestVar('hour'); + $day = ($this->getRequestVar('day') === null || $this->getRequestVar('day') > 31 || $this->getRequestVar('day') < 1) ? null : $this->getRequestVar('day'); + $month = ($this->getRequestVar('month') === null || $this->getRequestVar('month') > 12 || $this->getRequestVar('month') < 1) ? null : $this->getRequestVar('month'); + $year = ($this->getRequestVar('year') === null || $this->getRequestVar('year') > date('Y') || $this->getRequestVar('year') < $this->getConfig('logsFirstYear')) ? null : $this->getRequestVar('year'); + + // If a time (hour) is given but no date (year, month, day), use the current date: + if($hour !== null) { + if($day === null) + $day = date('j'); + if($month === null) + $month = date('n'); + if($year === null) + $year = date('Y'); + } + + if($year === null) { + // No year given, so no period condition + } else if($month === null) { + // Define the given year as period: + $periodStart = mktime(0, 0, 0, 1, 1, $year); + // The last day in a month can be expressed by using 0 for the day of the next month: + $periodEnd = mktime(23, 59, 59, 13, 0, $year); + } else if($day === null) { + // Define the given month as period: + $periodStart = mktime(0, 0, 0, $month, 1, $year); + // The last day in a month can be expressed by using 0 for the day of the next month: + $periodEnd = mktime(23, 59, 59, $month+1, 0, $year); + } else if($hour === null){ + // Define the given day as period: + $periodStart = mktime(0, 0, 0, $month, $day, $year); + $periodEnd = mktime(23, 59, 59, $month, $day, $year); + } else { + // Define the given hour as period: + $periodStart = mktime($hour, 0, 0, $month, $day, $year); + $periodEnd = mktime($hour, 59, 59, $month, $day, $year); + } + + if(isset($periodStart)) + $condition .= ' AND dateTime > \''.date('Y-m-d H:i:s', $periodStart).'\' AND dateTime <= \''.date('Y-m-d H:i:s', $periodEnd).'\''; + + // Check the search condition: + if($this->getRequestVar('search')) { + if(($this->getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == PURPLE || $this->getUserRole() == CMOD) && strpos($this->getRequestVar('search'), 'ip=') === 0) { + // Search for messages with the given IP: + $ip = substr($this->getRequestVar('search'), 3); + $condition .= ' AND (ip = '.$this->db->makeSafe($this->ipToStorageFormat($ip)).')'; + } else if(strpos($this->getRequestVar('search'), 'userID=') === 0) { + // Search for messages with the given userID: + $userID = substr($this->getRequestVar('search'), 7); + $condition .= ' AND (userID = '.$this->db->makeSafe($userID).')'; + } else { + // Use the search value as regular expression on message text and username: + $condition .= ' AND (userName REGEXP '.$this->db->makeSafe($this->getRequestVar('search')).' OR text REGEXP '.$this->db->makeSafe($this->getRequestVar('search')).')'; + } + } + + // If no period or search condition is given, just monitor the last messages on the given channel: + if(!isset($periodStart) && !$this->getRequestVar('search')) { + $condition .= ' AND NOW() < DATE_ADD(dateTime, interval '.$this->getConfig('logsRequestMessagesTimeDiff').' HOUR)'; + } + + return $condition; + } + + function getLogsViewMessagesXML() { + $sql = 'SELECT + id, + userID, + userName, + userRole, + channel AS channelID, + UNIX_TIMESTAMP(dateTime) AS timeStamp, + ip, + text + FROM + '.$this->getDataBaseTable('messages').' + WHERE + '.$this->getLogsViewCondition().' + ORDER BY + id + LIMIT '.$this->getConfig('logsRequestMessagesLimit').';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + $xml = ''; + while($row = $result->fetch()) { + $xml .= 'getUserRole() == AJAX_CHAT_ADMIN || $this->getUserRole() == AJAX_CHAT_MODERATOR || $this->getUserRole() == PURPLE) { + $xml .= ' ip="'.$this->ipFromStorageFormat($row['ip']).'"'; + } + $xml .= '>'; + $xml .= 'encodeSpecialChars($row['userName']).']]>'; + $xml .= 'encodeSpecialChars($row['text']).']]>'; + $xml .= ''; + } + $result->free(); + + $xml .= ''; + + return $xml; + } + + function getLogsViewXMLMessages() { + $xml = ''; + $xml .= ''; + $xml .= $this->getInfoMessagesXML(); + $xml .= $this->getLogsViewMessagesXML(); + $xml .= ''; + return $xml; + } + + function purgeLogs() { + $sql = 'DELETE FROM + '.$this->getDataBaseTable('messages').' + WHERE + dateTime < DATE_SUB(NOW(), interval '.$this->getConfig('logsPurgeTimeDiff').' DAY);'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + } + + function getInfoMessages($type=null) { + if(!isset($this->_infoMessages)) { + $this->_infoMessages = array(); + } + if($type) { + if(!isset($this->_infoMessages[$type])) { + $this->_infoMessages[$type] = array(); + } + return $this->_infoMessages[$type]; + } else { + return $this->_infoMessages; + } + } + + function addInfoMessage($info, $type='error') { + if(!isset($this->_infoMessages)) { + $this->_infoMessages = array(); + } + if(!isset($this->_infoMessages[$type])) { + $this->_infoMessages[$type] = array(); + } + if(!in_array($info, $this->_infoMessages[$type])) { + array_push($this->_infoMessages[$type], $info); + } + } + + function getRequestVars() { + return $this->_requestVars; + } + + function getRequestVar($key) { + if($this->_requestVars && isset($this->_requestVars[$key])) { + return $this->_requestVars[$key]; + } + return null; + } + + function setRequestVar($key, $value) { + if(!$this->_requestVars) { + $this->_requestVars = array(); + } + $this->_requestVars[$key] = $value; + } + + function getOnlineUsersData($channelIDs=null, $key=null, $value=null) { + if($this->_onlineUsersData === null) { + $this->_onlineUsersData = array(); + + $sql = 'SELECT + userID, + userName, + userRole, + channel, + UNIX_TIMESTAMP(dateTime) AS timeStamp, + ip + FROM + '.$this->getDataBaseTable('online').' + ORDER BY + userName;'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + while($row = $result->fetch()) { + $row['ip'] = $this->ipFromStorageFormat($row['ip']); + array_push($this->_onlineUsersData, $row); + } + + $result->free(); + } + + if($channelIDs || $key) { + $onlineUsersData = array(); + foreach($this->_onlineUsersData as $userData) { + if($channelIDs && !in_array($userData['channel'], $channelIDs)) { + continue; + } + if($key) { + if(!isset($userData[$key])) { + return $onlineUsersData; + } + if($value !== null) { + if($userData[$key] == $value) { + array_push($onlineUsersData, $userData); + } else { + continue; + } + } else { + array_push($onlineUsersData, $userData[$key]); + } + } else { + array_push($onlineUsersData, $userData); + } + } + return $onlineUsersData; + } + + return $this->_onlineUsersData; + } + + function removeUserFromOnlineUsersData($userID=null) { + if(!$this->_onlineUsersData) { + return; + } + $userID = ($userID === null) ? $this->getUserID() : $userID; + for($i=0; $i_onlineUsersData); $i++) { + if($this->_onlineUsersData[$i]['userID'] == $userID) { + array_splice($this->_onlineUsersData, $i, 1); + break; + } + } + } + + function resetOnlineUsersData() { + $this->_onlineUsersData = null; + } + + function getOnlineUsers($channelIDs=null) { + return $this->getOnlineUsersData($channelIDs, 'userName'); + } + + function getOnlineUserIDs($channelIDs=null) { + return $this->getOnlineUsersData($channelIDs, 'userID'); + } + + function startSession() { + if(!session_id()) { + // Set the session name: + session_name($this->getConfig('sessionName')); + + // Set session cookie parameters: + session_set_cookie_params( + 0, // The session is destroyed on logout anyway, so no use to set this + $this->getConfig('sessionCookiePath'), + $this->getConfig('sessionCookieDomain'), + $this->getConfig('sessionCookieSecure') + ); + + // Start the session: + session_start(); + + // We started a new session: + $this->_sessionNew = true; + } + } + + function destroySession() { + if($this->_sessionNew) { + // Delete all session variables: + $_SESSION = array(); + + // Delete the session cookie: + if (isset($_COOKIE[session_name()])) { + setcookie( + session_name(), + '', + time()-42000, + $this->getConfig('sessionCookiePath'), + $this->getConfig('sessionCookieDomain'), + $this->getConfig('sessionCookieSecure') + ); + } + + // Destroy the session: + session_destroy(); + } else { + // Unset all session variables starting with the sessionKeyPrefix: + foreach($_SESSION as $key=>$value) { + if(strpos($key, $this->getConfig('sessionKeyPrefix')) === 0) { + unset($_SESSION[$key]); + } + } + } + } + + function regenerateSessionID() { + if($this->_sessionNew) { + // Regenerate session id: + @session_regenerate_id(true); + } + } + + function getSessionVar($key, $prefix=null) { + if($prefix === null) + $prefix = $this->getConfig('sessionKeyPrefix'); + + // Return the session value if existing: + if(isset($_SESSION[$prefix.$key])) + return $_SESSION[$prefix.$key]; + else + return null; + } + + function setSessionVar($key, $value, $prefix=null) { + if($prefix === null) + $prefix = $this->getConfig('sessionKeyPrefix'); + + // Set the session value: + $_SESSION[$prefix.$key] = $value; + } + + function getSessionIP() { + return $this->getSessionVar('IP'); + } + + function setSessionIP($ip) { + $this->setSessionVar('IP', $ip); + } + + function getQueryUserName() { + return $this->getSessionVar('QueryUserName'); + } + + function setQueryUserName($userName) { + $this->setSessionVar('QueryUserName', $userName); + } + + function getInvitations() { + if($this->_invitations === null) { + $this->_invitations = array(); + + $sql = 'SELECT + channel + FROM + '.$this->getDataBaseTable('invitations').' + WHERE + userID='.$this->db->makeSafe($this->getUserID()).' + AND + DATE_SUB(NOW(), interval 1 DAY) < dateTime;'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + + while($row = $result->fetch()) { + array_push($this->_invitations, $row['channel']); + } + + $result->free(); + } + return $this->_invitations; + } + + function removeExpiredInvitations() { + $sql = 'DELETE FROM + '.$this->getDataBaseTable('invitations').' + WHERE + DATE_SUB(NOW(), interval 1 DAY) > dateTime;'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + } + + function addInvitation($userID, $channelID=null) { + $this->removeExpiredInvitations(); + + $channelID = ($channelID === null) ? $this->getChannel() : $channelID; + + $sql = 'INSERT INTO '.$this->getDataBaseTable('invitations').'( + userID, + channel, + dateTime + ) + VALUES ( + '.$this->db->makeSafe($userID).', + '.$this->db->makeSafe($channelID).', + NOW() + );'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + } + + function removeInvitation($userID, $channelID=null) { + $channelID = ($channelID === null) ? $this->getChannel() : $channelID; + + $sql = 'DELETE FROM + '.$this->getDataBaseTable('invitations').' + WHERE + userID='.$this->db->makeSafe($userID).' + AND + channel='.$this->db->makeSafe($channelID).';'; + + // Create a new SQL query: + $result = $this->db->sqlQuery($sql); + + // Stop if an error occurs: + if($result->error()) { + echo $result->getError(); + die(); + } + } + + function getUserID() { + return $this->getSessionVar('UserID'); + } + + function setUserID($id) { + $this->setSessionVar('UserID', $id); + } + + function getUserName() { + return $this->getSessionVar('UserName'); + } + + function setUserName($name) { + $this->setSessionVar('UserName', $name); + } + + function getLoginUserName() { + return $this->getSessionVar('LoginUserName'); + } + + function setLoginUserName($name) { + $this->setSessionVar('LoginUserName', $name); + } + + function getUserRole() { + $userRole = $this->getSessionVar('UserRole'); + if($userRole === null) + return AJAX_CHAT_GUEST; + return $userRole; + } + + function setUserRole($role) { + $this->setSessionVar('UserRole', $role); + } + + function getChannel() { + return $this->getSessionVar('Channel'); + } + + function setChannel($channel) { + $this->setSessionVar('Channel', $channel); + + // Save the channel enter timestamp: + $this->setChannelEnterTimeStamp(time()); + + // Update the channel authentication for the socket server: + if($this->getConfig('socketServerEnabled')) { + $this->updateSocketAuthentication( + $this->getUserID(), + $this->getSocketRegistrationID(), + array($channel,$this->getPrivateMessageID()) + ); + } + + // Reset the logs view socket authentication session var: + if($this->getSessionVar('logsViewSocketAuthenticated')) { + $this->setSessionVar('logsViewSocketAuthenticated', false); + } + } + + function isLoggedIn() { + return (bool)$this->getSessionVar('LoggedIn'); + } + + function setLoggedIn($bool) { + $this->setSessionVar('LoggedIn', $bool); + } + + function getLoginTimeStamp() { + return $this->getSessionVar('LoginTimeStamp'); + } + + function setLoginTimeStamp($time) { + $this->setSessionVar('LoginTimeStamp', $time); + } + + function getChannelEnterTimeStamp() { + return $this->getSessionVar('ChannelEnterTimeStamp'); + } + + function setChannelEnterTimeStamp($time) { + $this->setSessionVar('ChannelEnterTimeStamp', $time); + } + + function getStatusUpdateTimeStamp() { + return $this->getSessionVar('StatusUpdateTimeStamp'); + } + + function setStatusUpdateTimeStamp($time) { + $this->setSessionVar('StatusUpdateTimeStamp', $time); + } + + function getInactiveCheckTimeStamp() { + return $this->getSessionVar('InactiveCheckTimeStamp'); + } + + function setInactiveCheckTimeStamp($time) { + $this->setSessionVar('InactiveCheckTimeStamp', $time); + } + + function getInsertedMessagesRate() { + return $this->getSessionVar('InsertedMessagesRate'); + } + + function setInsertedMessagesRate($rate) { + $this->setSessionVar('InsertedMessagesRate', $rate); + } + + function getInsertedMessagesRateTimeStamp() { + return $this->getSessionVar('InsertedMessagesRateTimeStamp'); + } + + function setInsertedMessagesRateTimeStamp($time) { + $this->setSessionVar('InsertedMessagesRateTimeStamp', $time); + } + + function getLangCode() { + // Get the langCode from request or cookie: + $langCodeCookie = isset($_COOKIE[$this->getConfig('sessionName').'_lang']) ? $_COOKIE[$this->getConfig('sessionName').'_lang'] : null; + $langCode = $this->getRequestVar('lang') ? $this->getRequestVar('lang') : $langCodeCookie; + // Check if the langCode is valid: + if(!in_array($langCode, $this->getConfig('langAvailable'))) { + // Determine the user language: + $language = new AJAXChatLanguage($this->getConfig('langAvailable'), $this->getConfig('langDefault')); + $langCode = $language->getLangCode(); + } + return $langCode; + } + + function setLangCodeCookie() { + setcookie( + $this->getConfig('sessionName').'_lang', + $this->getLangCode(), + time()+60*60*24*$this->getConfig('sessionCookieLifeTime'), + $this->getConfig('sessionCookiePath'), + $this->getConfig('sessionCookieDomain'), + $this->getConfig('sessionCookieSecure') + ); + } + + function removeUnsafeCharacters($str) { + // Remove NO-WS-CTL, non-whitespace control characters (RFC 2822), decimal 1–8, 11–12, 14–31, and 127: + return AJAXChatEncoding::removeUnsafeCharacters($str); + } + + function subString($str, $start=0, $length=null, $encoding='UTF-8') { + return AJAXChatString::subString($str, $start, $length, $encoding); + } + + function stringLength($str, $encoding='UTF-8') { + return AJAXChatString::stringLength($str, $encoding); + } + + function trimMessageText($text) { + return $this->trimString($text, 'UTF-8', $this->getConfig('messageTextMaxLength')); + } + + function trimUserName($userName) { + return $this->trimString($userName, null, $this->getConfig('userNameMaxLength'), true, true); + } + + function trimChannelName($channelName) { + return $this->trimString($channelName, null, null, true, true); + } + + function trimString($str, $sourceEncoding=null, $maxLength=null, $replaceWhitespace=false, $decodeEntities=false, $htmlEntitiesMap=null) { + // Make sure the string contains valid unicode: + $str = $this->convertToUnicode($str, $sourceEncoding); + + // Make sure the string contains no unsafe characters: + $str = $this->removeUnsafeCharacters($str); + + // Strip whitespace from the beginning and end of the string: + $str = trim($str); + + if($replaceWhitespace) { + // Replace any whitespace in the userName with the underscore "_": + $str = preg_replace('/\s/u', '_', $str); + } + + if($decodeEntities) { + // Decode entities: + $str = $this->decodeEntities($str, 'UTF-8', $htmlEntitiesMap); + } + + if($maxLength) { + // Cut the string to the allowed length: + $str = $this->subString($str, 0, $maxLength); + } + + return $str; + } + + function convertToUnicode($str, $sourceEncoding=null) { + if($sourceEncoding === null) { + $sourceEncoding = $this->getConfig('sourceEncoding'); + } + return $this->convertEncoding($str, $sourceEncoding, 'UTF-8'); + } + + function convertFromUnicode($str, $contentEncoding=null) { + if($contentEncoding === null) { + $contentEncoding = $this->getConfig('contentEncoding'); + } + return $this->convertEncoding($str, 'UTF-8', $contentEncoding); + } + + function convertEncoding($str, $charsetFrom, $charsetTo) { + return AJAXChatEncoding::convertEncoding($str, $charsetFrom, $charsetTo); + } + + function encodeEntities($str, $encoding='UTF-8', $convmap=null) { + return AJAXChatEncoding::encodeEntities($str, $encoding, $convmap); + } + + function decodeEntities($str, $encoding='UTF-8', $htmlEntitiesMap=null) { + return AJAXChatEncoding::decodeEntities($str, $encoding, $htmlEntitiesMap); + } + + function htmlEncode($str) { + return AJAXChatEncoding::htmlEncode($str, $this->getConfig('contentEncoding')); + } + + function encodeSpecialChars($str) { + return AJAXChatEncoding::encodeSpecialChars($str); + } + + function decodeSpecialChars($str) { + return AJAXChatEncoding::decodeSpecialChars($str); + } + + function ipToStorageFormat($ip) { + if(function_exists('inet_pton')) { + // ipv4 & ipv6: + return @inet_pton($ip); + } + // Only ipv4: + return @pack('N',@ip2long($ip)); + } + + function ipFromStorageFormat($ip) { + if(function_exists('inet_ntop')) { + // ipv4 & ipv6: + return @inet_ntop($ip); + } + // Only ipv4: + $unpacked = @unpack('Nlong',$ip); + if(isset($unpacked['long'])) { + return @long2ip($unpacked['long']); + } + return null; + } + + function getConfig($key, $subkey=null) { + if($subkey) + return $this->_config[$key][$subkey]; + else + return $this->_config[$key]; + } + + function setConfig($key, $subkey, $value) { + if($subkey) { + if(!isset($this->_config[$key])) { + $this->_config[$key] = array(); + } + $this->_config[$key][$subkey] = $value; + } else { + $this->_config[$key] = $value; + } + } + + function getLang($key=null) { + if(!$this->_lang) { + // Include the language file: + $lang = null; + require AJAX_CHAT_PATH . '/lang/' . $this->getLangCode() . '.php'; + $this->_lang = &$lang; + } + if($key === null) + return $this->_lang; + if(isset($this->_lang[$key])) + return $this->_lang[$key]; + return null; + } + + function getChatURL() { + if(defined('AJAX_CHAT_URL')) { + return AJAX_CHAT_URL; + } + + return + (isset($_SERVER['HTTPS']) ? 'https://' : 'http://'). + (isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : ''). + (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME']. + (isset($_SERVER['HTTPS']) && $_SERVER['SERVER_PORT'] == 443 || $_SERVER['SERVER_PORT'] == 80 ? '' : ':'.$_SERVER['SERVER_PORT']))). + substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/')+1); + } + + function getIDFromName($userName) { + $userDataArray = $this->getOnlineUsersData(null,'userName',$userName); + if($userDataArray && isset($userDataArray[0])) { + return $userDataArray[0]['userID']; + } + return null; + } + + function getNameFromID($userID) { + $userDataArray = $this->getOnlineUsersData(null,'userID',$userID); + if($userDataArray && isset($userDataArray[0])) { + return $userDataArray[0]['userName']; + } + return null; + } + + function getChannelFromID($userID) { + $userDataArray = $this->getOnlineUsersData(null,'userID',$userID); + if($userDataArray && isset($userDataArray[0])) { + return $userDataArray[0]['channel']; + } + return null; + } + + function getIPFromID($userID) { + $userDataArray = $this->getOnlineUsersData(null,'userID',$userID); + if($userDataArray && isset($userDataArray[0])) { + return $userDataArray[0]['ip']; + } + return null; + } + + function getRoleFromID($userID) { + $userDataArray = $this->getOnlineUsersData(null,'userID',$userID); + if($userDataArray && isset($userDataArray[0])) { + return $userDataArray[0]['userRole']; + } + return null; + } + + function getChannelNames() { + return array_flip($this->getChannels()); + } + + function getChannelIDFromChannelName($channelName) { + if(!$channelName) + return null; + $channels = $this->getAllChannels(); + if(array_key_exists($channelName,$channels)) { + return $channels[$channelName]; + } + $channelID = null; + // Check if the requested channel is the own private channel: + if($channelName == $this->getPrivateChannelName()) { + return $this->getPrivateChannelID(); + } + // Try to retrieve a private room ID: + $strlenChannelName = $this->stringLength($channelName); + $strlenPrefix = $this->stringLength($this->getConfig('privateChannelPrefix')); + $strlenSuffix = $this->stringLength($this->getConfig('privateChannelSuffix')); + if($this->subString($channelName,0,$strlenPrefix) == $this->getConfig('privateChannelPrefix') + && $this->subString($channelName,$strlenChannelName-$strlenSuffix) == $this->getConfig('privateChannelSuffix')) { + $userName = $this->subString( + $channelName, + $strlenPrefix, + $strlenChannelName-($strlenPrefix+$strlenSuffix) + ); + $userID = $this->getIDFromName($userName); + if($userID !== null) { + $channelID = $this->getPrivateChannelID($userID); + } + } + return $channelID; + } + + function getChannelNameFromChannelID($channelID) { + foreach($this->getAllChannels() as $key=>$value) { + if($value == $channelID) { + return $key; + } + } + // Try to retrieve a private room name: + if($channelID == $this->getPrivateChannelID()) { + return $this->getPrivateChannelName(); + } + $userName = $this->getNameFromID($channelID-$this->getConfig('privateChannelDiff')); + if($userName === null) { + return null; + } + return $this->getPrivateChannelName($userName); + } + + function getChannelName() { + return $this->getChannelNameFromChannelID($this->getChannel()); + } + + function getPrivateChannelName($userName=null) { + if($userName === null) { + $userName = $this->getUserName(); + } + return $this->getConfig('privateChannelPrefix').$userName.$this->getConfig('privateChannelSuffix'); + } + + function getPrivateChannelID($userID=null) { + if($userID === null) { + $userID = $this->getUserID(); + } + return $userID + $this->getConfig('privateChannelDiff'); + } + + function getPrivateMessageID($userID=null) { + if($userID === null) { + $userID = $this->getUserID(); + } + return $userID + $this->getConfig('privateMessageDiff'); + } + + function isAllowedToSendPrivateMessage() { + if($this->getConfig('allowPrivateMessages') || $this->getUserRole() == AJAX_CHAT_ADMIN) { + return true; + } + return false; + } + + function isAllowedToCreatePrivateChannel() { + if($this->getConfig('allowPrivateChannels')) { + switch($this->getUserRole()) { + case DONATOR: + return true; + case BOTS: + return true; + case PURPLE: + return true; + case CMOD: + return true; + case AJAX_CHAT_MODERATOR: + return true; + case AJAX_CHAT_ADMIN: + return true; + default: + return false; + } + } + return false; + } + + function isAllowedToListHiddenUsers() { + // Hidden users are users within private or restricted channels: + switch($this->getUserRole()) { + case CMOD: + return true; + case PURPLE: + return true; + case AJAX_CHAT_MODERATOR: + return true; + case AJAX_CHAT_ADMIN: + return true; + default: + return false; + } + } + + function isUserOnline($userID=null) { + $userID = ($userID === null) ? $this->getUserID() : $userID; + $userDataArray = $this->getOnlineUsersData(null,'userID',$userID); + if($userDataArray && count($userDataArray) > 0) { + return true; + } + return false; + } + + function isUserNameInUse($userName=null) { + $userName = ($userName === null) ? $this->getUserName() : $userName; + $userDataArray = $this->getOnlineUsersData(null,'userName',$userName); + if($userDataArray && count($userDataArray) > 0) { + return true; + } + return false; + } + + function isUserBanned($userName, $userID=null, $ip=null) { + if($userID !== null) { + $bannedUserDataArray = $this->getBannedUsersData('userID',$userID); + if($bannedUserDataArray && isset($bannedUserDataArray[0])) { + return true; + } + } + if($ip !== null) { + $bannedUserDataArray = $this->getBannedUsersData('ip',$ip); + if($bannedUserDataArray && isset($bannedUserDataArray[0])) { + return true; + } + } + $bannedUserDataArray = $this->getBannedUsersData('userName',$userName); + if($bannedUserDataArray && isset($bannedUserDataArray[0])) { + return true; + } + return false; + } + + function isMaxUsersLoggedIn() { + if(count($this->getOnlineUsersData()) >= $this->getConfig('maxUsersLoggedIn')) { + return true; + } + return false; + } + + function validateChannel($channelID) { + if($channelID === null) { + return false; + } + // Return true for normal channels the user has acces to: + if(in_array($channelID, $this->getChannels())) { + return true; + } + // Return true if the user is allowed to join his own private channel: + if($channelID == $this->getPrivateChannelID() && $this->isAllowedToCreatePrivateChannel()) { + return true; + } + // Return true if the user has been invited to a restricted or private channel: + if(in_array($channelID, $this->getInvitations())) { + return true; + } + // No valid channel, return false: + return false; + } + + function createGuestUserName() { + $maxLength = $this->getConfig('userNameMaxLength') + - $this->stringLength($this->getConfig('guestUserPrefix')) + - $this->stringLength($this->getConfig('guestUserSuffix')); + + // seed with microseconds since last "whole" second: + mt_srand((double)microtime()*1000000); + + // Create a random userName using numbers between 100000 and 999999: + $userName = substr(mt_rand(100000, 999999), 0, $maxLength); + + return $this->getConfig('guestUserPrefix').$userName.$this->getConfig('guestUserSuffix'); + } + + // Guest userIDs must not interfere with existing userIDs and must be lower than privateChannelDiff: + function createGuestUserID() { + // seed with microseconds since last "whole" second: + mt_srand((double)microtime()*1000000); + + return mt_rand($this->getConfig('minGuestUserID'), $this->getConfig('privateChannelDiff')-1); + } + + function getGuestUser() { + if(!$this->getConfig('allowGuestLogins')) + return null; + + if($this->getConfig('allowGuestUserName')) { + $maxLength = $this->getConfig('userNameMaxLength') + - $this->stringLength($this->getConfig('guestUserPrefix')) + - $this->stringLength($this->getConfig('guestUserSuffix')); + + // Trim guest userName: + $userName = $this->trimString($this->getRequestVar('userName'), null, $maxLength, true, true); + + // If given userName is invalid, create one: + if(!$userName) { + $userName = $this->createGuestUserName(); + } else { + // Add the guest users prefix and suffix to the given userName: + $userName = $this->getConfig('guestUserPrefix').$userName.$this->getConfig('guestUserSuffix'); + } + } else { + $userName = $this->createGuestUserName(); + } + + $userData = array(); + $userData['userID'] = $this->createGuestUserID(); + $userData['userName'] = $userName; + $userData['userRole'] = AJAX_CHAT_GUEST; + return $userData; + } + + function getCustomVar($key) { + if(!isset($this->_customVars)) + $this->_customVars = array(); + if(!isset($this->_customVars[$key])) + return null; + return $this->_customVars[$key]; + } + + function setCustomVar($key, $value) { + if(!isset($this->_customVars)) + $this->_customVars = array(); + $this->_customVars[$key] = $value; + } + + // Override to replace custom template tags: + // Return the replacement for the given tag (and given tagContent) + function replaceCustomTemplateTags($tag, $tagContent) { + return null; + } + + // Override to initialize custom configuration settings: + function initCustomConfig() { + } + + // Override to add custom request variables: + // Add values to the request variables array: $this->_requestVars['customVariable'] = null; + function initCustomRequestVars() { + } + + // Override to add custom session code right after the session has been started: + function initCustomSession() { + } + + // Override, to parse custom info requests: + // $infoRequest contains the current info request + // Add info responses using the method addInfoMessage($info, $type) + function parseCustomInfoRequest($infoRequest) { + } + + // Override to replace custom text: + // Return replaced text + // $text contains the whole message + function replaceCustomText(&$text) { + return $text; + } + + // Override to add custom commands: + // Return true if a custom command has been successfully parsed, else false + // $text contains the whole message, $textParts the message split up as words array + function parseCustomCommands($text, $textParts) { + return false; + } + + // Override to perform custom actions on new messages: + // Return true if message may be inserted, else false + // $text contains the whole message + function onNewMessage($text) { + return true; + } + + // Override to perform custom actions on new messages: + // Method to set the style cookie depending on user data + function setStyle() { + } + + // Override: + // Returns true if the userID of the logged in user is identical to the userID of the authentication system + // or the user is authenticated as guest in the chat and the authentication system + function revalidateUserID() { + return true; + } + + // Override: + // Returns an associative array containing userName, userID and userRole + // Returns null if login is invalid + function getValidLoginUserData() { + // Check if we have a valid registered user: + if(false) { + // Here is the place to check user authentication + } else { + // Guest users: + return $this->getGuestUser(); + } + } + + // Override: + // Store the channels the current user has access to + // Make sure channel names don't contain any whitespace + function &getChannels() { + if($this->_channels === null) { + $this->_channels = $this->getAllChannels(); + } + return $this->_channels; + } + + // Override: + // Store all existing channels + // Make sure channel names don't contain any whitespace + function &getAllChannels() { + if($this->_allChannels === null) { + $this->_allChannels = array(); + + // Default channel, public to everyone: + $this->_allChannels[$this->trimChannelName($this->getConfig('defaultChannelName'))] = $this->getConfig('defaultChannelID'); + } + return $this->_allChannels; + } + +} diff --git a/src/AJAXChatDataBase.php b/src/AJAXChatDataBase.php new file mode 100644 index 0000000..d42e2a0 --- /dev/null +++ b/src/AJAXChatDataBase.php @@ -0,0 +1,80 @@ +_db = new AJAXChatDatabaseMySQLi($dbConnectionConfig); + break; + case 'mysql': + $this->_db = new AJAXChatDatabaseMySQL($dbConnectionConfig); + break; + default: + // Use MySQLi if available, else MySQL (and check the type of a given database connection object): + if(function_exists('mysqli_connect') && (!$dbConnectionConfig['link'] || is_object($dbConnectionConfig['link']))) { + $this->_db = new AJAXChatDatabaseMySQLi($dbConnectionConfig); + } else { + $this->_db = new AJAXChatDatabaseMySQL($dbConnectionConfig); + } + } + } + + // Method to connect to the DataBase server: + function connect(&$dbConnectionConfig) { + return $this->_db->connect($dbConnectionConfig); + } + + // Method to select the DataBase: + function select($dbName) { + return $this->_db->select($dbName); + } + + // Method to determine if an error has occured: + function error() { + return $this->_db->error(); + } + + // Method to return the error report: + function getError() { + return $this->_db->getError(); + } + + // Method to return the connection identifier: + function &getConnectionID() { + return $this->_db->getConnectionID(); + } + + // Method to prevent SQL injections: + function makeSafe($value) { + return $this->_db->makeSafe($value); + } + + // Method to perform SQL queries: + function sqlQuery($sql) { + return $this->_db->sqlQuery($sql); + } + + // Method to retrieve the current DataBase name: + function getName() { + return $this->_db->getName(); + //If your database has hyphens ( - ) in it, try using this instead: + //return '`'.$this->_db->getName().'`'; + } + + // Method to retrieve the last inserted ID: + function getLastInsertedID() { + return $this->_db->getLastInsertedID(); + } + +} diff --git a/src/AJAXChatEncoding.php b/src/AJAXChatEncoding.php new file mode 100644 index 0000000..b8bdb52 --- /dev/null +++ b/src/AJAXChatEncoding.php @@ -0,0 +1,137 @@ +'&', '<'=>'<', '>'=>'>', "'"=>''', '"'=>'"'); + } + return $specialChars; + } + + // Helper function to store Regular expression for NO-WS-CTL as we cannot use static class members in PHP4: + public static function getRegExp_NO_WS_CTL() { + static $regExp_NO_WS_CTL; + if(!$regExp_NO_WS_CTL) { + // Regular expression for NO-WS-CTL, non-whitespace control characters (RFC 2822), decimal 1–8, 11–12, 14–31, and 127: + $regExp_NO_WS_CTL = '/[\x0\x1\x2\x3\x4\x5\x6\x7\x8\xB\xC\xE\xF\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F]/'; + } + return $regExp_NO_WS_CTL; + } + + public static function convertEncoding($str, $charsetFrom, $charsetTo) { + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($str, $charsetTo, $charsetFrom); + } + if(function_exists('iconv')) { + return iconv($charsetFrom, $charsetTo, $str); + } + if(($charsetFrom == 'UTF-8') && ($charsetTo == 'ISO-8859-1')) { + return utf8_decode($str); + } + if(($charsetFrom == 'ISO-8859-1') && ($charsetTo == 'UTF-8')) { + return utf8_encode($str); + } + return $str; + } + + public static function htmlEncode($str, $contentCharset='UTF-8') { + switch($contentCharset) { + case 'UTF-8': + // Encode only special chars (&, <, >, ', ") as entities: + return AJAXChatEncoding::encodeSpecialChars($str); + break; + case 'ISO-8859-1': + case 'ISO-8859-15': + // Encode special chars and all extended characters above ISO-8859-1 charset as entities, then convert to content charset: + return AJAXChatEncoding::convertEncoding(AJAXChatEncoding::encodeEntities($str, 'UTF-8', array( + 0x26, 0x26, 0, 0xFFFF, // & + 0x3C, 0x3C, 0, 0xFFFF, // < + 0x3E, 0x3E, 0, 0xFFFF, // > + 0x27, 0x27, 0, 0xFFFF, // ' + 0x22, 0x22, 0, 0xFFFF, // " + 0x100, 0x2FFFF, 0, 0xFFFF // above ISO-8859-1 + )), 'UTF-8', $contentCharset); + break; + default: + // Encode special chars and all characters above ASCII charset as entities, then convert to content charset: + return AJAXChatEncoding::convertEncoding(AJAXChatEncoding::encodeEntities($str, 'UTF-8', array( + 0x26, 0x26, 0, 0xFFFF, // & + 0x3C, 0x3C, 0, 0xFFFF, // < + 0x3E, 0x3E, 0, 0xFFFF, // > + 0x27, 0x27, 0, 0xFFFF, // ' + 0x22, 0x22, 0, 0xFFFF, // " + 0x80, 0x2FFFF, 0, 0xFFFF // above ASCII + )), 'UTF-8', $contentCharset); + } + } + + public static function encodeSpecialChars($str) { + return strtr($str, AJAXChatEncoding::getSpecialChars()); + } + + public static function decodeSpecialChars($str) { + return strtr($str, array_flip(AJAXChatEncoding::getSpecialChars())); + } + + public static function encodeEntities($str, $encoding='UTF-8', $convmap=null) { + if($convmap && function_exists('mb_encode_numericentity')) { + return mb_encode_numericentity($str, $convmap, $encoding); + } + return htmlentities($str, ENT_QUOTES, $encoding); + } + + public static function decodeEntities($str, $encoding='UTF-8', $htmlEntitiesMap=null) { + // Due to PHP bug #25670, html_entity_decode does not work with UTF-8 for PHP versions < 5: + if(function_exists('html_entity_decode') && version_compare(phpversion(), 5, '>=')) { + // Replace numeric and literal entities: + $str = html_entity_decode($str, ENT_QUOTES, $encoding); + // Replace additional literal HTML entities if an HTML entities map is given: + if($htmlEntitiesMap) { + $str = strtr($str, $htmlEntitiesMap); + } + } else { + // Replace numeric entities: + $str = preg_replace('~&#([0-9]+);~e', 'AJAXChatEncoding::unicodeChar("\\1")', $str); + $str = preg_replace('~&#x([0-9a-f]+);~ei', 'AJAXChatEncoding::unicodeChar(hexdec("\\1"))', $str); + // Replace literal entities: + $htmlEntitiesMap = $htmlEntitiesMap ? $htmlEntitiesMap : array_flip(get_html_translation_table(HTML_ENTITIES, ENT_QUOTES)); + $str = strtr($str, $htmlEntitiesMap); + } + return $str; + } + + public static function unicodeChar($c) { + if($c <= 0x7F) { + return chr($c); + } else if($c <= 0x7FF) { + return chr(0xC0 | $c >> 6) . chr(0x80 | $c & 0x3F); + } else if($c <= 0xFFFF) { + return chr(0xE0 | $c >> 12) . chr(0x80 | $c >> 6 & 0x3F) + . chr(0x80 | $c & 0x3F); + } else if($c <= 0x10FFFF) { + return chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F) + . chr(0x80 | $c >> 6 & 0x3F) + . chr(0x80 | $c & 0x3F); + } else { + return null; + } + } + + public static function removeUnsafeCharacters($str) { + // Remove NO-WS-CTL, non-whitespace control characters (RFC 2822), decimal 1–8, 11–12, 14–31, and 127: + return preg_replace(AJAXChatEncoding::getRegExp_NO_WS_CTL(), '', $str); + } + +} diff --git a/public/lib/class/AJAXChatFileSystem.php b/src/AJAXChatFileSystem.php similarity index 53% rename from public/lib/class/AJAXChatFileSystem.php rename to src/AJAXChatFileSystem.php index a8c5704..cd267cb 100644 --- a/public/lib/class/AJAXChatFileSystem.php +++ b/src/AJAXChatFileSystem.php @@ -10,13 +10,12 @@ // Class to provide methods for file system access: class AJAXChatFileSystem { - public static function getFileContents($file) { - if(function_exists('file_get_contents')) { - return file_get_contents($file); - } else { - return(implode('', file($file))); - } - } + public static function getFileContents($file) { + if(function_exists('file_get_contents')) { + return file_get_contents($file); + } else { + return(implode('', file($file))); + } + } } -?> \ No newline at end of file diff --git a/src/AJAXChatHTTPHeader.php b/src/AJAXChatHTTPHeader.php new file mode 100644 index 0000000..03c515c --- /dev/null +++ b/src/AJAXChatHTTPHeader.php @@ -0,0 +1,55 @@ +_contentType = $contentType.'; charset='.$encoding; + $this->_constant = true; + } else { + if(isset($_SERVER['HTTP_ACCEPT']) && (strpos($_SERVER['HTTP_ACCEPT'],'application/xhtml+xml') !== false)) { + $this->_contentType = 'application/xhtml+xml; charset='.$encoding; + } else { + $this->_contentType = 'text/html; charset='.$encoding; + } + $this->_constant = false; + } + $this->_noCache = $noCache; + } + + // Method to send the HTTP header: + function send() { + // Prevent caching: + if($this->_noCache) { + header('Cache-Control: no-cache, must-revalidate'); + header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); + } + + // Send the content-type-header: + header('Content-Type: '.$this->_contentType); + + // Send vary header if content-type varies (important for proxy-caches): + if(!$this->_constant) { + header('Vary: Accept'); + } + } + + // Method to return the content-type string: + function getContentType() { + // Return the content-type string: + return $this->_contentType; + } + +} diff --git a/src/AJAXChatLanguage.php b/src/AJAXChatLanguage.php new file mode 100644 index 0000000..deb65f6 --- /dev/null +++ b/src/AJAXChatLanguage.php @@ -0,0 +1,101 @@ +_regExpAcceptLangCode = '/^([a-z]{1,8}(?:-[a-z]{1,8})*)(?:;\s*q=(0(?:\.[0-9]{1,3})?|1(?:\.0{1,3})?))?$/i'; + $this->_availableLangCodes = $availableLangCodes; + $this->_defaultLangCode = $defaultLangCode; + if($langCode && in_array($langCode, $availableLangCodes)) { + $this->_langCode = $langCode; + } + $this->_strictMode = $strictMode; + } + + // Method to detect the language code from the HTTP_ACCEPT_LANGUAGE header: + function detectLangCode() { + // If HTTP_ACCEPT_LANGUAGE is empty use defaultLangCode: + if(empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + $this->_langCode = $this->_defaultLangCode; + return; + } + + // Split up the HTTP_ACCEPT_LANGUAGE header: + $acceptedLanguages = preg_split('/,\s*/', $_SERVER['HTTP_ACCEPT_LANGUAGE']); + + $currentLangCode = $this->_defaultLangCode; + $currentLangQuality = 0.0; + + foreach($acceptedLanguages as $acceptedLanguage) { + // Parse the language string: + $match = preg_match($this->_regExpAcceptLangCode, $acceptedLanguage, $matches); + // Check if the syntax is valid: + if(!$match) { + continue; + } + + // Get and split the language code: + $langCodeParts = explode ('-', $matches[1]); + + // Get the language quality given as float value: + if(isset($matches[2])) { + $langQuality = (float)$matches[2]; + } else { + // Missing language quality value is maximum quality: + $langQuality = 1.0; + } + + // Go through it until the language code is empty: + while(count($langCodeParts)) { + // Join the current langCodeParts: + $langCode = strtolower(join('-', $langCodeParts)); + // Check if the langCode is in the available list: + if(in_array($langCode, $this->_availableLangCodes)) { + // Check the quality setting: + if ($langQuality > $currentLangQuality) { + $currentLangCode = $langCode; + $currentLangQuality = $langQuality; + break; + } + } + // If strict mode is set, don't minimalize the language code: + if($this->_strictMode) { + break; + } + // else chop off the right part: + array_pop($langCodeParts); + } + } + + $this->_langCode = $currentLangCode; + } + + function getLangCode() { + if(!$this->_langCode) { + $this->detectLangCode(); + } + return $this->_langCode; + } + + function setLangCode($langCode) { + $this->_langCode = $langCode; + } + + function getLangCodes() { + return $this->_availableLangCodes; + } + +} diff --git a/src/AJAXChatMySQLiDataBase.php b/src/AJAXChatMySQLiDataBase.php new file mode 100644 index 0000000..6c9a031 --- /dev/null +++ b/src/AJAXChatMySQLiDataBase.php @@ -0,0 +1,90 @@ +_connectionID = $dbConnectionConfig['link']; + $this->_dbName = $dbConnectionConfig['name']; + } + + // Method to connect to the DataBase server: + function connect(&$dbConnectionConfig) { + $this->_connectionID = new mysqli( + $dbConnectionConfig['host'], + $dbConnectionConfig['user'], + $dbConnectionConfig['pass'] + ); + if(!$this->_connectionID) { + $this->_errno = mysqli_connect_errno(); + $this->_error = mysqli_connect_error(); + return false; + } + return true; + } + + // Method to select the DataBase: + function select($dbName) { + if(!$this->_connectionID->select_db($dbName)) { + $this->_errno = $this->_connectionID->errno; + $this->_error = $this->_connectionID->error; + return false; + } + $this->_dbName = $dbName; + return true; + } + + // Method to determine if an error has occured: + function error() { + return (bool)$this->_error; + } + + // Method to return the error report: + function getError() { + if($this->error()) { + $str = 'Error-Report: ' .$this->_error."\n"; + $str .= 'Error-Code: '.$this->_errno."\n"; + } else { + $str = 'No errors.'."\n"; + } + return $str; + } + + // Method to return the connection identifier: + function &getConnectionID() { + return $this->_connectionID; + } + + // Method to prevent SQL injections: + function makeSafe($value) { + return "'".$this->_connectionID->escape_string($value)."'"; + } + + // Method to perform SQL queries: + function sqlQuery($sql) { + return new AJAXChatMySQLiQuery($sql, $this->_connectionID); + } + + // Method to retrieve the current DataBase name: + function getName() { + return $this->_dbName; + } + + // Method to retrieve the last inserted ID: + function getLastInsertedID() { + return $this->_connectionID->insert_id; + } + +} diff --git a/src/AJAXChatMySQLiQuery.php b/src/AJAXChatMySQLiQuery.php new file mode 100644 index 0000000..7a7e0cd --- /dev/null +++ b/src/AJAXChatMySQLiQuery.php @@ -0,0 +1,80 @@ +_sql = trim($sql); + $this->_connectionID = $connectionID; + $this->_result = $this->_connectionID->query($this->_sql); + if(!$this->_result) { + $this->_errno = $this->_connectionID->errno; + $this->_error = $this->_connectionID->error; + } + } + + // Returns true if an error occured: + function error() { + // Returns true if the Result-ID is valid: + return !(bool)($this->_result); + } + + // Returns an Error-String: + function getError() { + if($this->error()) { + $str = 'Query: ' .$this->_sql ."\n"; + $str .= 'Error-Report: ' .$this->_error."\n"; + $str .= 'Error-Code: '.$this->_errno; + } else { + $str = "No errors."; + } + return $str; + } + + // Returns the content: + function fetch() { + if($this->error()) { + return null; + } else { + return $this->_result->fetch_assoc(); + } + } + + // Returns the number of rows (SELECT or SHOW): + function numRows() { + if($this->error()) { + return null; + } else { + return $this->_result->num_rows; + } + } + + // Returns the number of affected rows (INSERT, UPDATE, REPLACE or DELETE): + function affectedRows() { + if($this->error()) { + return null; + } else { + return $this->_connectionID->affected_rows; + } + } + + // Frees the memory: + function free() { + $this->_result->free(); + } + +} diff --git a/src/AJAXChatString.php b/src/AJAXChatString.php new file mode 100644 index 0000000..e3d0e8d --- /dev/null +++ b/src/AJAXChatString.php @@ -0,0 +1,36 @@ +ajaxChat = $ajaxChat; + $this->_regExpTemplateTags = '/\[(\w+?)(?:(?:\/)|(?:\](.+?)\[\/\1))\]/s'; + $this->_templateFile = $templateFile; + $this->_contentType = $contentType; + } + + function getParsedContent() { + if(!$this->_parsedContent) { + $this->parseContent(); + } + return $this->_parsedContent; + } + + function getContent() { + if(!$this->_content) { + $this->_content = AJAXChatFileSystem::getFileContents($this->_templateFile); + } + return $this->_content; + } + + function parseContent() { + $this->_parsedContent = $this->getContent(); + + // Remove the XML declaration if the content-type is not xml: + if($this->_contentType && (strpos($this->_contentType,'xml') === false)) { + $doctypeStart = strpos($this->_parsedContent, '_parsedContent = substr($this->_parsedContent, $doctypeStart); + } + } + + // Replace template tags ([TAG/] and [TAG]content[/TAG]) and return parsed template content: + $this->_parsedContent = preg_replace_callback($this->_regExpTemplateTags, array($this, 'replaceTemplateTags'), $this->_parsedContent); + } + + function replaceTemplateTags($tagData) { + switch($tagData[1]) { + case 'AJAX_CHAT_URL': + return $this->ajaxChat->htmlEncode($this->ajaxChat->getChatURL()); + + case 'LANG': + return $this->ajaxChat->htmlEncode($this->ajaxChat->getLang($tagData[2])); + case 'LANG_CODE': + return $this->ajaxChat->getLangCode(); + + case 'BASE_DIRECTION': + return $this->getBaseDirectionAttribute(); + + case 'CONTENT_ENCODING': + return $this->ajaxChat->getConfig('contentEncoding'); + + case 'CONTENT_TYPE': + return $this->_contentType; + + case 'LOGIN_URL': + return ($this->ajaxChat->getRequestVar('view') == 'logs') ? './?view=logs' : './'; + + case 'USER_NAME_MAX_LENGTH': + return $this->ajaxChat->getConfig('userNameMaxLength'); + case 'MESSAGE_TEXT_MAX_LENGTH': + return $this->ajaxChat->getConfig('messageTextMaxLength'); + + case 'LOGIN_CHANNEL_ID': + return $this->ajaxChat->getValidRequestChannelID(); + + case 'SESSION_NAME': + return $this->ajaxChat->getConfig('sessionName'); + + case 'COOKIE_EXPIRATION': + return $this->ajaxChat->getConfig('sessionCookieLifeTime'); + case 'COOKIE_PATH': + return $this->ajaxChat->getConfig('sessionCookiePath'); + case 'COOKIE_DOMAIN': + return $this->ajaxChat->getConfig('sessionCookieDomain'); + case 'COOKIE_SECURE': + return $this->ajaxChat->getConfig('sessionCookieSecure'); + + case 'CHAT_BOT_NAME': + return rawurlencode($this->ajaxChat->getConfig('chatBotName')); + case 'CHAT_BOT_ID': + return $this->ajaxChat->getConfig('chatBotID'); + + case 'ALLOW_USER_MESSAGE_DELETE': + if($this->ajaxChat->getConfig('allowUserMessageDelete')) + return 1; + else + return 0; + + case 'INACTIVE_TIMEOUT': + return $this->ajaxChat->getConfig('inactiveTimeout'); + + case 'PRIVATE_CHANNEL_DIFF': + return $this->ajaxChat->getConfig('privateChannelDiff'); + case 'PRIVATE_MESSAGE_DIFF': + return $this->ajaxChat->getConfig('privateMessageDiff'); + + case 'SHOW_CHANNEL_MESSAGES': + if($this->ajaxChat->getConfig('showChannelMessages')) + return 1; + else + return 0; + + case 'SOCKET_SERVER_ENABLED': + if($this->ajaxChat->getConfig('socketServerEnabled')) + return 1; + else + return 0; + + case 'SOCKET_SERVER_HOST': + if($this->ajaxChat->getConfig('socketServerHost')) { + $socketServerHost = $this->ajaxChat->getConfig('socketServerHost'); + } else { + $socketServerHost = (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']); + } + return rawurlencode($socketServerHost); + + case 'SOCKET_SERVER_PORT': + return $this->ajaxChat->getConfig('socketServerPort'); + + case 'SOCKET_SERVER_CHAT_ID': + return $this->ajaxChat->getConfig('socketServerChatID'); + + case 'STYLE_SHEETS': + return $this->getStyleSheetLinkTags(); + + case 'CHANNEL_OPTIONS': + return $this->getChannelOptionTags(); + case 'STYLE_OPTIONS': + return $this->getStyleOptionTags(); + case 'LANGUAGE_OPTIONS': + return $this->getLanguageOptionTags(); + + case 'ERROR_MESSAGES': + return $this->getErrorMessageTags(); + + case 'LOGS_CHANNEL_OPTIONS': + return $this->getLogsChannelOptionTags(); + case 'LOGS_YEAR_OPTIONS': + return $this->getLogsYearOptionTags(); + case 'LOGS_MONTH_OPTIONS': + return $this->getLogsMonthOptionTags(); + case 'LOGS_DAY_OPTIONS': + return $this->getLogsDayOptionTags(); + case 'LOGS_HOUR_OPTIONS': + return $this->getLogsHourOptionTags(); + case 'MENU_BAR': + return << +
  • Home
  • +
  • News
  • +
  • Chat
  • +
  • Members
  • +
  • Donate
  • +
  • Status
  • + +EOF; + case 'COPYRIGHT': + return << + Copyright © 2013-2015 Flashwave +
    AJAX Chat © blueimp.net +
    + Feedback | + Changelog | + Rules & Info | + Terms of Service | + Contact | + DevSite | + Legacy Login +
    +EOF; + case 'SANDSTORM': + if(date('md') === '0127' || !empty($_GET['sandstorm'])) + return << + +
    +HTML; + else + return ''; + default: + return $this->ajaxChat->replaceCustomTemplateTags($tagData[1], (isset($tagData[2]) ? $tagData[2] : null)); + } + } + + // Function to display alternating table row colors: + function alternateRow($rowOdd='rowOdd', $rowEven='rowEven') { + static $i; + $i += 1; + if($i % 2 == 0) { + return $rowEven; + } else { + return $rowOdd; + } + } + + function getBaseDirectionAttribute() { + $langCodeParts = explode('-', $this->ajaxChat->getLangCode()); + switch($langCodeParts[0]) { + case 'ar': + case 'fa': + case 'he': + return 'rtl'; + default: + return 'ltr'; + } + } + + function getStyleSheetLinkTags() { + $styleSheets = ''; + foreach($this->ajaxChat->getConfig('styleAvailable') as $style) { + $alternate = ($style == $this->ajaxChat->getConfig('styleDefault')) ? '' : 'alternate '; + $styleSheets .= ''; + } + return $styleSheets; + } + + function getChannelOptionTags() { + $channelOptions = ''; + $channelSelected = false; + foreach($this->ajaxChat->getChannels() as $key=>$value) { + if($this->ajaxChat->isLoggedIn()) { + $selected = ($value == $this->ajaxChat->getChannel()) ? ' selected="selected"' : ''; + } else { + $selected = ($value == $this->ajaxChat->getConfig('defaultChannelID')) ? ' selected="selected"' : ''; + } + if($selected) { + $channelSelected = true; + } + $channelOptions .= ''; + } + if($this->ajaxChat->isLoggedIn() && $this->ajaxChat->isAllowedToCreatePrivateChannel()) { + // Add the private channel of the user to the options list: + if(!$channelSelected && $this->ajaxChat->getPrivateChannelID() == $this->ajaxChat->getChannel()) { + $selected = ' selected="selected"'; + $channelSelected = true; + } else { + $selected = ''; + } + $privateChannelName = $this->ajaxChat->getPrivateChannelName(); + $channelOptions .= ''; + } + // If current channel is not in the list, try to retrieve the channelName: + if(!$channelSelected) { + $channelName = $this->ajaxChat->getChannelName(); + if($channelName !== null) { + $channelOptions .= ''; + } else { + // Show an empty selection: + $channelOptions .= ''; + } + } + return $channelOptions; + } + + function getStyleOptionTags() { + $styleOptions = ''; + foreach($this->ajaxChat->getConfig('styleAvailable') as $style) { + $selected = ($style == $this->ajaxChat->getConfig('styleDefault')) ? ' selected="selected"' : ''; + $styleOptions .= ''; + } + return $styleOptions; + } + + function getLanguageOptionTags() { + $languageOptions = ''; + $languageNames = $this->ajaxChat->getConfig('langNames'); + foreach($this->ajaxChat->getConfig('langAvailable') as $langCode) { + $selected = ($langCode == $this->ajaxChat->getLangCode()) ? ' selected="selected"' : ''; + $languageOptions .= ''; + } + return $languageOptions; + } + + function getErrorMessageTags() { + $errorMessages = ''; + foreach($this->ajaxChat->getInfoMessages('error') as $error) { + $errorMessages .= '

    '.$this->ajaxChat->htmlEncode($this->ajaxChat->getLang($error)).'

    '; + } + return $errorMessages; + } + + function getLogsChannelOptionTags() { + $channelOptions = ''; + $channelOptions .= ''; + foreach($this->ajaxChat->getChannels() as $key=>$value) { + if($this->ajaxChat->getUserRole() != AJAX_CHAT_ADMIN && $this->ajaxChat->getConfig('logsUserAccessChannelList') && !in_array($value, $this->ajaxChat->getConfig('logsUserAccessChannelList'))) { + continue; + } + $channelOptions .= ''; + } + $channelOptions .= ''; + $channelOptions .= ''; + return $channelOptions; + } + + function getLogsYearOptionTags() { + $yearOptions = ''; + $yearOptions .= ''; + for($year=date('Y'); $year>=$this->ajaxChat->getConfig('logsFirstYear'); $year--) { + $yearOptions .= ''; + } + return $yearOptions; + } + + function getLogsMonthOptionTags() { + $monthOptions = ''; + $monthOptions .= ''; + for($month=1; $month<=12; $month++) { + $monthOptions .= ''; + } + return $monthOptions; + } + + function getLogsDayOptionTags() { + $dayOptions = ''; + $dayOptions .= ''; + for($day=1; $day<=31; $day++) { + $dayOptions .= ''; + } + return $dayOptions; + } + + function getLogsHourOptionTags() { + $hourOptions = ''; + $hourOptions .= ''; + for($hour=0; $hour<=23; $hour++) { + $hourOptions .= ''; + } + return $hourOptions; + } + +} diff --git a/public/lib/class/CustomAJAXChat.php b/src/CustomAJAXChat.php similarity index 52% rename from public/lib/class/CustomAJAXChat.php rename to src/CustomAJAXChat.php index 8a073a1..8fd1215 100644 --- a/public/lib/class/CustomAJAXChat.php +++ b/src/CustomAJAXChat.php @@ -9,17 +9,17 @@ class CustomAJAXChat extends AJAXChat { - // Returns an associative array containing userName, userID and userRole - // Returns null if login is invalid - function getValidLoginUserData() { - if($this->getRequestVar('password')) { - // Check if we have a valid registered user: + // Returns an associative array containing userName, userID and userRole + // Returns null if login is invalid + function getValidLoginUserData() { + if($this->getRequestVar('password')) { + // Check if we have a valid registered user: - $userName = $this->getRequestVar('userName'); - $userName = $this->convertEncoding($userName, $this->getConfig('contentEncoding'), $this->getConfig('sourceEncoding')); + $userName = $this->getRequestVar('userName'); + $userName = $this->convertEncoding($userName, $this->getConfig('contentEncoding'), $this->getConfig('sourceEncoding')); - $password = $this->getRequestVar('password'); - $password = $this->convertEncoding($password, $this->getConfig('contentEncoding'), $this->getConfig('sourceEncoding')); + $password = $this->getRequestVar('password'); + $password = $this->convertEncoding($password, $this->getConfig('contentEncoding'), $this->getConfig('sourceEncoding')); $flashiiConfig = parse_ini_file('/www/flashii.net/config/config.ini', true, INI_SCANNER_TYPED); @@ -78,136 +78,136 @@ class CustomAJAXChat extends AJAXChat { } } - return null; - } else { - // Guest users: - return $this->getGuestUser(); - } - } + return null; + } else { + // Guest users: + return $this->getGuestUser(); + } + } - // Store the channels the current user has access to - // Make sure channel names don't contain any whitespace - function &getChannels() { - if($this->_channels === null) { - $this->_channels = array(); - - /*$customUsers = $this->getCustomUsers(); - - // Get the channels, the user has access to: - if($this->getUserRole() == AJAX_CHAT_GUEST) { - $validChannels = $customUsers[0]['channels']; - } else { - $validChannels = $customUsers[$this->getUserID()]['channels']; - }*/ - - // Add the valid channels to the channel list (the defaultChannelID is always valid): - foreach($this->getAllChannels() as $key=>$value) { - // Check if we have to limit the available channels: - if($this->getConfig('limitChannelList') && !in_array($value, $this->getConfig('limitChannelList'))) { - continue; - } - - //if(in_array($value, $validChannels) || $value == $this->getConfig('defaultChannelID')) { - $this->_channels[$key] = $value; - //} - } - } - return $this->_channels; - } + // Store the channels the current user has access to + // Make sure channel names don't contain any whitespace + function &getChannels() { + if($this->_channels === null) { + $this->_channels = array(); - // Store all existing channels - // Make sure channel names don't contain any whitespace - function &getAllChannels() { - if($this->_allChannels === null) { - // Get all existing channels: - $customChannels = $this->getCustomChannels(); - - $defaultChannelFound = false; - - foreach($customChannels as $key=>$value) { - $forumName = $this->trimChannelName($value); - - $this->_allChannels[$forumName] = $key; - - if($key == $this->getConfig('defaultChannelID')) { - $defaultChannelFound = true; - } - } - - if(!$defaultChannelFound) { - // Add the default channel as first array element to the channel list: - $this->_allChannels = array_merge( - array( - $this->trimChannelName($this->getConfig('defaultChannelName'))=>$this->getConfig('defaultChannelID') - ), - $this->_allChannels - ); - } - } - return $this->_allChannels; - } + /*$customUsers = $this->getCustomUsers(); - /*function &getCustomUsers() { - global $database; + // Get the channels, the user has access to: + if($this->getUserRole() == AJAX_CHAT_GUEST) { + $validChannels = $customUsers[0]['channels']; + } else { + $validChannels = $customUsers[$this->getUserID()]['channels']; + }*/ - $userlist = $database->query("SELECT * FROM `accounts`.`flashii_users` WHERE `userrole` != '0'")->fetch_all(MYSQLI_ASSOC); + // Add the valid channels to the channel list (the defaultChannelID is always valid): + foreach($this->getAllChannels() as $key=>$value) { + // Check if we have to limit the available channels: + if($this->getConfig('limitChannelList') && !in_array($value, $this->getConfig('limitChannelList'))) { + continue; + } + + //if(in_array($value, $validChannels) || $value == $this->getConfig('defaultChannelID')) { + $this->_channels[$key] = $value; + //} + } + } + return $this->_channels; + } + + // Store all existing channels + // Make sure channel names don't contain any whitespace + function &getAllChannels() { + if($this->_allChannels === null) { + // Get all existing channels: + $customChannels = $this->getCustomChannels(); + + $defaultChannelFound = false; + + foreach($customChannels as $key=>$value) { + $forumName = $this->trimChannelName($value); + + $this->_allChannels[$forumName] = $key; + + if($key == $this->getConfig('defaultChannelID')) { + $defaultChannelFound = true; + } + } + + if(!$defaultChannelFound) { + // Add the default channel as first array element to the channel list: + $this->_allChannels = array_merge( + array( + $this->trimChannelName($this->getConfig('defaultChannelName'))=>$this->getConfig('defaultChannelID') + ), + $this->_allChannels + ); + } + } + return $this->_allChannels; + } + + /*function &getCustomUsers() { + global $database; + + $userlist = $database->query("SELECT * FROM `accounts`.`flashii_users` WHERE `userrole` != '0'")->fetch_all(MYSQLI_ASSOC); + + $users = array(); + + $users[0] = array(); + $users[0]['userRole'] = AJAX_CHAT_GUEST; + $users[0]['userName'] = null; + $users[0]['password'] = null; + $users[0]['channels'] = array(0,1); - $users = array(); - - $users[0] = array(); - $users[0]['userRole'] = AJAX_CHAT_GUEST; - $users[0]['userName'] = null; - $users[0]['password'] = null; - $users[0]['channels'] = array(0,1); - foreach($userlist as $user) { $users[$user['id']] = array(); $users[$user['id']]['userName'] = $user['username']; $users[$user['id']]['password'] = $user['password']; - + switch($user['userrole']) { // Tenshi case 7: $users[$user['id']]['userRole'] = DONATOR; $users[$user['id']]['channels'] = array(0, 1); break; - + // Chat Moderators case 6: $users[$user['id']]['userRole'] = CMOD; $users[$user['id']]['channels'] = array(0, 1, 2); break; - + // Bots case 5: $users[$user['id']]['userRole'] = BOTS; $users[$user['id']]['channels'] = array(0, 1, 2); break; - + // Developers case 4: $users[$user['id']]['userRole'] = PURPLE; $users[$user['id']]['channels'] = array(0, 1, 2); break; - + // Administrator case 3: $users[$user['id']]['userRole'] = AJAX_CHAT_ADMIN; $users[$user['id']]['channels'] = array(0, 1, 2); break; - + // Site Moderators case 2: $users[$user['id']]['userRole'] = AJAX_CHAT_MODERATOR; $users[$user['id']]['channels'] = array(0, 1, 2); break; - + // Regular Users case 1: $users[$user['id']]['userRole'] = AJAX_CHAT_USER; $users[$user['id']]['channels'] = array(0, 1); break; - + // Unknown and Deactivated Users case 0: default: @@ -215,16 +215,16 @@ class CustomAJAXChat extends AJAXChat { $users[$user['id']]['channels'] = array(0); } } - - return $users; - }*/ - - function &getCustomChannels() { - $channels = [ + + return $users; + }*/ + + function &getCustomChannels() { + $channels = [ 0 => 'Public', ]; - /*$result = $this->db->sqlQuery("SELECT * FROM ajax_chat_channels")->_result->fetch_all(MYSQLI_ASSOC); - + /*$result = $this->db->sqlQuery("SELECT * FROM ajax_chat_channels")->_result->fetch_all(MYSQLI_ASSOC); + foreach($result as $channel) { $channels[$channel['id']] = $channel['name']; }*/ @@ -232,29 +232,29 @@ class CustomAJAXChat extends AJAXChat { if($this->isLoggedIn()) $channels[9001] = 'Secret'; - return $channels; - } - - function parseCustomCommands($text, $textParts) { - switch($textParts[0]) { - case '/afk': - $this->setUserName('_' . $this->getUserName()); - $this->updateOnlineList(); - $this->addInfoMessage($this->getUserName(), 'userName'); - $this->setSessionVar('AwayFromKeyboard', true); - return true; - default: - return false; - } - } + return $channels; + } - function onNewMessage($text) { - if($this->getSessionVar('AwayFromKeyboard')) { - $this->setUserName(substr($this->getUserName(), 6)); - $this->updateOnlineList(); - $this->addInfoMessage($this->getUserName(), 'userName'); - $this->setSessionVar('AwayFromKeyboard', false); - } - return true; - } + function parseCustomCommands($text, $textParts) { + switch($textParts[0]) { + case '/afk': + $this->setUserName('_' . $this->getUserName()); + $this->updateOnlineList(); + $this->addInfoMessage($this->getUserName(), 'userName'); + $this->setSessionVar('AwayFromKeyboard', true); + return true; + default: + return false; + } + } + + function onNewMessage($text) { + if($this->getSessionVar('AwayFromKeyboard')) { + $this->setUserName(substr($this->getUserName(), 6)); + $this->updateOnlineList(); + $this->addInfoMessage($this->getUserName(), 'userName'); + $this->setSessionVar('AwayFromKeyboard', false); + } + return true; + } } diff --git a/public/lib/class/CustomAJAXChatInterface.php b/src/CustomAJAXChatInterface.php similarity index 54% rename from public/lib/class/CustomAJAXChatInterface.php rename to src/CustomAJAXChatInterface.php index b84dd42..c957f9d 100644 --- a/public/lib/class/CustomAJAXChatInterface.php +++ b/src/CustomAJAXChatInterface.php @@ -9,13 +9,12 @@ class CustomAJAXChatInterface extends CustomAJAXChat { - function initialize() { - // Initialize configuration settings: - $this->initConfig(); + function initialize() { + // Initialize configuration settings: + $this->initConfig(); - // Initialize the DataBase connection: - $this->initDataBaseConnection(); - } + // Initialize the DataBase connection: + $this->initDataBaseConnection(); + } } -?> \ No newline at end of file diff --git a/src/CustomAJAXChatShoutBox.php b/src/CustomAJAXChatShoutBox.php new file mode 100644 index 0000000..ede212a --- /dev/null +++ b/src/CustomAJAXChatShoutBox.php @@ -0,0 +1,24 @@ +initConfig(); + } + + function getShoutBoxContent() { + $template = new AJAXChatTemplate($this, AJAX_CHAT_PATH . '/template/shoutbox.html'); + + // Return parsed template content: + return $template->getParsedContent(); + } + +} diff --git a/src/satori.php b/src/satori.php new file mode 100644 index 0000000..d51d00a --- /dev/null +++ b/src/satori.php @@ -0,0 +1,239 @@ +]*?))?\\]/ms', '', $satoriParse); +$textParts = explode(' ', $satoriParse); + + +// Random Stuff +$defaultResponseArray = ['What do you want?', 'Kindly fuck off.', 'Don\'t know how to "%s" something.', 'Come again?', 'Satori returned an empty result set (i.e. zero rows).']; +$defaultResponse = sprintf($defaultResponseArray[array_rand($defaultResponseArray)], $textParts[0]); + + +// Actions +if(preg_match('/^k$/im', $satoriParse)) { + $satoriResp = ['Thank you for your amazing and insightful message. It is truly an honour to have this message in my database. I can\'t thank you more than to say go fuck yourself. You truly touched me... Thank you.']; +} +if(preg_match('/^time to break the chat$/im', $satoriParse)) { + $satoriResp = ['Stay away from me!']; +} +if(preg_match('/^all aboard the sailboat$/im', $satoriParse)) { + $satoriResp = ['Why would we get on something that is about to sink :^)']; +} + + +// Reactions +if(preg_match('/^satori/im', $textParts[0])) { + switch($satoriInput = preg_replace('/^satori? ?/', '', $satoriParse)) { + case 'version': + $satoriResp = ['[b][color=Red]S[/color][color=Ruby]a[/color][color=Citrine]t[/color][color=Green]o[/color][color=Teal]r[/color][color=Cobalt]i[/color][/b] Version not [b]6[/b]']; + break; + case 'what are you': + $satoriResp = ['I am nice girl for nice chat.', '[img]http://i.imgur.com/NcFitL2.jpg[/img]']; + break; + case 'hi': + $satoriResp = ['sup']; + break; + case 'help': + $satoriResp = ['If you need help with things refer to the [url=http://flashii.net/r/faq]FAQ[/url].', 'If this didn\'t help you don\'t hesitate to ask an active user.']; + break; + case 'why do you exist': + $satoriResp = ['So you have someone to hate. <3']; + break; + case 'suck my dick': + $satoriResp = ['Do you even have one? Can\'t see it.']; + break; + case 'make me admin': + $satoriResp = ['Why the fuck would you WANT admin? It\'s nothing more than extra work for an ugly red username! Look now the colour for deactivated user, that one\'s fucking hot.']; + break; + case 'anime': + $satoriResp = ['Oh god, i wish i could leave this chat but i\'m stuck in here ;__;']; + break; + case 'e': + $satoriResp = ['Do I look like Nasbot or something?']; + break; + case 'meow': + $satoriResp = ['Mewow!']; + break; + case 'puush': + $satoriResp = ['Something you should be using.']; + break; + case 'what is flash\'s password': + case 'what is flashwave\'s password': + case 'what is moka\'s password': + $satoriResp = ['/suicide', 'I do recommend sending it in chat right now.']; + break; + case 'what do you think about snailmush': + case 'what do you like snailmush': + case 'snailmush': + $satoriResp = ['I-it\'s not like I like him or-or any-anything...... ;_;']; + break; + case 'x snailmush': + case 'loves snailmush': + case 'do you love snailmush': + case 'do you love snailmush?': + $satoriResp = ['NO!', '[s]Trigger Kick']; + break; + case 'saibateku': + $satoriResp = ['That place is still up?']; + break; + case 'titanic': + $satoriResp = ['Did you mean Sailboat?']; + break; + case 'did sailboat sink yet': + $satoriResp = ['No but I wish it would. Fuck that place. Seems to be getting pretty close however...']; + break; + case 'malwareup': + $satoriResp = ['Good malware discussion forum.']; + break; + case 'flashii': + $satoriResp = ['Mediocre shithole. 0/10']; + break; + case 'cybernetics': + $satoriResp = ['Did you mean "Saibateku"?']; + break; + case 'nathat': + $satoriResp = ['shut up']; + break; + case 'waifu': + case 'inori aizawa': + case 'internet explorer tan': + $satoriResp = ['Inori Aizawa Is Mai Waifu.', 'Welcome To Mai Web Browser Is Mai Waifu Land!']; + break; + case 'webkit': + case 'safari': + case 'blink': + case 'chrome': + $satoriResp = [':puke::puke::puke:']; + break; + case 'gecko': + case 'trident': + case 'internet explorer': + case 'iexplore': + case 'firefox': + case 'mozilla firefox': + $satoriResp = [':love::love::love:']; + break; + case 'bribob': + case 'bribob4': + $satoriResp = ['Mediocre faggot. 0/10']; + break; + case 'kelopez': + case 'brante': + $satoriResp = ['http://en.wikipedia.org/wiki/Mexican']; + break; + case 'kamil': + case 'rakowski': + case 'kamilrakowski': + $satoriResp = ['http://en.wikipedia.org/wiki/Jews']; + break; + case 'secret': + $satoriResp = ['I\'m not a secret ripoff, what are you talking about?', '[i]My code is better, time to kill yourself![/i]']; + break; + case 'koishi': + $satoriResp = ['Don\'t fuck with Koishi.']; + break; + case ':^)': + $satoriResp = ['8^)']; + break; + case 'nookls': + $satoriResp = ['HOOOOLLLLLYYYYYYYYYYYYY CRAP NOOKLS IS SO AMAZING WOWOWOWOWOWOW HE\'S ACTUALLY ON THIS SITE WORSHIP WORSHIP AMAZING BRILLIANT I LOVE YOU NOOKLS WE ALL LOVE YOU WE LOVE YOU AS MUCH AS FANGIRLS LOVE JUSTIN BIEBER AAAAAAAAHHHHHHHHHHHH THIS IS THE BEST MOMENT!']; + break; + case 'zeniea': + $satoriResp = ['For whatever reason I have the urge to say "This place smells like a catholic church on crack"...']; + break; + case 'zquest': + $satoriResp = ['Good comic 10/10']; + break; + case 'fuck me': + $satoriResp = [':wtf:']; + break; + case 'satori': + $satoriResp = ['Wait, what are you trying to do?']; + break; + case 'satori satori': + $satoriResp = ['Don\'t fucking do this to me...']; + break; + case 'satori satori satori': + $satoriResp = ['[b][i]I\'ll fucking murder you![/i][/b]']; + break; + case 'satori satori satori satori': + $satoriResp = ['no don\'t']; + break; + case 'satori satori satori satori satori': + $satoriResp = ['please don\'t do this to me']; + break; + case 'satori satori satori satori satori satori': + $satoriResp = ['i have a waifu and kids']; + break; + case 'satori satori satori satori satori satori satori': + $satoriResp = ['okay i was kidding about the kids part']; + break; + case 'satori satori satori satori satori satori satori satori': + $satoriResp = ['rip life']; + break; + case 'you are annoying': + case 'please die': + case 'die': + $satoriResp = ['Well I\'m God and you can\'t do shit.']; + break; + case 'misaka-20001': + $satoriResp = ['We\'ll have to move one of these days...', 'The good ol\' Pentium 4 doesn\'t seem to be able to handle shit anymore...']; + break; + case 'how old are you': + case 'how old is flashii': + case 'how old is koishi': + $satoriResp = [date_diff(date_create('2013-01-27 22:14:44 UTC'), date_create(date('Y-m-d H:i:s e')))->format('%y year(s), %m month(s), %d day(s), %H hour(s), %i minute(s) and %s second(s)')]; + break; + case 'how old is zeniea': + case 'how old is secret': + $satoriResp = [date_diff(date_create('2011-07-07 00:00:00 UTC'), date_create(date('Y-m-d H:i:s e')))->format('%y year(s), %m month(s), %d day(s), %H hour(s), %i minute(s) and %s second(s)')]; + break; + case 'how old is zquest': + $satoriResp = [date_diff(date_create('2013-11-16 00:00:00 UTC'), date_create(date('Y-m-d H:i:s e')))->format('%y year(s), %m month(s), %d day(s), %H hour(s), %i minute(s) and %s second(s)')]; + break; + case 'are you broken': + case 'are you broken?': + case 'is flashii broken': + case 'is flashii broken?': + $satoriResp = ['yes']; + break; + default: + $satoriResp = [$defaultResponse]; + break; + } +} + + +// Check if disabled +if(!$satoriSetting['enabled']) + $satoriResp = null; + + +// Bring the process of sending a message down to one if +if(isset($satoriResp)) { + foreach($satoriResp as $directives => $response) { + if($response == '[s]Trigger Kick') { + $this->logout('Kicked'); + } else { + $this->insertCustomMessage( + $satoriSetting['userID'], + $satoriSetting['userName'], + $satoriSetting['userRank'], + $this->getChannel(), + vsprintf($response, $directives), + $satoriSetting['userIP'], + 0 + ); + } + } +} diff --git a/public/lib/template/banned.html b/template/banned.html similarity index 100% rename from public/lib/template/banned.html rename to template/banned.html diff --git a/public/lib/template/legacyLogin.html b/template/legacyLogin.html similarity index 100% rename from public/lib/template/legacyLogin.html rename to template/legacyLogin.html diff --git a/public/lib/template/loggedIn.html b/template/loggedIn.html similarity index 100% rename from public/lib/template/loggedIn.html rename to template/loggedIn.html diff --git a/public/lib/template/loggedOut.html b/template/loggedOut.html similarity index 100% rename from public/lib/template/loggedOut.html rename to template/loggedOut.html diff --git a/public/lib/template/loggedOutFA.html b/template/loggedOutFA.html similarity index 100% rename from public/lib/template/loggedOutFA.html rename to template/loggedOutFA.html diff --git a/public/lib/template/loggedOut~.html b/template/loggedOut~.html similarity index 100% rename from public/lib/template/loggedOut~.html rename to template/loggedOut~.html diff --git a/public/lib/template/logs.html b/template/logs.html similarity index 100% rename from public/lib/template/logs.html rename to template/logs.html diff --git a/public/lib/template/mobile.html b/template/mobile.html similarity index 100% rename from public/lib/template/mobile.html rename to template/mobile.html diff --git a/public/lib/template/shoutbox.html b/template/shoutbox.html similarity index 100% rename from public/lib/template/shoutbox.html rename to template/shoutbox.html diff --git a/public/lib/template/~loggedOut.html b/template/~loggedOut.html similarity index 100% rename from public/lib/template/~loggedOut.html rename to template/~loggedOut.html