#1470 monday's commit: update on parser (still incomplete); wip datasources; initial monitoring cronjob (done); various minor changes, fixes and so
--HG-- branch : gsoc2012-achievements
This commit is contained in:
parent
6d33124bc3
commit
8aeabcd247
18 changed files with 635 additions and 159 deletions
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
error_reporting(E_ALL ^ E_NOTICE);
|
||||
ini_set("display_errors","1");
|
||||
|
||||
if(file_exists("monitor.stop")) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
require_once("class/mySQL_class.php");
|
||||
require_once("conf.php");
|
||||
|
||||
//create database connection
|
||||
$DBc = new mySQL($CONF['mysql_error']);
|
||||
$DBc->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);
|
||||
?>
|
|
@ -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);
|
||||
}
|
||||
|
||||
//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']);
|
||||
|
||||
$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");
|
||||
}
|
||||
|
||||
$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
|
||||
|
||||
foreach() {
|
||||
#MISSING: fetch objectives to evaluate
|
||||
foreach() {
|
||||
#MISSING: fetch atoms
|
||||
foreach() {
|
||||
#MISSING: evaluate atoms
|
||||
if($MODE == "SINGLE") {
|
||||
$chars = array();
|
||||
$chars[] = array('amc_character',$CID);
|
||||
}
|
||||
#MISSING: evaluate objective
|
||||
}
|
||||
#MISSING: evaluate perk
|
||||
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.")");
|
||||
|
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 9.7 KiB |
|
@ -1,118 +1,21 @@
|
|||
<?php
|
||||
class Atom {
|
||||
private $ruleset;
|
||||
private $ruleset_parsed;
|
||||
|
||||
private $id;
|
||||
private $objective;
|
||||
|
||||
function Atom(&$data) {
|
||||
$this->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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
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]."*";
|
||||
}
|
||||
|
||||
private function getDataSource($type) {
|
||||
//find the highest priority datasource for given type
|
||||
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]];
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -1,24 +1,25 @@
|
|||
<?php
|
||||
abstract class DataSource {
|
||||
private $types = array();
|
||||
private $priority = array();
|
||||
private $write = false;
|
||||
#MISSING: offered values
|
||||
|
||||
function DataSource() {
|
||||
require_once(dirname(__FILE__)."/conf.php");
|
||||
|
||||
$this->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);
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
class Logfile {
|
||||
private $logfile;
|
||||
private $buffer;
|
||||
|
||||
function Logfile($f) {
|
||||
$this->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 = "";
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
// This class is designed to make it easy to run multiple curl requests in parallel, rather than
|
||||
// waiting for each one to finish before starting the next. Under the hood it uses curl_multi_exec
|
||||
// but since I find that interface painfully confusing, I wanted one that corresponded to the tasks
|
||||
// that I wanted to run.
|
||||
//
|
||||
// To use it, first create the ParallelCurl object:
|
||||
//
|
||||
// $parallelcurl = new ParallelCurl(10);
|
||||
//
|
||||
// The first argument to the constructor is the maximum number of outstanding fetches to allow
|
||||
// before blocking to wait for one to finish. You can change this later using setMaxRequests()
|
||||
// The second optional argument is an array of curl options in the format used by curl_setopt_array()
|
||||
//
|
||||
// Next, start a URL fetch:
|
||||
//
|
||||
// $parallelcurl->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 <pete@petewarden.com>, 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
|
@ -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 "<script language='javascript'>\n<!--\nalert(\"database error:\\n".mysql_real_escape_string($error)."\");\n// -->\n</script>";
|
||||
break;
|
||||
case 'LOG':
|
||||
logf("MySQL ERROR: ".$error);
|
||||
break;
|
||||
default:
|
||||
flush();
|
||||
break;
|
||||
|
|
31
code/web/app/app_achievements/_AchWebParser/conf.php
Normal file
31
code/web/app/app_achievements/_AchWebParser/conf.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
$CONF = array();
|
||||
|
||||
$CONF['logging'] = true;
|
||||
$CONF['logfile'] = "log/AchWebParser.log";
|
||||
|
||||
$CONF['mysql_error'] = "";
|
||||
$CONF['mysql_server'] = "localhost";
|
||||
$CONF['mysql_user'] = "root";
|
||||
$CONF['mysql_pass'] = "";
|
||||
$CONF['mysql_database'] = "app_achievements";
|
||||
|
||||
$CONF['data_source'] = array();
|
||||
|
||||
$CONF['synch_chars'] = true
|
||||
$CONF['char_mysql_server'] = "localhost";
|
||||
$CONF['char_mysql_user'] = "root";
|
||||
$CONF['char_mysql_pass'] = "";
|
||||
$CONF['char_mysql_database'] = "ring_open";
|
||||
|
||||
$CONF['fork'] = true;
|
||||
|
||||
$CONF['self_host'] = "127.0.0.1";
|
||||
$CONF['self_path'] = "/path/to/AchWebParser.php";
|
||||
|
||||
$CONF['sleep_time'] = 1500;
|
||||
|
||||
$CONF['enable_selfcall'] = true
|
||||
|
||||
$CONF['timeout'] = 60*60;
|
||||
?>
|
|
@ -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);
|
||||
}
|
||||
?>
|
132
code/web/app/app_achievements/_AchWebParser/parser.php
Normal file
132
code/web/app/app_achievements/_AchWebParser/parser.php
Normal file
|
@ -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);
|
||||
}
|
|
@ -1,26 +1,19 @@
|
|||
<?php
|
||||
class ValueCache extends DataSource {
|
||||
function ValueCache() {
|
||||
$this->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");
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
$CONF = array();
|
||||
|
||||
$CONF['types'] = array("c_cache*");
|
||||
$CONF['write'] = true;
|
||||
|
||||
?>
|
|
@ -1,17 +1,29 @@
|
|||
<?php
|
||||
class XMLapi extends DataSource {
|
||||
private $xml_path;
|
||||
|
||||
function XMLapi() {
|
||||
$this->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;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
$CONF = array();
|
||||
|
||||
$CONF['types'] = array("c_stats*","c_items*");
|
||||
$CONF['write'] = false;
|
||||
|
||||
$CONF['xml_path'] = "foo/bar/xml/"; // this is a dummy ^^
|
||||
?>
|
Loading…
Reference in a new issue