| admin_login.php | index.php | plugins_footer.php | plugins_header.php | qt_viewquests.php | qt_viewtimers.php | quest_timer.php | quest_timer/loadquests.php | quest_timer/newquests.php | quest_timer/savequests.php | quest_timer/submitquests.php | scroll_manager.php | show_create.php | sql_config_example.php | viewsource.php |

quest_timer/savequests.php

  [Go to page]


<?php
    error_reporting
(E_ALL E_NOTICE E_WARNING);
    
    if (isset(
$_GET['viewsource']))
    {
        echo(
"<table><tr><td nowrap>");
        
show_source("savequests.php");
        die(
"</td></tr></table>");
    }
    
    
header('Content-Type: text/xml');
    
    
$username addslashes($_POST['username']);
    
$password addslashes($_POST['password']);
    
    if (
strlen($username) < || strlen($password) < 5)
        die(
'<error reason="Username and Password must be at least 5 characters long" />');
    if (
strlen($username) > 30 || strlen($password) > 30)
        die(
'<error reason="Username and Password cannot be more than 30 characters long" />');
        
    
$questxml $_POST['questxml'];
    
$lastmodified addslashes($_POST['lastmodified']); //Date will be in GMT with the format yyyy-mm-dd hh:mm:ss
    
$acctchars addslashes($_POST['acctchars']);
    
$gmtoffset addslashes($_POST['gmtoffset']);
    if (
strpos($questxml"<Quests") === false)
        die(
'<error reason="Invalid Quests XML file" />');
    
    
$currentcharacter addslashes($_POST['currentcharacter']);
    
$currentworld addslashes($_POST['currentworld']);
    
    if (isset(
$_POST['compare_merge']))
        
$compare_merge strtoupper(addslashes($_POST['compare_merge'])); //NONE, COMPARE, or MERGE
    
else
        
$compare_merge 'NONE';
        
    if (isset(
$_POST['uploadct']) && $_POST['uploadct'] <> '')
    {
        
$uploadct addslashes($_POST['uploadct']);
        
$check_uploadct = (bool)($uploadct >= 0); //Plugin will send -1 if checking should not be perfomed
    
}
    else
        
