diff --git a/code/web/app/app_achievements/_AchWebParser/AchWebMonitor.php b/code/web/app/app_achievements/_AchWebParser/AchWebMonitor.php new file mode 100644 index 000000000..7a5895418 --- /dev/null +++ b/code/web/app/app_achievements/_AchWebParser/AchWebMonitor.php @@ -0,0 +1,35 @@ +connect($CONF['mysql_server'],$CONF['mysql_user'],$CONF['mysql_pass'],$CONF['mysql_database']); + + //check status + $res = $DBc->sendSQL("SELECT * FROM ach_monitor_status ORDER by ams_start DESC LIMIT 0,1","ARRAY"); + + if(($res[0]['ams_start'] < (time()-$CONF['timeout']) && $res[0]['ams_end'] == 0) || ($res[0]['ams_end'] > 0 && $res[0]['ams_end'] < (time()-$CONF['timeout']))) { + $fp = fsockopen($CONF['self_host'], 80, $errno, $errstr, 30); + if(!$fp) { + logf("ERROR: self call; socket: ".$errstr." (."$errno.")"); + } + else { + $out = "GET ".$CONF['self_path']." HTTP/1.1\r\n"; + $out .= "Host: ".$CONF['self_host']."\r\n"; + $out .= "Connection: Close\r\n\r\n"; + + fwrite($fp, $out); + fclose($fp); + } + } + + exit(0); +?> \ No newline at end of file diff --git a/code/web/app/app_achievements/_AchWebParser/AchWebParser.php b/code/web/app/app_achievements/_AchWebParser/AchWebParser.php index 84ec7273c..68cb415b5 100644 --- a/code/web/app/app_achievements/_AchWebParser/AchWebParser.php +++ b/code/web/app/app_achievements/_AchWebParser/AchWebParser.php @@ -2,20 +2,43 @@ error_reporting(E_ALL ^ E_NOTICE); ini_set("display_errors","1"); + if(file_exists("parser.stop")) { + exit(0); + } + require_once("class/mySQL_class.php"); require_once("conf.php"); require_once("inlcude/functions_inc.php"); $logfile = false; if($CONF['logging'] == true) { - $logfile = fopen($CONF['logfile'].'.'.date("Ymd",time()).'.txt','a'); + require_once("class/Logfile_class.php"); + #$logfile = fopen($CONF['logfile'].'.'.date("Ymd",time()).'.txt','a'); + $logfile = new Logfile($CONF['logfile']); + } + + //set mode: cron || single with given cid + #MISSING: conf to allow external calls; whitelist ips + $MODE = "CRON"; + if($_REQUEST["cid"] > 0 || $_REQUEST["invoke"] == "TRUE") { + if($_REQUEST["cid"] > 0 && $_REQUEST["invoke"] == "TRUE") { + $MODE = "SINGLE"; + $CID = $DBc->mre($_REQUEST["cid"]); + } + else { + $e = "Failed to start SINGLE mode; cid=".$_REQUEST["cid"]; + logf($e); + die($e); + } } //create database connection $DBc = new mySQL($CONF['mysql_error']); $DBc->connect($CONF['mysql_server'],$CONF['mysql_user'],$CONF['mysql_pass'],$CONF['mysql_database']); - #MISSING: mode -> single, cron, debug + if($MODE == "CRON") { + $RID = $DBc->sendSQL("INSERT INTO ach_monitor_state (ams_start,ams_end) VALUES ('".time()."','0')","INSERT"); // insert run into monitoring table + } require_once("class/DataSourceHandler_class.php"); require_once("class/DataSource_abstract.php"); @@ -30,26 +53,127 @@ $_DATA->registerDataSource($tmp); } - #MISSING: fetch candidates + //synch chars from ring_open character table + if($CONF['synch_chars'] == true) { + $DBc_char = new mySQL($CONF['mysql_error']); + $DBc_char->connect($CONF['char_mysql_server'],$CONF['char_mysql_user'],$CONF['char_mysql_pass'],$CONF['char_mysql_database']); - foreach() { - #MISSING: fetch objectives to evaluate - foreach() { - #MISSING: fetch atoms - foreach() { - #MISSING: evaluate atoms - } - #MISSING: evaluate objective + $DBc->sendSQL("UPDATE ach_monitor_character SET amc_confirmed='0'","NONE"); + + $res = $DBc_char->sendSQL("SELECT char_id,last_played_date FROM characters","ARRAY"); + $sz = sizeof($res); + for($i=0;$i<$sz;$i++) { + $DBc->sendSQL("INSERT INTO ach_monitor_character (amc_character,amc_last_import,amc_last_login,amc_confirmed) VALUES ('".$res[$i]['char_id']."','0','".dateTime_to_timestamp($res[$i]['last_played_date'])."','1') ON DUPLICATE KEY UPDATE amc_confirmed='1', amc_last_login='".dateTime_to_timestamp($res[$i]['last_played_date'])."'","NONE"); } - #MISSING: evaluate perk + + $DBc->sendSQL("DELETE FROM ach_monitor_character WHERE amc_confirmed='0'","NONE"); //remove deleted characters + //remove data for deleted chars + $DBc->sendSQL("DELETE FROM ach_player_atom WHERE NOT EXISTS (SELECT * FROM ach_monitor_character WHERE amc_character='apa_player')","NONE"); + $DBc->sendSQL("DELETE FROM ach_player_objective WHERE NOT EXISTS (SELECT * FROM ach_monitor_character WHERE amc_character='apo_player')","NONE"); + $DBc->sendSQL("DELETE FROM ach_player_perk WHERE NOT EXISTS (SELECT * FROM ach_monitor_character WHERE amc_character='app_player')","NONE"); + $DBc->sendSQL("DELETE FROM ach_player_valuecache WHERE NOT EXISTS (SELECT * FROM ach_monitor_character WHERE amc_character='apv_player')","NONE"); } - + #MISSING: fetch candidates + if($MODE == "SINGLE") { + $chars = array(); + $chars[] = array('amc_character',$CID); + } + else { + $chars = array(); + } + //fork if enabled in conf + if($CONF['fork'] == true && $MODE == "CRON") { + require_once("class/ParallelCURL_class.php"); + + $max_requests = 0; + $curl_options = array( + CURLOPT_SSL_VERIFYPEER => FALSE, + CURLOPT_SSL_VERIFYHOST => FALSE, + CURLOPT_USERAGENT, 'Ryzom - Achievement Tracker', + ); + + $_CURL = new ParallelCurl($max_requests, $curl_options); + + foreach($chars as $elem) { + $_CURL->startRequest("http://".$CONF['self_host']."/".$CONF['self_path']."?invoke=TRUE&cid=".$elem['amc_character'], 'received_char',null); + } + } + else { + $atom_list = array(); + + foreach($chars as $elem) { + #STEP 1: evaluate atoms + + //get unfinished perks which have no parent or complete parent + $res = $DBc->sendSQL("SELECT ap_id FROM ach_perk WHERE (ap_parent IS NULL OR EXISTS (SELECT * FROM ach_player_perk WHERE app_player='".$elem['amc_character']."' AND app_perk=ap_parent)) AND (NOT EXISTS (SELECT * FROM ach_player_perk WHERE app_player='".$elem['amc_character']."' AND app_perk=ap_id))","ARRAY"); + foreach($res as $perk) { + //get unfinished atoms belonging to unfinished objectives + $res = $DBc->sendSQL("","ARRAY"); + foreach($res2 as $atom) { + if(!isset($atom_list[$atom['atom_id']])) { // only load if not already cached + $atom_list[$atom['atom_id']] = new Atom($atom); + } + + $atom_list[$atom['atom_id']]->evalRuleset($elem['amc_character']); + } + } + + #STEP 2: detect obj/perk progression + //obj + $res = $DBc->sendSQL("SELECT ao_id FROM ach_objective WHERE ao_condition='all' AND NOT EXISTS (SELECT * FROM ach_atom WHERE atom_objective=ao_id AND NOT EXISTS (SELECT * FROM ach_player_atom WHERE apa_atom=atom_id AND apa_state!='GRANT' AND apa_player='".$elem['amc_character']."'))","ARRAY"); + $sz = sizeof($res); + for($i=0;$i<$sz;$i++) { + $DBc->sendSQL("INSERT INTO ach_player_objective (apo_objective,apo_player,apo_date) VALUES ('".$res[$i]['ao_id']."','".$elem['amc_character']."','".time()."')","NONE"); + } + + $res = $DBc->sendSQL("SELECT ao_id FROM ach_objective WHERE ao_condition='value' AND ao_value<=(SELECT count(*) FROM ach_atom WHERE atom_objective=ao_id AND EXISTS (SELECT * FROM ach_player_atom WHERE apa_atom=atom_id AND apa_state='GRANT' AND apa_player='".$elem['amc_character']."'))","ARRAY"); + $sz = sizeof($res); + for($i=0;$i<$sz;$i++) { + $DBc->sendSQL("INSERT INTO ach_player_objective (apo_objective,apo_player,apo_date) VALUES ('".$res[$i]['ao_id']."','".$elem['amc_character']."','".time()."')","NONE"); + } + + $res = $DBc->sendSQL("SELECT ao_id FROM ach_objective WHERE ao_condition='any' AND EXISTS (SELECT * FROM ach_atom WHERE atom_objective=ao_id AND EXISTS (SELECT * FROM ach_player_atom WHERE apa_atom=atom_id AND apa_state='GRANT' AND apa_player='".$elem['amc_character']."'))","ARRAY"); + $sz = sizeof($res); + for($i=0;$i<$sz;$i++) { + $DBc->sendSQL("INSERT INTO ach_player_objective (apo_objective,apo_player,apo_date) VALUES ('".$res[$i]['ao_id']."','".$elem['amc_character']."','".time()."')","NONE"); + } + + //perk + $res = $DBc->sendSQL("SELECT ap_id FROM ach_perk WHERE ap_condition='all' AND NOT EXISTS (SELECT * FROM ach_objective WHERE ao_perk=ap_id AND NOT EXISTS (SELECT * FROM ach_player_objective WHERE apo_objective=ao_id AND apo_state!='GRANT' AND apo_player='".$elem['amc_character']."'))","ARRAY"); + $sz = sizeof($res); + for($i=0;$i<$sz;$i++) { + $DBc->sendSQL("INSERT INTO ach_player_perk (app_objective,app_player,app_date) VALUES ('".$res[$i]['ap_id']."','".$elem['amc_character']."','".time()."')","NONE"); + } + + $res = $DBc->sendSQL("SELECT ap_id FROM ach_perk WHERE ap_condition='value' AND ap_value<=(SELECT count(*) FROM ach_objective WHERE ao_perk=ap_id AND EXISTS (SELECT * FROM ach_player_objective WHERE apo_objective=ao_id AND apo_state='GRANT' AND apo_player='".$elem['amc_character']."'))","ARRAY"); + $sz = sizeof($res); + for($i=0;$i<$sz;$i++) { + $DBc->sendSQL("INSERT INTO ach_player_perk (app_objective,app_player,app_date) VALUES ('".$res[$i]['ap_id']."','".$elem['amc_character']."','".time()."')","NONE"); + } + + $res = $DBc->sendSQL("SELECT ap_id FROM ach_perk WHERE ap_condition='any' AND EXISTS (SELECT * FROM ach_objective WHERE ao_perk=ap_id AND EXISTS (SELECT * FROM ach_player_objective WHERE apo_objective=ao_id AND apo_state='GRANT' AND apo_player='".$elem['amc_character']."'))","ARRAY"); + $sz = sizeof($res); + for($i=0;$i<$sz;$i++) { + $DBc->sendSQL("INSERT INTO ach_player_perk (app_objective,app_player,app_date) VALUES ('".$res[$i]['ap_id']."','".$elem['amc_character']."','".time()."')","NONE"); + } + } + } + + if($CONF['sleep_time'] != false) { + sleep($CONF['sleep_time']); + } + + if($logfile) { + $logfile->write(); + } + + //self call if cron mode is on + if($MODE == "CRON" && $CONF['enable_selfcall'] == true) { + $DBc->sendSQL("UPDATE ach_monitor_state SET ams_end='".time()."' WHERE ams_id='".$RID."'","NONE"); - #MISSING: self call on cron mode - if() { $fp = fsockopen($CONF['self_host'], 80, $errno, $errstr, 30); if(!$fp) { logf("ERROR: self call; socket: ".$errstr." (."$errno.")"); diff --git a/code/web/app/app_achievements/_AchWebParser/_doc/Class_scheme.dia b/code/web/app/app_achievements/_AchWebParser/_doc/Class_scheme.dia index b620e6af4..2295a2aff 100644 Binary files a/code/web/app/app_achievements/_AchWebParser/_doc/Class_scheme.dia and b/code/web/app/app_achievements/_AchWebParser/_doc/Class_scheme.dia differ diff --git a/code/web/app/app_achievements/_AchWebParser/_doc/Class_scheme.png b/code/web/app/app_achievements/_AchWebParser/_doc/Class_scheme.png index 30f5e89af..fc92edd83 100644 Binary files a/code/web/app/app_achievements/_AchWebParser/_doc/Class_scheme.png and b/code/web/app/app_achievements/_AchWebParser/_doc/Class_scheme.png differ diff --git a/code/web/app/app_achievements/_AchWebParser/class/Atom_class.php b/code/web/app/app_achievements/_AchWebParser/class/Atom_class.php index 435eac302..0d04b8960 100644 --- a/code/web/app/app_achievements/_AchWebParser/class/Atom_class.php +++ b/code/web/app/app_achievements/_AchWebParser/class/Atom_class.php @@ -1,118 +1,21 @@ ruleset = $data['atom_ruleset']; - $this->ruleset_parsed = false; + $this->ruleset = $data['atom_ruleset_parsed']; $this->id = $data['atom_id']; $this->objective = $data['atom_objective']; } - private function parseRuleset() { - #WORKPAD:#### - /* - Trigger: - by value - (by event) - - Sources: - XML - valuecache - ring_open - (Achievement Service) - (Mirror Service) - - Keywords: - VALUE - GRANT:EVENT player_death - DENY:TIMER 3600 - RESET - RESET_ALL - UNLOCK - UNLOCK_ALL - - IF - SCRIPT - MSG - - VALUE dappers = c_money - IF(dappers >= 5000) { - GRANT - } - - VALUE tmp = c_fame[scorchers] - IF(tmp == 0) { - DENY:3600 - } - - VALUE x = c_pos_x - VALUE y = c_pos_y - SCRIPT inside(x,y) { - IF(MSG == "Majestic Garden") { - GRANT - } - } - - EVENT player_death - ON player_death { - UNLOCK - } - - EVENT region_changed - ON region_changed { - IF(MSG == "Majestic Garden") { - GRANT - } - } - */ - ############# - - - VALUE var = name - - IF(statement) { - - } - - SCRIPT script(a,r,g,s) { - MSG - } - - EVENT name - - ON name { - MSG - } - - GRANT - GRANT:EVENT name - GRANT:TIMER seconds - - DENY - DENY:EVENT name - DENY:TIMER seconds - - RESET - RESET_ALL - UNLOCK - UNLOCK_ALL - } - function evalRuleset($user) { global $DBc,$_DATA; - if($this->ruleset_parsed == false) { - $this->parseRuleset(); - } - try { - return eval($this->ruleset_parsed); + return eval($this->ruleset); } catch(Exception $e) { return $e->getMessage() @@ -137,8 +40,14 @@ $DBc->sendSQL("DELETE FROM ach_player_atom WHERE apa_atom='".$this->id."' AND apa_player='".$user."'","NONE"); } - private function reset_all() { + private function reset_all($user) { + global $DBc; + $res = $DBc->sendSQL("SELECT atom_id FROM ach_atom WHERE atom_objective='".$this->objective."'","ARRAY"); + $sz = sizeof($res); + for($i=0;$i<$sz;$i++) { + $DBc->sendSQL("DELETE FROM ach_player_atom WHERE apa_atom='".$res[$i]['atom_id']."' AND apa_player='".$user."'","NONE"); + } } private function unlock($user) { @@ -147,8 +56,14 @@ $DBc->sendSQL("DELETE FROM ach_player_atom WHERE apa_atom='".$this->id."' AND apa_player='".$user."' AND apa_state='DENY'","NONE"); } - private function unlock_all() { + private function unlock_all($user) { + global $DBc; + $res = $DBc->sendSQL("SELECT atom_id FROM ach_atom WHERE atom_objective='".$this->objective."'","ARRAY"); + $sz = sizeof($res); + for($i=0;$i<$sz;$i++) { + $DBc->sendSQL("DELETE FROM ach_player_atom WHERE apa_atom='".$res[$i]['atom_id']."' AND apa_player='".$user."' AND apa_state='DENY'","NONE"); + } } function getID() { diff --git a/code/web/app/app_achievements/_AchWebParser/class/DataSourceHandler_class.php b/code/web/app/app_achievements/_AchWebParser/class/DataSourceHandler_class.php index 53b64d8d6..8c446d25f 100644 --- a/code/web/app/app_achievements/_AchWebParser/class/DataSourceHandler_class.php +++ b/code/web/app/app_achievements/_AchWebParser/class/DataSourceHandler_class.php @@ -6,36 +6,50 @@ function DataSourceHandler() { $this->source = array(); $this->alloc = array(); - - } function registerDataSource($src) { $i = sizeof($this->source); $this->source[$i] = $src; foreach($src->getTypes() as $elem) { - if(!is_array($this->alloc[$elem])) { - $this->alloc[$elem] = array(); - } //add to list - $this->alloc[$elem][$src->getPriority($elem)] = $i; + $this->alloc[$elem] = $i; } } - function getData($type,$field,$ident) { - return $this->getDataSource($type)->getData($type,$field,$ident); + function getData($ident,$field) { + $type = false; + $tmp = $this->getDataSource($field,$type); + if($tmp == false) { + return false; + } + return $tmp->getData($field,$ident,$type); } - private function getDataSource($type) { - //find the highest priority datasource for given type + function writeData($ident,$field,$data) { + $type = false; + $tmp = $this->getDataSource($field,$type); + if($tmp == false) { + return false; + } + return $tmp->writeData($field,$ident,$data,$type); + } + + + private function getDataSource(&$field,&$type) { + $type = $field; + //allow wildcard datafields + $tmp = explode(":",$field); + if(sizeof($tmp) > 1) { + $field = $tmp[1]; + $type = $tmp[0]."*"; + } + if(!$this->alloc[$type]) { return false; //unknown type } - $pos = array_keys($this->alloc[$type]); - if(sizeof($pos) == 0) { - return false; //no datasource for type // should not happen since type is defined by datasource - } - return $this->alloc[$type][$pos[0]]; + + return $this->source[$this->alloc[$type]]; } } ?> \ No newline at end of file diff --git a/code/web/app/app_achievements/_AchWebParser/class/DataSource_abstract.php b/code/web/app/app_achievements/_AchWebParser/class/DataSource_abstract.php index 4b5d64bf6..02453f06e 100644 --- a/code/web/app/app_achievements/_AchWebParser/class/DataSource_abstract.php +++ b/code/web/app/app_achievements/_AchWebParser/class/DataSource_abstract.php @@ -1,24 +1,25 @@ types = $CONF["types"]; + $this->write = $CONF["write"]; } function getTypes() { return $this->types; } - function getPriority($type) { - return $this->priority[$type]; + function isWriteable() { + return $this->write; } - abstract function getData($type,$ident,$field = array()); + abstract function getData($ident,$field,$type); - abstract function writeData($type,$ident,$field = array(),$value = array()); + abstract function writeData($ident,$field,$data,$type); } ?> \ No newline at end of file diff --git a/code/web/app/app_achievements/_AchWebParser/class/Logfile_class.php b/code/web/app/app_achievements/_AchWebParser/class/Logfile_class.php new file mode 100644 index 000000000..58254ff3c --- /dev/null +++ b/code/web/app/app_achievements/_AchWebParser/class/Logfile_class.php @@ -0,0 +1,22 @@ +logfile = $f; + $this->buffer = ""; + } + + function append($t) { + $this->buffer .= $t; + } + + function write() { + $f = fopen($this->logfile.'.'.date("Ymd",time()).'.txt','a'); + fwrite($f,$this->buffer); + fclose($f); + $this->buffer = ""; + } + } +?> \ No newline at end of file diff --git a/code/web/app/app_achievements/_AchWebParser/class/ParallelCURL_class.php b/code/web/app/app_achievements/_AchWebParser/class/ParallelCURL_class.php new file mode 100644 index 000000000..233d7a101 --- /dev/null +++ b/code/web/app/app_achievements/_AchWebParser/class/ParallelCURL_class.php @@ -0,0 +1,160 @@ +startRequest('http://example.com', 'on_request_done', array('something')); +// +// The first argument is the address that should be fetched +// The second is the callback function that will be run once the request is done +// The third is a 'cookie', that can contain arbitrary data to be passed to the callback +// +// This startRequest call will return immediately, as long as less than the maximum number of +// requests are outstanding. Once the request is done, the callback function will be called, eg: +// +// on_request_done($content, 'http://example.com', $ch, array('something')); +// +// The callback should take four arguments. The first is a string containing the content found at +// the URL. The second is the original URL requested, the third is the curl handle of the request that +// can be queried to get the results, and the fourth is the arbitrary 'cookie' value that you +// associated with this object. This cookie contains user-defined data. +// +// By Pete Warden , freely reusable, see http://petewarden.typepad.com for more + +class ParallelCurl { + + public $max_requests; + public $options; + + public $outstanding_requests; + public $multi_handle; + + public function __construct($in_max_requests = 10, $in_options = array()) { + $this->max_requests = $in_max_requests; + $this->options = $in_options; + + $this->outstanding_requests = array(); + $this->multi_handle = curl_multi_init(); + } + + //Ensure all the requests finish nicely + public function __destruct() { + $this->finishAllRequests(); + } + + // Sets how many requests can be outstanding at once before we block and wait for one to + // finish before starting the next one + public function setMaxRequests($in_max_requests) { + $this->max_requests = $in_max_requests; + } + + // Sets the options to pass to curl, using the format of curl_setopt_array() + public function setOptions($in_options) { + + $this->options = $in_options; + } + + // Start a fetch from the $url address, calling the $callback function passing the optional + // $user_data value. The callback should accept 3 arguments, the url, curl handle and user + // data, eg on_request_done($url, $ch, $user_data); + public function startRequest($url, $callback, $user_data = array(), $post_fields=null) { + + if( $this->max_requests > 0 ) + $this->waitForOutstandingRequestsToDropBelow($this->max_requests); + + $ch = curl_init(); + curl_setopt_array($ch, $this->options); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + + if (isset($post_fields)) { + curl_setopt($ch, CURLOPT_POST, TRUE); + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields); + } + + curl_multi_add_handle($this->multi_handle, $ch); + + $ch_array_key = (int)$ch; + + $this->outstanding_requests[$ch_array_key] = array( + 'url' => $url, + 'callback' => $callback, + 'user_data' => $user_data, + ); + + $this->checkForCompletedRequests(); + } + + // You *MUST* call this function at the end of your script. It waits for any running requests + // to complete, and calls their callback functions + public function finishAllRequests() { + $this->waitForOutstandingRequestsToDropBelow(1); + } + + // Checks to see if any of the outstanding requests have finished + private function checkForCompletedRequests() { + + // Call select to see if anything is waiting for us + if (curl_multi_select($this->multi_handle, 0.0) === -1) + return; + + // Since something's waiting, give curl a chance to process it + do { + $mrc = curl_multi_exec($this->multi_handle, $active); + } while ($mrc == CURLM_CALL_MULTI_PERFORM); + + // Now grab the information about the completed requests + while ($info = curl_multi_info_read($this->multi_handle)) { + + $ch = $info['handle']; + $ch_array_key = (int)$ch; + + if (!isset($this->outstanding_requests[$ch_array_key])) { + die("Error - handle wasn't found in requests: '$ch' in ". + print_r($this->outstanding_requests, true)); + } + + $request = $this->outstanding_requests[$ch_array_key]; + + $url = $request['url']; + $content = curl_multi_getcontent($ch); + $callback = $request['callback']; + $user_data = $request['user_data']; + + call_user_func($callback, $content, $url, $ch, $user_data); + + unset($this->outstanding_requests[$ch_array_key]); + + curl_multi_remove_handle($this->multi_handle, $ch); + } + + } + + // Blocks until there's less than the specified number of requests outstanding + private function waitForOutstandingRequestsToDropBelow($max) + { + while (1) { + $this->checkForCompletedRequests(); + if (count($this->outstanding_requests)<$max) + break; + + usleep(10000); + } + } + +} + + +?> \ No newline at end of file diff --git a/code/web/app/app_achievements/_AchWebParser/class/mySQL_class.php b/code/web/app/app_achievements/_AchWebParser/class/mySQL_class.php index 4202ffcd8..dba981254 100644 --- a/code/web/app/app_achievements/_AchWebParser/class/mySQL_class.php +++ b/code/web/app/app_achievements/_AchWebParser/class/mySQL_class.php @@ -19,7 +19,7 @@ function mySQL($err=false) { $this->DBstats = array(); $this->DBc = false; - if($err === "DIE" || $err === "PRINT" || $err === "ALERT" || $err === "HIDE") { + if($err === "DIE" || $err === "PRINT" || $err === "ALERT" || $err === "HIDE" || $err === "LOG") { $this->DBerror = $err; } else { @@ -31,13 +31,16 @@ function connect($ip,$user,$pass,$db=false) { $this->DBc = mysql_pconnect($ip,$user,$pass) or $this->error(mysql_error()); - if($db) { + if($this->DBc && $db) { $this->database($db); } $this->resetStats(); } function database($db) { + if(!$this->DBc) { + return false; + } mysql_select_db($db,$this->DBc) or $this->error(mysql_error()); } @@ -54,6 +57,9 @@ #if($this->cached !== false) { #$this->unlinkSql($this->cached); #} + if(!$this->DBc) { + return false; + } if($buffer === false && $handling !== "PLAIN") { $res = mysql_unbuffered_query($query,$this->DBc) or $this->error(mysql_error(),$query); @@ -142,6 +148,9 @@ case 'ALERT': echo ""; break; + case 'LOG': + logf("MySQL ERROR: ".$error); + break; default: flush(); break; diff --git a/code/web/app/app_achievements/_AchWebParser/conf.php b/code/web/app/app_achievements/_AchWebParser/conf.php new file mode 100644 index 000000000..23401b223 --- /dev/null +++ b/code/web/app/app_achievements/_AchWebParser/conf.php @@ -0,0 +1,31 @@ + \ No newline at end of file diff --git a/code/web/app/app_achievements/_AchWebParser/include/functions_inc.php b/code/web/app/app_achievements/_AchWebParser/include/functions_inc.php index 17e9a89ae..969ffc2f1 100644 --- a/code/web/app/app_achievements/_AchWebParser/include/functions_inc.php +++ b/code/web/app/app_achievements/_AchWebParser/include/functions_inc.php @@ -5,7 +5,7 @@ if($nl) { $txt .= "\n"; } - fwrite($logfile,"[".date('H:i:s',time())."] ".$txt); + $logfile->append("[".date('H:i:s',time())."] ".$txt); } } @@ -16,4 +16,17 @@ } return $tmp."> ".$txt; } + + function dateTime_to_timestamp($dt) { + #2012-05-12 00:26:40 + $tmp = explode(" ",$dt); + $d = explode("-",$tmp[0]); + $t = explode(":",$tmp[1]); + + return mktime($t[0],$t[1],$t[2],$d[1],$d[2],$d[0]); + } + + function received_char($res, $url, $ch, $argv) { + logf("character tracking returned: ".$res); + } ?> \ No newline at end of file diff --git a/code/web/app/app_achievements/_AchWebParser/log/_logDefaultDir_ b/code/web/app/app_achievements/_AchWebParser/log/_logDefaultDir_ new file mode 100644 index 000000000..e69de29bb diff --git a/code/web/app/app_achievements/_AchWebParser/parser.php b/code/web/app/app_achievements/_AchWebParser/parser.php new file mode 100644 index 000000000..65836d1ee --- /dev/null +++ b/code/web/app/app_achievements/_AchWebParser/parser.php @@ -0,0 +1,132 @@ +private function parseRuleset() { + $this->ruleset_parsed = $this->ruleset; + #WORKPAD:#### + /* + Trigger: + by value + (by event) + + Sources: + XML + valuecache + ring_open + (Achievement Service) + (Mirror Service) + + Keywords: + VALUE + GRANT:EVENT player_death + DENY:TIMER 3600 + RESET + RESET_ALL + UNLOCK + UNLOCK_ALL + + IF + SCRIPT + MSG + + VALUE dappers = c_money + IF(dappers >= 5000) { + GRANT + } + + VALUE sum = c_cache:sum + IF(sum > 1000) { + GRANT + } + + VALUE tmp = c_fame[scorchers] + IF(tmp == 0) { + DENY:3600 + } + + VALUE x = c_pos_x + VALUE y = c_pos_y + SCRIPT inside(x,y) { + IF(MSG == "Majestic Garden") { + GRANT + } + } + + EVENT player_death + ON player_death { + UNLOCK + } + + EVENT region_changed + ON region_changed { + IF(MSG == "Majestic Garden") { + GRANT + } + } + */ + ############# + + + #VALUE var = name; + $match = array(); + preg_match_all("#VALUE ([a-zA-Z0-9_]) ?= ?([a-zA-Z0-9_]);#", $this->ruleset_parsed, $match,PREG_PATTERN_ORDER); + foreach($match[0] as $key=>$elem) { + $tmp = '$'.$match[1][$key].' = $_DATA->getData("VALUE","'.$match[2][$key].'",$user);\n'; + $tmp .= 'if($'.$match[1][$key].' == ) {\n'; + $tmp .= 'ERROR\n'; + $tmp .= '}\n'; + $this->ruleset_parsed = str_replace($elem,$tmp,$this->ruleset_parsed); + } + + + #IF(statement) { } + $match = array(); + preg_match_all("#IF ?\(([^\)]*)\) ?{#", $this->ruleset_parsed, $match,PREG_PATTERN_ORDER); + foreach($match[0] as $key=>$elem) { + $tmp = 'if() {\n'; + $this->ruleset_parsed = str_replace($elem,$tmp,$this->ruleset_parsed); + } + + + SCRIPT script(a,r,g,s) { + MSG + } + + #EVENT name; + $match = array(); + preg_match_all("#EVENT ([^;]*);#", $this->ruleset_parsed, $match,PREG_PATTERN_ORDER); + foreach($match[0] as $key=>$elem) { + $tmp = ''; + $this->ruleset_parsed = str_replace($elem,$tmp,$this->ruleset_parsed); + } + + ON name { + MSG + } + + #GRANT; + #GRANT:EVENT name; + #GRANT:TIMER seconds; + $match = array(); + preg_match_all("#GRANT:?([^;]*);#", $this->ruleset_parsed, $match,PREG_PATTERN_ORDER); + foreach($match[0] as $key=>$elem) { + $tmp = '$this->grant("'.$match[1][$key].'");'; + $this->ruleset_parsed = str_replace($elem,$tmp,$this->ruleset_parsed); + } + + #DENY; + #DENY:EVENT name; + #DENY:TIMER seconds; + $match = array(); + preg_match_all("#DENY:?([^;]*);#", $this->ruleset_parsed, $match,PREG_PATTERN_ORDER); + foreach($match[0] as $key=>$elem) { + $tmp = '$this->deny("'.$match[1][$key].'");'; + $this->ruleset_parsed = str_replace($elem,$tmp,$this->ruleset_parsed); + } + + #RESET; + #RESET_ALL; + #UNLOCK; + #UNLOCK_ALL; + $this->ruleset_parsed = str_replace("RESET_ALL;",'$this->reset_all();',$this->ruleset_parsed); + $this->ruleset_parsed = str_replace("RESET;",'$this->reset_();',$this->ruleset_parsed); + $this->ruleset_parsed = str_replace("UNLOCK_ALL;",'$this->unlock_all();',$this->ruleset_parsed); + $this->ruleset_parsed = str_replace("UNLOCK;",'$this->unlock();',$this->ruleset_parsed); + } \ No newline at end of file diff --git a/code/web/app/app_achievements/_AchWebParser/source/ValueCache/ValueCache_class.php b/code/web/app/app_achievements/_AchWebParser/source/ValueCache/ValueCache_class.php index 84c174124..7918e27e5 100644 --- a/code/web/app/app_achievements/_AchWebParser/source/ValueCache/ValueCache_class.php +++ b/code/web/app/app_achievements/_AchWebParser/source/ValueCache/ValueCache_class.php @@ -1,26 +1,19 @@ types[] = "c_cache"; - - $this->write = true; + parent::__construct(); } - function getData($type,$ident,$field) { + function getData($ident,$field,$type) { + $res = $DBc->sendSQL("SELECT apv_value,apv_date FROM ach_player_valuecache WHERE apv_name='".$DBc->mre($field)."' AND apv_player='".$DBc->mre($ident)."'","ARRAY"); + return array($res[0]['apv_value'],$res[0]['apv_date']); } - function writeData($type,$ident,$field = array(),$value = array()) { + function writeData($ident,$field,$data,$type) { global $DBc; - if($type == "c_cache") { - $DBc->sendSQL("INSERT INTO ach_player_valuecache () VALUES () ON DUPLICATE KEY UPDATE "); - - return true; - } - else { - return false; - } + $DBc->sendSQL("INSERT INTO ach_player_valuecache (apv_name,apv_player,apv_value,apv_date) VALUES ('".$DBc->mre($field)."','".$DBc->mre($ident)."','".$DBc->mre($data)."','".time()."') ON DUPLICATE KEY UPDATE apv_value='".$DBc->mre($data)."', apv_date='".time()."'","NONE"); } } ?> \ No newline at end of file diff --git a/code/web/app/app_achievements/_AchWebParser/source/ValueCache/conf.php b/code/web/app/app_achievements/_AchWebParser/source/ValueCache/conf.php new file mode 100644 index 000000000..117d56f0a --- /dev/null +++ b/code/web/app/app_achievements/_AchWebParser/source/ValueCache/conf.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/code/web/app/app_achievements/_AchWebParser/source/XMLapi/XMLapi_class.php b/code/web/app/app_achievements/_AchWebParser/source/XMLapi/XMLapi_class.php index 6ae24a6ac..e1b2270f0 100644 --- a/code/web/app/app_achievements/_AchWebParser/source/XMLapi/XMLapi_class.php +++ b/code/web/app/app_achievements/_AchWebParser/source/XMLapi/XMLapi_class.php @@ -1,17 +1,29 @@ types[] = "c_stats"; - $this->types[] = "c_items"; + parent::__construct(); - $this->write = false; + $this->xml_path = $CONF['xml_path']; } - function getData() { - + function getData($ident,$field,$type) { + switch($type) { + case "c_stats": + $path = $this->xml_path."full/".$ident.".xml"; + break; + case "c_items": + $path = $this->xml_path."item/".$ident.".xml"; + break; + default: + return false; + break; + } + $xml = new SimpleXMLElement($string); } - function writeData() { + function writeData($ident,$field,$data,$type) { return false; } diff --git a/code/web/app/app_achievements/_AchWebParser/source/XMLapi/conf.php b/code/web/app/app_achievements/_AchWebParser/source/XMLapi/conf.php new file mode 100644 index 000000000..d71249d09 --- /dev/null +++ b/code/web/app/app_achievements/_AchWebParser/source/XMLapi/conf.php @@ -0,0 +1,8 @@ + \ No newline at end of file