$check_uploadct false;
    
    if (isset(
$_POST['currenttime']) && $_POST['currenttime'] <> '')
    {
        
$client_timestamp strtotime(addslashes($_POST['currenttime']) . '+0000'); // Sent in GMT
        
if ($client_timestamp === -1// Invalid time
            
$client_timestamp time();
    }
    else
        
$client_timestamp time();
    
$client_time gmdate('Y-m-d H:i:s'$client_timestamp);
    
    
$restoredquests "";
    
    
// Connection to mysql is done in sql_config.php, which is included before this file 
    
if (defined('MYSQL_CONNECTED'))
    {        
        if (
$result mysql_query("SELECT * FROM QuestTimer_UserQuests WHERE username='$username'"))
        {
            if (
$data mysql_fetch_array($result))
            {
                if (
$compare_merge != 'NONE')
                {
                    
$database_questxml gzuncompress($data['questxml']) or die('<error reason="Failed to uncompress Quest XML from database" />');
                }
                
                if (
$data['password'] == stripslashes($password))
                {
                    if (
$check_uploadct && $uploadct $data['uploadct'])
                    {
                        echo(
'<OldFile/>');
                    }
                    elseif (
$compare_merge == 'COMPARE' && !check_otherchars($database_questxml$questxmlfalse))
                    {
                        echo(
'<OtherCharMismatch/>');
                    }
                    else
                    {
                        
$merged = ($compare_merge == 'MERGE' && !check_otherchars($database_questxml$questxmltrue));
                        
                        if (
$merged)
                            
$lastmodified $client_time;
                        
                        
$uploadct $data['uploadct'] + 1;
                        
                        
$questxml_compressed gzcompress($questxml) or die('<error reason="Failed to compress Quest XML to store in database" />');
                        
$compressed_len strlen($questxml_compressed);
                        
$questxml_compressed addslashes($questxml_compressed);
                        
                        if (
$compressed_len 65535)
                        {
                            echo(
'<error reason="Your quest file is too large, even after GZIP compression.  The file must be smaller than 64 KB; yours is ' round($compressed_len 10242) . ' KB after compression" />');
                            echo(
'<!-- Note: To reduce the size, remove some quests or set "Time Up" quests to "Not Completed" -->');
                        }
                        elseif (
mysql_query("UPDATE QuestTimer_UserQuests 
                                        SET lastmodified='
$lastmodified', questxml='$questxml_compressed', acctchars='$acctchars', gmtoffset='$gmtoffset', lastuploaded='" gmdate('Y-m-d H:i:s') . "', uploadct='$uploadct'
                                        WHERE username='
$username'"))
                        {
                            if (
$merged)
                            {
                                
// Return the quest XML so the plugin can update it 
                                
echo("<Merged uploadct='$uploadct' restoredquests='" htmlspecialchars($restoredquests) . "'>$questxml</Merged>");
                            }
                            else
                            {
                                echo(
"<Success uploadct='$uploadct'/>");
                            }
                        }
                        else echo(
'<error reason="Failed to update record in database: ' mysql_error() . '" />');
                    }
                }
                else echo(
'<error reason="Password does not match Username" />');
            }
            else 
//User does not exist
            
{
                
$questxml_compressed gzcompress($questxml) or die('<error reason="Failed to compress Quest XML to store in database" />');
                
//die('<error reason="Error">' . base64_encode($questxml_compressed) . '</error>');
                
$questxml_compressed addslashes($questxml_compressed);
                if (
mysql_query("INSERT INTO QuestTimer_UserQuests (username,password,lastmodified,lastuploaded,uploadct,acctchars,gmtoffset,questxml) 
                                 VALUES ('
$username','$password','$lastmodified','" gmdate('Y-m-d H:i:s') . "','1','$acctchars','$gmtoffset','$questxml_compressed')"))
                    echo(
"<Success uploadct='1'/>
                        <!-- Note: Username " 
htmlspecialchars(stripslashes($username)) . " did not exist and was created with the supplied password -->");
                else echo(
'<error reason="Failed to create new record in database: ' mysql_error() . '" />');
            }
        }
        else echo(
'<error reason="SQL Query error: ' mysql_error() . '" />');
    }
    else echo(
'<error reason="Failed to connect to database" />');

    
/*Create Table:
    CREATE TABLE `QuestTimer_UserQuests` (
        `username` varchar(30) NOT NULL default '',
        `password` varchar(30) NOT NULL default '',
        `lastmodified` datetime NOT NULL default '0000-00-00 00:00:00',
        `lastuploaded` datetime NOT NULL default '0000-00-00 00:00:00',
        `uploadct` int(11) NOT NULL default '0',
        `acctchars` text NOT NULL,
        `gmtoffset` varchar(10) NOT NULL default '-0500',
        `questxml` text NOT NULL,
        PRIMARY KEY  (`username`,`password`)
    ) TYPE=MyISAM;
    */
    
    
function check_otherchars(&$database_xml, &$uploaded_xml$do_merge)
    
/* 
        if $do_merge is TRUE, merge the two XMLs; otherwise just check for differences
        
        returns TRUE if info for characters other than $currentcharacter matches between XMLs
        
        *** THIS FUNCTION USES DOM, WHICH IS ONLY AVAILABLE IN PHP 5 ***
        If you're using PHP 4, you'll have to convert to DOMXML.  See http://www.php.net for more info.
    */
    
{
        global 
$currentcharacter$currentworld$restoredquests;
        
        
$cur_char_world strtolower("$currentcharacter [$currentworld]");
        
$xmlOldQuests DOMDocument::loadXML($database_xml);
        
$xmlNewQuests DOMDocument::loadXML($uploaded_xml);
        
        if (!
is_object($xmlOldQuests))
        {
            echo(
"<!-- Note: Server failed to parse quests xml in database.  If you see this error often, contact me. -->");
            return 
true;
        }
        if (!
is_object($xmlNewQuests))
        {
            die(
'<error reason="Failed to parse the uploaded quests xml.  Disable character info match checking to upload anyways."/>');
        }
        
        
$retval true;
        
        foreach (
$xmlOldQuests->documentElement->getElementsByTagName('Quest') as $OldQuest)
        {
            
$found_quest false;
            
            foreach (
$xmlNewQuests->documentElement->getElementsByTagName('Quest') as $NewQuest)
            {
                if (
strtolower($OldQuest->getAttribute('QuestName')) == strtolower($NewQuest->getAttribute('QuestName')))
                {
                    foreach (
$OldQuest->getElementsByTagName('Character') as $OldChar)
                    {    
                        
// Skip current character or ones whose timer has already expired
                        
if (char_world($OldChar) == $cur_char_world || timer_expired($OldQuest$OldChar))
                            continue;
                        
                        
$found_char false;
                        
                        foreach (
$NewQuest->getElementsByTagName('Character') as $NewChar)
                        {
                            if (
char_world($OldChar) == char_world($NewChar))
                            {
                                
$old_completed strtotime($OldChar->getAttribute('Completed'));
                                
$new_completed strtotime($NewChar->getAttribute('Completed'));
                                if (
$old_completed !== -&& $new_completed !== -&& $old_completed $new_completed)
                                {
                                    if (!
$do_merge) return false;
                                    
$retval false;
                                    
                                    
$NewChar->setAttribute('Completed'$OldChar->getAttribute('Completed'));
                                }
                                
                                
$found_char true;
                                break;
                            } 
// if (char_world($OldChar) == char_world($NewChar))
                        
// foreach (... as $NewChar)
                        
                        
if (!$found_char)
                        {
                            if (!
$do_merge) return false;
                            
$retval false;
                            
                            
$NewQuest->appendChild($xmlNewQuests->importNode($OldChartrue));
                        }
                    } 
// foreach (... as $OldChar)
                    
                    
$found_quest true;
                    break;
                } 
// if ($OldQuest->getAttribute('QuestName') == $NewQuest->getAttribute('QuestName'))
            
// foreach (... as $NewQuest)
            
            
if (!$found_quest)
            {
                
$quest_added false;
                
                foreach (
$OldQuest->getElementsByTagName('Character') as $OldChar)
                {
                    
// Skip current character or ones whose timer has already expired
                    
if (char_world($OldChar) == $cur_char_world || timer_expired($OldQuest$OldChar))
                        continue;
                    
                    if (!
$do_merge) return false;
                    
$retval false;
                    
                    if (!
$quest_added)
                    {
                        
// Append a copy of the quest node with all child nodes intact
                        
$NewQuest $xmlNewQuests->documentElement->appendChild($xmlNewQuests->importNode($OldQuesttrue));
                        
                        
// Remove all of the Character nodes (but leave the Note nodes intact)
                        // This is so we only have the Characters whose timers haven't expired
                        
while ($NewQuest->getElementsByTagName('Character')->length 0)
                        {
                            
$NewChar $NewQuest->getElementsByTagName('Character')->item(0);
                            
$NewQuest->removeChild($NewChar);
                        }
                        
                        
$quest_added true;
                        
$restoredquests[] = $NewQuest->getAttribute('QuestName');
                    }
                    
                    
$NewQuest->appendChild($xmlNewQuests->importNode($OldChartrue));
                } 
// foreach (... as $OldChar)
                
            
// if (!$found_quest)
        
// foreach (... as $OldQuest)
        
        
if (is_array($restoredquests))
        {
            
$restoredquests join($restoredquests', ');
        }
        
        if (
$do_merge && $retval == false)
        {
            
// Only the document element, not the processing instructions like < ?xml version="1.0" ? >
            
$uploaded_xml $xmlNewQuests->saveXML($xmlNewQuests->documentElement);
        }
        
        return 
$retval;
    }
    
    function 
char_world(&$char_node)
    {
        return 
strtolower($char_node->getAttribute('Name') . ' [' $char_node->getAttribute('Server') . ']');
    }
    
    function 
timer_expired(&$quest_node, &$char_node)
    {
        global 
$gmtoffset$client_timestamp;
        
        
$mins $quest_node->getAttribute('Minutes');
        
$hours $quest_node->getAttribute('Hours');
        
$days $quest_node->getAttribute('Days');
        
        
$quest_duration 60 * ($mins 60 * ($hours 24 $days));
        
        
$completed strtotime($char_node->getAttribute('Completed') . $gmtoffset);
        
        return (
$client_timestamp > ($completed $quest_duration));
    }
?>