All pastes #2090355 Raw Edit

Anonymous

public text v1 · immutable
#2090355 ·published 2011-10-15 21:14 UTC
rendered paste body
<?php

class Bot {
    var $zySnid;
    var $zySig;
	var $zySig2;		// Added by dhani_reed_cool
	var $zyUid;		    // Added dhani_reed_cool
    var $zyAuthHash;
    var $flashRevision;
    var $usern;
	var $DebugMsg; 	    // Added by dhani_reed_cool
    var $uid;
    var $sequense;

    var $level;
    var $cash;
	var $assetspath;	// dhani_reed_cool
	var $pm;
	var $energy;
    var $immunityExp;
    var $ld;
    var $serverTime;
    var $xp;
    var $energyMax;

    var $fobjects;
	var $Time2Log;	    // Added by dhani_reed_cool
    var $neighbors;

    var $error_msg;
	var $cfg;		    // Added by dhani_reed_cool
    var $hooks;
	
    var $traymsg;
    var $xmlsOb;
    var $firstrun;
	var $postInit;
	var $statistics;	// Added by dhani_reed_cool
	var $HelpRequest;   // Added by Amit
    var $dooberItems;   // Added by dhani_reed_cool
    var $dooberItem;    // Added dhani_reed_cool
    var $CheckDoober;   // Added dhani_reed_cool
	var $inventory;		// Added by pjhkaka

    var $xmlConfig;
	var $x_flash_version;  // Added dhani_reed_cool
    var $streakBonusCheck; // Added by dhani_reed_cool7 to be switch on / off streakBonus
                           // See function streakBonusCheck & doobers
	
    // ==========================================================================
    function Bot()
    {
	
    }
    // ==========================================================================
    function Init() { // Change all action in Botclass.php dhani_reed_cool..
        if ($this->GetParamByName("Time2Log") == 1) {
               $this->Time2Log = 1;
        } else {
               $this->Time2Log = 0;
        }

		ini_set("memory_limit",'-1'); // Added by dhani_reed_cool
		
		$this->CheckDoober = FALSE;	  // Added by dhani_reed_cool
		
        date_default_timezone_set($this->GetParamByName("sTimeZone"));
        
        $this->SendMsg('Bot Init 1');
        define('AMFPHP_BASE', 'amfphp/core/');
        require_once(AMFPHP_BASE . "shared/util/CharsetHandler.php");
        require_once(AMFPHP_BASE . "amf/util/AMFObject.php");
        require_once(AMFPHP_BASE . "shared/util/CompatPhp5.php");
        require_once(AMFPHP_BASE . "shared/util/MessageBody.php");
        require_once(AMFPHP_BASE . "shared/app/Constants.php");
        require_once(AMFPHP_BASE . "shared/app/Globals.php");
        require_once(AMFPHP_BASE . "amf/io/AMFDeserializer.php");
        require_once(AMFPHP_BASE . "amf/io/AMFSerializer.php");
		
        global $headers_file, $amfbin_file;
        if ((file_exists($amfbin_file) == false) or (file_exists($headers_file) == false)) {
            $this->SendMsg('Cannot find MainRequest.bin or Headers.bin');
            $this->SendMsg('If running on windows, please run the bot as administrator');
            exit;
        }

        try {
            $f = fopen($amfbin_file, 'r');
            $size = filesize($amfbin_file);
            $amf = new AMFObject(fread($f, $size));
            fclose($f);
        } catch (Exception $e) {
            $this->SendMsg($e->getMessage());
            exit;
        }

        $deserializer = new AMFDeserializer($amf->rawData);
        $deserializer->deserialize($amf);

        $bod = new MessageBody();
        $bod = $amf->_bodys[0];

        $this->usern = trim($bod->_value[1][0]['params'][0]);
        $this->zyAuthHash = trim($bod->_value['0']['zyAuthHash']);
        $this->flashRevision = trim($bod->_value['0']['flashRevision']);
		// Auto-update to zySig (Added by p627)
		
        if(isset($this->zySig2))
        {
			$this->SendMsg("zySig updated");
			$this->zySig = $this->zySig2 ;
        }
        else
        {
			$this->zySig=trim($bod->_value['0']['zySig']);
        }

        $this->zySnid=trim($bod->_value['0']['zySnid']);

        $fh = file($headers_file);
        $this->url = trim($fh[0]);
        unset($fh[0]);
        foreach ($fh as $value) {
            $pos = strpos($value, ':');
            $name = trim(substr($value, 0, $pos));
            $val = trim(substr($value, $pos + 1, strlen($value)));
            $headers[$name]=$val;
        }
		
        $this->host = $headers['Host'];
        $this->x_flash_version = $headers['x-flash-version'];
        $this->headers["Accept"] = $headers['Accept'];
        $this->headers["Accept-Language"] = $headers['Accept-Language'];
        $this->headers["Referer"] = $headers['Referer'];
        $this->headers["x-flash-version"] = $headers['x-flash-version'];
        $this->headers["Content-Type"] = $headers['Content-Type'];
        $this->headers["Accept-Encoding"] = "gzip, deflate";
        $this->headers["User-Agent"] = $headers['User-Agent'];
        $this->headers["Host"] = $headers['Host'];
        if(isset($headers['Connection'])){
            $this->headers["Connection"] =$headers['Connection'];    
        }
        if(isset($headers['Proxy-Connection'])){
            $this->headers["Proxy-Connection"] =$headers['Proxy-Connection'];
        }
        if(isset($headers['Pragma'])){
            $this->headers["Pragma"] =$headers['Pragma'];
        }
        if(isset($headers['Cache-Control'])){
            $this->headers["Cache-Control"] =$headers['Cache-Control'];
        }
        $this->headers["Cookie"] =$headers['Cookie'];

        $this->pm = new PluginManager();
        $this->pm->GetConfiguration();
		
		$this->DebugMsg = file_exists('tmp_dir\Debug\Flags\DebugMsgTrue.txt');//P627, infos to Debug..
        
    }
        
    // ==========================================================================
    function Init2() { // second phase of the init
                       // after the reload.

        $this->SendMsg('Bot Init 2');

        $this->ld = new LocalData();

        $this->ld->ConnectTo($this->uid); 
		
        global $headers_file, $amfbin_file;
        $this->firstrun=false;
        if ($amfbin_file != 'tmp_dir\\' . $this->uid . '_amf.bin') {
            echo "Deleting old BIN files \n";
            if (file_exists('tmp_dir\\' . $this->uid . '_amf.bin')) {
                unlink('tmp_dir\\' . $this->uid . '_amf.bin');
                unlink('tmp_dir\\' . $this->uid . '_headers.bin');
         }
            $this->firstrun=true;
            SendApi('BotApi.SetUserId=' . $this->uid);
         }
        $this->xmlConfig = new xmlConfig();
        $ConfigArray = array();
        $ConfigArray = $this->GetAmfHeader();
        //$ConfigArray["Cookie"] = $headers['Cookie'];
        $ConfigArray["Cookie"] = $this->headers["Cookie"];
        //$ConfigArray["Referer"] = $headers['Referer'];
        $ConfigArray["Referer"] = $this->headers["Referer"];
        //$ConfigArray["UserAgent"] = $headers['User-Agent'];
        $ConfigArray["UserAgent"] = $this->headers["User-Agent"];
        $ConfigFile = $this->uid . '__Zy.xml';
        $this->xmlConfig->writeXml($ConfigFile, $ConfigArray);

    }
	
    // ==========================================================================
	function IncludeAllHooks() // Update by p627 to read only the enable plugins
	{
		foreach ($this->pm->plugins as $plugin)
		{
			if (($plugin['active'] == '1') && (file_exists($plugin['hooks'])))
			{
				include($plugin['hooks']);
			}
		}
	}

    // ==========================================================================
    function ShowReportMsgInTray() {
        if (count($this->statistics) > 0) {
            foreach ($this->statistics as $key => $value) {
                $this->traymsg[] = $key . " = " . sizeof($value);
            }
        }

        if (isset($this->traymsg)) {
            if (sizeof($this->traymsg) > 0) {
                $this->SendMsg("");

                foreach ($this->traymsg as $msg) {
                    $tmp = $tmp . $msg . "\n";
                    $this->SendMsg($msg);
                }
                if (strlen($tmp) > 0) {
                    SendApi('BotApi.ShowTrayMsg=' . $tmp);
                }
            }
        }
    }

    // ==========================================================================
    function AddHook($hook, $fname) 
	{
        $this->hooks[$hook][] = $fname;
    }

    // ==========================================================================
    function Hook($hook) { // Added by p627
        if (isset($this->hooks[$hook])) {
            foreach ($this->hooks[$hook] as $function) {
                if (function_exists($function)) 
				{
					if (isset($this->DebugMsg) and $this->DebugMsg)
						$this->SendMsg('Debug... Launch : '.$function.' call the group : '.$hook.'...');
					call_user_func($function, $this);
                }
            }
        }
    }

    // ==========================================================================
    function GetAmfHeader() {
        $arr['zyAuthHash'] = $this->zyAuthHash;
        $arr['zySnid'] = $this->zySnid;
        $arr['zySig'] = $this->zySig;
        $arr['flashRevision'] = $this->flashRevision;
        global $Zy;
        $Zy = $arr;
        return $arr;

    }

    // ==========================================================================
    function LoadNeighbors() // Added by p627
	{
		if (isset($this->neighbors) and count($this->neighbors)>0)
			return $this->neighbors;
		else
		{
			//$this->SendMsgDebug('-Load Neighbors-');
			$friends=$this->LoadFriends();
			$this->neighbors=$friends['allNeighbors'];
			return $this->neighbors;
		}
	}
	
    // ==========================================================================
    function LoadFriends() // Added by p627
	{
		unset($this->error_msg);
		//$this->SendMsgDebug('Load Friends');
		
        $amf = new AMFObject($this->PostInit());
        $deserializer = new AMFDeserializer($amf->rawData);
        $deserializer->deserialize($amf);
        $bod = new MessageBody();
        $bod = $amf->_bodys[0];
		
		$ret=array();
		$ret['allInfos_'] = $bod->_value['data'][0]['data'];             
		$ret['allFriendsInfos_'] = $bod->_value['data'][0]['data']['neighbors'];
		$ret['allFriends'] = array();
		$ret['allNeighbors'] = array();
		foreach($ret['allFriendsInfos_'] as $friend)
		{
			$tmp=array();
			$tmp['uid'] = $friend['uid'];
			$tmp['name_'] = $friend['name'];
			$avant = array("'", "|");
			$apres = array(' ', ' ');
			$tmp['name'] = str_replace($avant, $apres, $friend['name']);
			$tmp['level'] = $friend['level'];
			$tmp['xp'] = $friend['xp'];
			$tmp['coins'] = $friend['coins'];
			$tmp['resource'] = $friend['resource'];
			$tmp['lastVisited'] = $friend['lastVisited'];
			$tmp['lastLogin'] = $friend['lastLogin'];
			$tmp['socialLevelGood'] = $friend['socialLevelGood'];
			$tmp['socialXpGood'] = $friend['socialXpGood'];
			$tmp['socialLevelBad'] = $friend['socialLevelBad'];
			$tmp['socialXpBad'] = $friend['socialXpBad'];
			$tmp['isNew'] = $friend['isNew'];
			$tmp['pvpImmunityTimestamp'] = $friend['pvpImmunityTimestamp'];
			$tmp['pvpInfo'] = $friend['pvpInfo'];
			$tmp['pvpNumOccupiers'] = $friend['pvpNumOccupiers'];
			$tmp['tending']['actions'] = $friend['tending']['actions'];
			$tmp['tending']['ts'] = $friend['tending']['ts'];
			
			$tmp['isNeightbor'] = (in_array($tmp['uid'], $this->cfg->_value['data'][0]['data']['userInfo']['player']['neighbors']));

			$ret['allFriends'][]=$tmp;
			if ($tmp['isNeightbor']) $ret['allNeighbors'][]=$tmp;
		}
		return $ret;
	}

    // ==========================================================================
    function SendRequestAMF(&$amf) // Added by p627 
	{
		$serializer = new AMFSerializer();
		$amf = $serializer->serialize($amf);
		$ret = $this->SendRequest($amf);
		
		return $ret;
	}
	
    // ==========================================================================
    function DeserializeRetAMF(&$amf) // Added by p627 
	{
        $amf = new AMFObject($amf);
        $deserializer = new AMFDeserializer($amf->rawData);
        $deserializer->deserialize($amf);
        $bod = new MessageBody();
        $bod = $amf->_bodys[0];
		
        return $bod;
	}

    // ==========================================================================
    function CreateRequestAMF($functionName) // Added by p627 
	{
		$amf = new AMFObject("");
		$amf->_bodys[0] = new MessageBody();
		$amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

		$amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
		$amf->_bodys[0]->responseURI = '';
		$amf->_bodys[0]->_value[2] = 0;

		$amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
		$amf->_bodys[0]->_value[1][0]['functionName'] = $functionName;
		$amf->_bodys[0]->_value[1][0]['params'] = array();
		
		return $amf;
	}

    // ==========================================================================
	function ReloadConfig()//Change settings by p627
	{
		if (isset($this->error_msg))// Added by p627
		{
			unset($this->error_msg); // unset errors
		}
		else 
		{ 
			if($this->didnothing == 1) 
			return; 
		}
		$this->SendMsg('Loading configuration.');
		
		unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '/1';
        $amf->_bodys[0]->_value[2] = 0;

		$amf->_bodys[0]->_value[1][0]['sequence'] = 1;
		$amf->_bodys[0]->_value[1][0]['functionName'] = "UserService.initUser";
		$amf->_bodys[0]->_value[1][0]['params'][0] = $this->usern;
		
        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        $x = $this->SendRequest($result);

        $amf = new AMFObject($x);
        $deserializer = new AMFDeserializer($amf->rawData);
        $deserializer->deserialize($amf);
        $bod = new MessageBody();
        $bod = $amf->_bodys[0];
        $this->cfg = $bod;
        $this->sequense = 1;
		
        $this->zyUid = $bod->_value['data'][0]['data']['snuid']; // Use your real id not Z***a's id... // Added by p627
        $this->uid = $bod->_value['data'][0]['data']['userInfo']['id'];
        $this->cash = $bod->_value['data'][0]['data']['userInfo']['player']['cash'];
        $this->level = $bod->_value['data'][0]['data']['userInfo']['player']['level'];
        $this->xp = $bod->_value['data'][0]['data']['userInfo']['player']['xp'];
        $this->energy = $bod->_value['data'][0]['data']['userInfo']['player']['energy'];
        $this->energyMax = $bod->_value['data'][0]['data']['userInfo']['player']['energyMax'];
        $this->fobjects = $bod->_value['data'][0]['data']['userInfo']['world']['objects'];
		$this->gold = $bod->_value['data'][0]['data']['userInfo']['world']['resources']['coins']; 	   // Added by p627
		$this->oil = $bod->_value['data'][0]['data']['userInfo']['world']['resources']['oil']; 		   // Added by p627
		$this->wood = $bod->_value['data'][0]['data']['userInfo']['world']['resources']['wood']; 	   // Added by p627
		$this->HelpRequest = $bod->_value['data'][0]['data']['visitorHelpRequests'];		  		   // Added by Amit
        $this->immunityExp = $bod->_value['data'][0]['data']['pvp']['immunity']['expTS'];
        $this->serverTime = $bod->_value['data'][0]['serverTime'];
		$this->inventory = (array)$bod->_value['data'][0]['data']['userInfo']['player']['inventory']['items'];	// Added by pjhkaka
			
		$this->SendMsg(">Coins: ".number_format($this->gold)." Wood: ".number_format($this->wood)." Oil: ".number_format($this->oil)." Energy: $this->energy"); // Added by p627
		
		$this->didnothing = 1; // Added by p627
    }
	
    // ==========================================================================
    function PostInit() { //Added by p627
		if (isset($this->postInit) and count($this->postInit)>0)
			return $this->postInit;
        //$this->SendMsg('PostInit');

        $amf=$this->CreateRequestAMF('UserService.initUser');
		$amf->_bodys[0]->_value[1][0]['sequence'] = 1;
        $amf->_bodys[0]->_value[1][0]['params'][0] = $this->usern;

        $this->postInit = $result = $this->SendRequestAMF($amf);
        return $result;
    }
	
    // ==========================================================================
    function AcceptNeighborHelp($neighbor, $pendingActions) // Added by p627
    {
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][0]['functionName'] = "VisitorService.accept";
        $amf->_bodys[0]->_value[1][0]['params'][0] = $neighbor;
		
        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        $x = $this->SendRequest($result);
                
        foreach ($pendingActions as $action)
        {
			//$this->setNeighborState($neighbor, $action);
        }
    }
	
    // ==========================================================================
    function GetEnergy($Energy) // Added by p627
	{
        //$this->statistics['Get energy'][]=1;
		
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][0]['functionName'] = "UserService.useItem";
        $amf->_bodys[0]->_value[1][0]['params'][0] = $Energy;
        
        //add this line to results that does not give dooberitems via AMF, but streak bonus can be collected.
        //$this->dooberItems +=2;

        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);

        $x = $this->SendRequest($result);
        //$this->Add2Report('load world');

        return $x;
    }
	
    // ==========================================================================
    function LoadWorld($nuid, $name) // Added by p627
	{
        //$this->statistics['load world'][]=1;
		
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;
		
        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][0]['functionName'] = "WorldService.loadWorld";
        $amf->_bodys[0]->_value[1][0]['params'][0] = $nuid;
        $amf->_bodys[0]->_value[1][0]['params'][1] = "home";
        $amf->_bodys[0]->_value[1][0]['params'][2] = 0;
		$amf->_bodys[0]->_value[1][0]['params'][3]['dbg'] = 3;
		$amf->_bodys[0]->_value[1][0]['params'][3]['ctx'] = "MessagePane";
		
        //add this line to results that does not give dooberitems via AMF, but streak bonus can be collected.
        //$this->dooberItems +=2;

        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);

        $x = $this->SendRequest($result);
        //$this->Add2Report('load world');

        return $x;
    }
	
    // ==========================================================================
    function HelpNeighbor($hostID, $obj, $reward) // Added by p627
    {
		$this->SendMsg('Action: '.$reward.' = '.$obj['itemName']);
		
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;
		
		$amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][0]['functionName'] = "ZlingshotService.fetch";
        $amf->_bodys[0]->_value[1][0]['params'][0] = $hostID;
			
        $amf->_bodys[0]->_value[1][1]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][1]['functionName'] = "VisitorService.help";
        $amf->_bodys[0]->_value[1][1]['params'][0] = $hostID;
        $amf->_bodys[0]->_value[1][1]['params'][1] = $obj['id'];
        $amf->_bodys[0]->_value[1][1]['params'][2] = $reward;
			
        //add this line to results that does not give dooberitems via AMF, but streak bonus can be collected.
        $this->dooberItems +=2;

        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        $x = $this->SendRequest($result);
			
		return $x;
    }
	 
    // ==========================================================================
    function CheckImmunity()
    {
         $isUnderImmunity = false;
         if ($this->immunityExp > $this->serverTime)
         {
             $this->SendMsg('Currently under immunity.');
             $isUnderImmunity = true;
             $time_period = ($this->immunityExp - $this->serverTime);
             $days = 0;
             $hours = 0;
             $minutes = 0;
             $seconds = 0;

             $time_increments = array( 'Days' => 86400, 'Hours' => 3600, 'Minutes' => 60, 'Seconds' => 1 );

             ## will hold our values for ( day, minute, hour, seconds )
             $time_span = array();

             ## cycle through time_increments
             while( list( $key, $value ) = each( $time_increments )) {
                 $this_value = (int) ( $time_period / $value );
                 $time_period = ( $time_period % $value );

                 # save value
                 $time_span[$key] = $this_value;
             }				
             $this->SendMsg('Immunity expires in ' . $time_span['Days'] . "d:" . $time_span['Hours'] . "h:" . $time_span['Minutes'] . "m:" . $time_span['Seconds'] . "s");
        }
        return $isUnderImmunity;
	}
	
    // ==============================================================================
    function setOtherState($obj, $ref = null) // Added by p627
    {
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][0]['functionName'] = "WorldService.performAction";
        $amf->_bodys[0]->_value[1][0]['params'][0] = "setState";
        $amf->_bodys[0]->_value[1][0]['params'][1] = $obj;

        $amf->_bodys[0]->_value[1][0]['params'][2][0]['referenceItem'] = $ref;

        $amf->_bodys[0]->_value[1][0]['params'][1]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][1]);

        $amf->_bodys[0]->_value[1][0]['params'][2][0]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][2][0]);
        // print_r($amf->_bodys[0]->_value[1][0]['params']);
        // exit;
			
		//add this line to results that does not give dooberitems via AMF, but streak bonus can be collected.
		//$this->dooberItems +=2;
			
        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        return $this->SendRequest($result);
    }
		
    // ==============================================================================
    function setState($obj, $ref = null)
    {
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][0]['functionName'] = "WorldService.performAction";
        $amf->_bodys[0]->_value[1][0]['params'][0] = "setState";
        $amf->_bodys[0]->_value[1][0]['params'][1] = $obj;

        $amf->_bodys[0]->_value[1][0]['params'][2][0]['referenceItem'] = $ref;

        $amf->_bodys[0]->_value[1][0]['params'][1]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][1]);

        $amf->_bodys[0]->_value[1][0]['params'][2][0]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][2][0]);
        // print_r($amf->_bodys[0]->_value[1][0]['params']);
        // exit;
			
		//add this line to results that does not give dooberitems via AMF, but streak bonus can be collected.
		$this->dooberItems +=2;
			
        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        return $this->SendRequest($result);
    }
		
	//==============================================================================
	function streamPublish($feed) // Added by p627
	{
		$this->SendMsg('streamPublish' . $feed );

		$amf = new AMFObject("");
		$amf->_bodys[0] = new MessageBody();
		$amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

		$amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
		$amf->_bodys[0]->responseURI = '';
		$amf->_bodys[0]->_value[2] = 0;

		$amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
		$amf->_bodys[0]->_value[1][0]['params'][0] = $nuid;
		$amf->_bodys[0]->_value[1][0]['functionName'] = "UserService.streamPublish";
		$amf->_bodys[0]->_value[1][0]['params'][0] = $feed;
		$amf->_bodys[0]->_value[1][0]['params'][1] = (object) "";
		$amf->_bodys[0]->_value[1][0]['params'][2] = $this->uid; // me $this->uid

		$serializer = new AMFSerializer();
		$result = $serializer->serialize($amf);

		$x = $this->SendRequest($result);
		$this->Add2Report('Publish Requests');

		return $x;
	}
		
    // ==============================================================================
    function orig_streakBonus($i,$cnt) { // Added by p627
        $bonus = round((($this->level + 1) * 1.5 * 55)-1);
        $this->SendMsg('streakBonus '.$i .'/'.$cnt .': '. $bonus);

        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();;
        $amf->_bodys[0]->_value[1][0]['functionName'] = "UserService.streakBonus";
        $amf->_bodys[0]->_value[1][0]['params'][0]['amount'] = 9; //$bonus; //9;
        $amf->_bodys[0]->_value[1][0]['params'][0]['maxesReached'] = 1;
        $amf->_bodys[0]->_value[2] = 0;

        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        $x = $this->SendRequest($result);
        $this->Add2Report('streakBonus');
    }
	
    // ==============================================================================
    function streakBonusCheck() { // Added by p627

    $showDooberInLog = true;  // Make this false to have less log
    if($showDooberInLog && is_array($this->dooberItem))
    { foreach($this->dooberItem as $item => $amount)   { $this->Add2Report('Bonus: ' . $item); }
      $this->dooberItem = array();
    }
    // check if we can get streakBonus
     $streakBonus = $this->GetParamByName("steakbonus");
    // streak bonus is now controled via the settings plugin.
    // $streakBonus = 1; // 0 = Do not collect streakBonus (off, in case Z patch this again)
                         // 1 = collect streakBonus every time (default)
                         // 2 - 31 = configurable
                         // 32 = the normal amount to collect maximum bonus.
     if($streakBonus == 0 ) return;
     if($this->dooberItems > $streakBonus)
       {
         $this->streakBonus3();
         $this->dooberItems = 0;
       }
      return;
     }
	 
    // ==============================================================================
	function streakBonus3() { // Added by p627
		$bonus = round((($this->level + 1) * 1.5 * 55)-1);
        $this->SendMsg('streakBonus3: '. number_format($bonus) . ' coins');
        $this->dooberItem['coin'] += $bonus;
		
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();;
        $amf->_bodys[0]->_value[1][0]['functionName'] = "UserService.streakBonus";
        $amf->_bodys[0]->_value[1][0]['params'][0]['amount'] = $bonus; //900000;
        $amf->_bodys[0]->_value[1][0]['params'][0]['maxesReached'] = 10;
        $amf->_bodys[0]->_value[2] = 0;

        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        $x = $this->SendRequest($result);
        $this->Add2Report('streakBonus3');
    }
	
    // ==============================================================================
    function startImmunity($obj)
    {
        $this->SendMsg('Start Immunity ' . $obj['itemName'] . " position=" . $obj['position']);
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][0]['functionName'] = "PVPService.immunityStart";
        $amf->_bodys[0]->_value[1][0]['params'] = Array();
		
		//add this line to results that does not give dooberitems via AMF, but streak bonus can be collected.
		//$this->dooberItems +=2;
		
        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        $x = $this->SendRequest($result);
        $this->Add2Report('Start Immunity');
    }
	
    // ==============================================================================
    function GetItems($obj,$item2,$nums=1) // Added by p627
	{
		//$this->SendMsg('Get ('.$item2.') buildings success');
		
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;
        
        for ($i=0; $i<($nums/10); $i++)
        {
			$x=($nums/10)-$i;
			if ($x > 1) $x=1;
			for ($j=0; $j<($x*10); $j++)
            {
				$amf->_bodys[0]->_value[1][$j]['functionName'] = "WorldService.performAction";
				$amf->_bodys[0]->_value[1][$j]['sequence'] = $this->GetSequense();
				$amf->_bodys[0]->_value[1][$j]['params'][0] = "place";
			
				$amf->_bodys[0]->_value[1][$j]['params'][1] = $obj;
				$amf->_bodys[0]->_value[1][$j]['params'][1]['itemName'] = $item2;
				$amf->_bodys[0]->_value[1][$j]['params'][1]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][1]);
			
				$amf->_bodys[0]->_value[1][$j]['params'][2][0] = $obj;
				$amf->_bodys[0]->_value[1][$j]['params'][2][0]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][2][0]);
            }
			
			$serializer = new AMFSerializer();
			$result = $serializer->serialize($amf);
			$x = $this->SendRequest($result);
			
			if ($nums>10)
            {
				$this->SendMsg('Wait to load...');
				sleep(1);
            }
        }       
    }
	
    // ==============================================================================
  	function Action1($obj,$tmp_itemname,$tmp_id,$tmp_pos) // Added by p627
    {
		//$this->SendMsg("Set auto the right state in section");
		
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][0]['functionName'] = "WorldService.performAction";
        $amf->_bodys[0]->_value[1][0]['params'][0] = "setState";
        $amf->_bodys[0]->_value[1][0]['params'][1] = array();
		$amf->_bodys[0]->_value[1][0]['params'][1]['id'] = $tmp_id;
	    $amf->_bodys[0]->_value[1][0]['params'][1]['position'] = $tmp_pos;
		$amf->_bodys[0]->_value[1][0]['params'][1]['itemName'] = $tmp_itemname;
        $amf->_bodys[0]->_value[1][0]['params'][2][0]['referenceItem'] = Null;
		
		$amf->_bodys[0]->_value[1][0]['params'][1]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][1]);
		
		$amf->_bodys[0]->_value[1][0]['params'][2][0]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][2][0]);
			
		//add this line to results that does not give dooberitems via AMF, but streak bonus can be collected.
		//$this->dooberItems +=2;
			
        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        return $this->SendRequest($result);
    }

    // ==============================================================================
    function Action2($obj,$tmp_itemname,$tmp_id,$tmp_pos) // Added by p627
    {
		//$this->SendMsg("Set auto the right state in section");
		
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][0]['functionName'] = "WorldService.performAction";
        $amf->_bodys[0]->_value[1][0]['params'][0] = "setState";
        $amf->_bodys[0]->_value[1][0]['params'][1] = array();
		$amf->_bodys[0]->_value[1][0]['params'][1]['id'] = $tmp_id;
	    $amf->_bodys[0]->_value[1][0]['params'][1]['position'] = $tmp_pos;
		$amf->_bodys[0]->_value[1][0]['params'][1]['itemName'] = $tmp_itemname;
        $amf->_bodys[0]->_value[1][0]['params'][2][0]['referenceItem'] = Null;
		
		$amf->_bodys[0]->_value[1][0]['params'][1]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][1]);
		
		$amf->_bodys[0]->_value[1][0]['params'][2][0]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][2][0]);
			
		//add this line to results that does not give dooberitems via AMF, but streak bonus can be collected.
		$this->dooberItems +=2;
			
        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        return $this->SendRequest($result);
    } 
	
    // ==============================================================================
    function setCityName($name) // Added by p627
	{
        $this->SendMsg('SetCityName: '. $name );
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();;
        $amf->_bodys[0]->_value[1][0]['functionName'] = "UserService.setWorldName";
        $amf->_bodys[0]->_value[1][0]['params'][0] = $name;

        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        $x = $this->SendRequest($result);
		
        $this->Add2Report('setCityName');
    }
	
    // ==============================================================================
	function acceptInvHelpN($id) // Added by Amitb
	{
		unset($this->error_msg);
		$amf = new AMFObject("");
		$amf->_bodys[0] = new MessageBody();
		$amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

		$amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
		$amf->_bodys[0]->responseURI = '';
		$amf->_bodys[0]->_value[2] = 0;

		$amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
		$amf->_bodys[0]->_value[1][0]['functionName'] = "PVPService.acceptFriendRepel";
		$amf->_bodys[0]->_value[1][0]['stamp'] = (($this->serverTime)*1000);
		$amf->_bodys[0]->_value[1][0]['params'][0] = $id;

		$serializer = new AMFSerializer();
		$result = $serializer->serialize($amf);
		$x = $this->SendRequest($result);
	
		if(isset($this->error_msg))
		{
			// error
			$this->SendMsg("Defender Help failed. Accept Manually.");
		}
		else
		{
			$this->SendMsg("Defender Help accepted successfully.");
		}
	}

    // ==============================================================================
	function PillageNeighbor($neighbor) // Added by Amitb
	{
		unset($this->error_msg);
		$amf = new AMFObject("");
		$amf->_bodys[0] = new MessageBody();
		$amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

		$amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
		$amf->_bodys[0]->responseURI = '';
		$amf->_bodys[0]->_value[2] = 0;

		$amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
		$amf->_bodys[0]->_value[1][0]['functionName'] = "WorldService.loadWorld";
		$amf->_bodys[0]->_value[1][0]['params'][0] = $neighbor['uid'];
		$amf->_bodys[0]->_value[1][0]['params'][1] = "home";
		$amf->_bodys[0]->_value[1][0]['params'][2] = 1;
		$amf->_bodys[0]->_value[1][0]['params'][3]['dbg'] = 0;

		$serializer = new AMFSerializer();
		$result = $serializer->serialize($amf);
		$x = $this->SendRequest($result);

		if (isset($this->error_msg))
		{
			$this->SendMsg("LoadWorld failed for Invaded Neighbor: ".$neighbor['name']);
			return;
		}
		$this->SendMsg("LoadWorld success for Invaded Neighbor: ".$neighbor['name']);
		unset($amf);
	
		$amf = new AMFObject("");
		$amf->_bodys[0] = new MessageBody();
		$amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

		$amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
		$amf->_bodys[0]->responseURI = '';
		$amf->_bodys[0]->_value[2] = 0;
	
		$amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
		$amf->_bodys[0]->_value[1][0]['functionName'] = "PVPService.pillage";
		$amf->_bodys[0]->_value[1][0]['params'][0] = $neighbor['uid'];

		$serializer = new AMFSerializer();
		$result = $serializer->serialize($amf);
		$x = $this->SendRequest($result);

		if (isset($this->error_msg))
			$this->SendMsg("Collect loot failed from Invaded Neighbor: ".$neighbor['name']);
		else
			$this->SendMsg("Collected loot from Invaded Neighbor: ".$neighbor['name']);

		return;
	}
	
	// ==============================================================================
	function buy_item_2($hostid,$obj,$amount) // Added by kpd
	{
		unset($this->error_msg);
		$amf = new AMFObject("");
		$amf->_bodys[0] = new MessageBody();
		$amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

		$amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
		$amf->_bodys[0]->responseURI = '';
		$amf->_bodys[0]->_value[2] = 0;

		$amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
		$amf->_bodys[0]->_value[1][0]['functionName'] = "WorldService.performAction";

		$amf->_bodys[0]->_value[1][0]['params'][0] = "buy";
		$amf->_bodys[0]->_value[1][0]['params'][1] = array();
		$amf->_bodys[0]->_value[1][0]['params'][1]['id'] = $obj['id'];
		$amf->_bodys[0]->_value[1][0]['params'][1]['position'] = $obj['position'];
		$amf->_bodys[0]->_value[1][0]['params'][1]['itemName'] = $obj['itemName'];
		$amf->_bodys[0]->_value[1][0]['params'][1]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][1]);
		$amf->_bodys[0]->_value[1][0]['params'][2] = array();
		$amf->_bodys[0]->_value[1][0]['params'][2][0]['item'] = $obj['item'];
		$amf->_bodys[0]->_value[1][0]['params'][2][0]['units'] = $amount;
		$amf->_bodys[0]->_value[1][0]['params'][2][0]['hostId'] = $hostid;
		$amf->_bodys[0]->_value[1][0]['params'][2][0]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][2][0]);
		  
		$serializer = new AMFSerializer();
		$result = $serializer->serialize($amf);
		return $this->SendRequest($result);
	} 

    // ==============================================================================
    function SellObject($obj) // Added by p627
    {
		$this->SendMsg('Plugin Sell: .' . $obj['itemName']);
		
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][0]['functionName'] = "WorldService.performAction";
        $amf->_bodys[0]->_value[1][0]['params'][0] = "sell";
        $amf->_bodys[0]->_value[1][0]['params'][1] = $obj;
		$amf->_bodys[0]->_value[1][0]['params'][1]['id'] = $obj['id'];
		
        $amf->_bodys[0]->_value[1][0]['params'][1]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][1]);
		
		$amf->_bodys[0]->_value[1][0]['params'][2] = Array();
		//add this line to results that does not give dooberitems via AMF, but streak bonus can be collected.
		//$this->dooberItems +=2;
			
        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        return $this->SendRequest($result);
    }
	
	// ==============================================================================
    function list_market($neighid,$marketid,$marketpos) // Added by kpd
    {
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
		//$amf->_bodys[0]->_value[1][0]['transaction'] = Null;
        $amf->_bodys[0]->_value[1][0]['functionName'] = "WorldService.performAction";
        $amf->_bodys[0]->_value[1][0]['params'][0] = "list";
        $amf->_bodys[0]->_value[1][0]['params'][1] = array();
	    $amf->_bodys[0]->_value[1][0]['params'][1]['itemName'] = 'Market';
		$amf->_bodys[0]->_value[1][0]['params'][1]['id'] = $marketid;
		$amf->_bodys[0]->_value[1][0]['params'][1]['position'] = $marketpos;
		$amf->_bodys[0]->_value[1][0]['params'][1]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][1]);
		
		$amf->_bodys[0]->_value[1][0]['params'][2][0] = array();
		//$amf->_bodys[0]->_value[1][0]['params'][2]['all'] = true;
		$amf->_bodys[0]->_value[1][0]['params'][2][0]['hostId'] = $neighid;
		$amf->_bodys[0]->_value[1][0]['params'][2][0]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][2][0]);
		
        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        return $this->SendRequest($result);
    } 
	
	// ==============================================================================
    function buy_item($obj,$itemcode,$amount) // Added by kpd
    {
        unset($this->error_msg);
        $amf = new AMFObject("");
        $amf->_bodys[0] = new MessageBody();
        $amf->_bodys[0]->_value[0] = $this->GetAmfHeader();

        $amf->_bodys[0]->targetURI = 'BaseService.dispatchBatch';
        $amf->_bodys[0]->responseURI = '';
        $amf->_bodys[0]->_value[2] = 0;

        $amf->_bodys[0]->_value[1][0]['sequence'] = $this->GetSequense();
        $amf->_bodys[0]->_value[1][0]['functionName'] = "UserService.buyItem";

        $amf->_bodys[0]->_value[1][0]['params'][0] = array();
		$amf->_bodys[0]->_value[1][0]['params'][0]['code'] = $itemcode;
		$amf->_bodys[0]->_value[1][0]['params'][0]['amount'] = $amount;

		$amf->_bodys[0]->_value[1][0]['params'][0]['ch'] = $this->ch($amf->_bodys[0]->_value[1][0]['params'][0]);
        $serializer = new AMFSerializer();
        $result = $serializer->serialize($amf);
        return $this->SendRequest($result);
    } 
	
    // ==============================================================================
    function get_mil_info() { // Added by devi8 & p627
       
       $this->rep = Array();
       $gmi_build_types = array("Drydocks", "Barracks", "Hangar");      
             
             
       $this->SendMsg('Getting Military buildings information..');
       $gmi_count_found = 0;
       $gmi_count = 0;
       $res = $this->ld->GetSelect("select * from objects");
          foreach ($res as $val) {
             $v = (string)$val[1];
             $obj = unserialize(base64_decode($v));
             $this->rep["classes"][$obj['className']][$this->xmlsOb->GetFname($obj['itemName'])] ++;
             $x = ((int) strtok($obj['position'], ','));
             $y = ((int) strtok(','));
             
             if ($obj['className'] == 'Item') {
                
               foreach ($gmi_build_types as $gmi_building) {
               if (stristr($obj['itemName'], $gmi_building)) {   
               $this->SendMsg("Found: NAME: ".$obj['itemName']." ID: ".$obj['id']." POS: ".$obj['position']);
               $gmi_count_found++;        
               }
		   }            
       }
       $gmi_count++ ;
    }
	   $this->SendMsg("Found ".$gmi_count_found." Buildings matching criteria...");
    }

    // ==============================================================================
    function collectRent($obj)
    {
            $this->SendMsg('Collect rent from ' . $obj['itemName']);
            $x = $this->setState($obj);
            $this->Add2Report('Collect rent');
    }
		
    // ==============================================================================
    function clearWilderness($obj)
    {
            $this->SendMsg('Cut Tree ' . $obj['itemName'] . " position=" . $obj['position']);
            $x = $this->setState($obj);
            $this->Add2Report('Cut Tree');
    }
		
    // ==============================================================================
    function harvest($obj)
    {
            $this->SendMsg('harvest ' . $this->xmlsOb->GetFname($this->xmlsOb->GetNameByCode($obj['referenceItem'])) . ' from ' . $this->xmlsOb->GetFname($obj['itemName']) . ' id=' . $obj['id']);
            $x = $this->setState($obj);
			$this->Add2Report('Harvest ' . $this->xmlsOb->GetFname($this->xmlsOb->GetNameByCode($ref)));
    }
		
    // ==============================================================================
    function seed($obj, $ref)
    {
            $this->SendMsg('seed ' . $this->xmlsOb->GetFname($this->xmlsOb->GetNameByCode($ref)) . ' to ' . $this->xmlsOb->GetFname($obj['itemName']) . ' id=' . $obj['id']);
            $x = $this->setOtherState($obj, $ref);
            $this->Add2Report('Seed ' . $this->xmlsOb->GetFname($this->xmlsOb->GetNameByCode($ref)));
    }
		
    // ==============================================================================
    function ch($obj)
    {
		if (is_numeric($this->uid)){
			$userid = strval($this->uid);
			$total = $this->ch_from_object($obj) + $this->ch_from_object($userid) + ceil(($this->sequense)/2) - 1;
		}else{
			$total = $this->ch_from_object($obj) + $this->ch_from_object($this->uid) + ceil(($this->sequense)/2) - 1;
		}
		return $total;
	}
		
    // ==============================================================================
    function ch_from_object($obj)
    {
		$sum = 0;
		if ($obj) {
		
			if (is_string($obj)) {
				for ($i = 0; $i < strlen($obj); $i++) {
					$sum += ord($obj{$i}) + $i;
				}
			} else if (is_numeric($obj)) {
				$sum += floor($obj / 2);
			} else if (is_bool($obj)) {
				$sum += ($obj ? 16 : 9);
			} else {
				foreach ($obj as $subobj) {
					$sum += $this->ch_from_object($subobj);
				}
			}
		}
		return $sum;
	}
	
    // ==============================================================================
    function GetParamByName($name) { // Added by p627
        $fl = file('options.txt');
        foreach ($fl as $line) {
            if (strpos($line, $name) !== false) {
                $pos = strpos($line, '=');
                $val = trim(substr($line, $pos + 1, strlen($line)));
            }
        }
        return $val;
    }
		
    // ==============================================================================
    function SendRequest($data)
    {
		$response = $this->Request($data);
        $this->CheckServerError($response);
        return $response;
    }
		
    // ------------------------------------------------------------------------------
    function Disconnect()
    {
		fclose($this->s);
    }
		
    // ------------------------------------------------------------------------------
	function Connect() // Update by p627 for ERROR connection
	{
		$this->didnothing = 0;
		if ($this->GetParamByName("iProxyUse") == 1) 
		{
			$this->s = fsockopen($this->GetParamByName("sProxyHost"), $this->GetParamByName("iProxyPort"));
		} else {
			$this->s = fsockopen($this->headers["Host"], 80, $errNo, $errStr, 30);
		}
		$ctry = 0;
		if ($errNo > 0)
		{
			$this->SendMsg('=====================================');
			
			while (!$this->s && ($ctry < 3))
			{
				$this->SendMsg('ERROR: (' . $errNo . ') ' . $errStr);
				$ctry++;
				$this->SendMsg('Connection try #' . $ctry . ' ...');
				if ($this->GetParamByName("iProxyUse") == 1)
				{
					$this->s = fsockopen($this->GetParamByName("sProxyHost"), $this->GetParamByName("iProxyPort"));
				} else {
					$this->s = fsockopen($this->headers["Host"], 80, $errNo, $errStr, 30);
				}
			}
			if ($this->s)
			{
				$this->SendMsg('Connection estabilished again. Continuing work in progress...');
				$this->SendMsg('=====================================');
			}
		}

		if (!$this->s) 
		{
			$this->SendMsg("Error: Can't connect to game server");
			exit;
		}
	}
    // ------------------------------------------------------------------------------
    function fullread($sd, $len)
    {
		$ret = '';
		$read = 0;

		while ($read < $len && ($buf = fread($sd, $len - $read))) {
			$read += strlen($buf);
			$ret .= $buf;
        }

		return $ret;
    }
		
    // ------------------------------------------------------------------------------
    function Request($data) // Fix and update by p627
    {
		$this->Connect();
		if (strpos($this->url, 'http://') === false)
			$query = "POST http://" . $this->host . $this->url . " HTTP/1.1\r\n";
		else
            $query = "POST $this->url HTTP/1.1\r\n";

		if ($this->GetParamByName("iProxyUse") == 1) {
			$authorization = base64_encode(trim($this->GetParamByName("sProxyUser")) . ':' . trim($this->GetParamByName("sProxyPass")));
			$this->headers["Proxy-Authorization"] = "Basic $authorization";
		}

        foreach ($this->headers as $key => $value) {
			$query .= $key . ": " . $value . "\r\n";
		}

		$query .= "Content-Length: " . strlen($data) . "\r\n\r\n";
		$query .= $data;

		stream_set_blocking($this->s, 0);

		fwrite($this->s, $query);
		$answer = '';

		$max_tick = 500; // wait max 50 seconds for data before we repeat request
		$cur_tick = 0;
		$is_bad = false;

		while (!strlen($answer)) {
			$answer .= $this->fullread($this->s, 1024);

			if (!strlen($answer)) {
				usleep(100000);
				$cur_tick++;

				if ($cur_tick > $max_tick) {
					$is_bad = true;
					break;
                }
			}
		}

		if ($is_bad) {
			$this->Disconnect();
            $this->Connect();
			return $this->SendRequest($data);
		}

		if (strpos($answer, '404 Not Found') !== false) {
			$this->Disconnect();
            $this->Connect();
            $this->SendMsg("Repeat request -404-");
            return $this->SendRequest($data);
        }

        if (strripos($answer, '500 Internal Server Error') !== false) {
            $this->SendMsg("ERROR: Internal Server Error");
            $this->Disconnect();
            return 0;
        }

        if (strripos($answer, '502 Bad Gateway') !== false) {
            $this->SendMsg("ERROR: 502 Bad Gateway");
            return 0;
        }
			
		preg_match('/Content-length:[\s]([0-9]*)[\s]/si', $answer, $match);
        $pos = strpos($answer, "\r\n\r\n");
        if ($pos !== false) {
            $answer = substr($answer, $pos + 4, strlen($answer));
            $pos = strpos($answer, "\r\n");
            if ($pos !== false)
				$answer = substr($answer, $pos + 2, strlen($answer));
        } else
            $answer = null;

        while (!feof($this->s)) {
            $answer .= fgets($this->s, 128);
        }
        $this->Disconnect();

        return $answer;
    }
	
    // ==============================================================================
    function CheckServerError($resp) {
        $tmp = new AMFObject($resp);
        $deserializer = new AMFDeserializer($tmp->rawData);
        $deserializer->deserialize($tmp);
		
        if (isset($tmp->_bodys[0]->_value['data'][0]['data']['result'])) { // added by p627  (result  String  failure)
            if($tmp->_bodys[0]->_value['data'][0]['data']['result'] == "failure") {$this->error_msg = "Unknown error";}
            if($tmp->_bodys[0]->_value['data'][0]['data']['result'] == "batchFailure") {$this->error_msg = "Unknown batchFailure error";}
        }
        if (isset($tmp->_bodys[0]->_value['faultCode'])) { //added by p627 found by Altizar
            $this->error_msg = $tmp->_bodys[0]->_value['faultCode'];
        }
        if (isset($tmp->_bodys[0]->_value['data'][0]['errorData'])) {
            $this->error_msg = $tmp->_bodys[0]->_value['data'][0]['errorData'];
        }
        if (isset($tmp->_bodys[0]->_value['errorData'])) {
            $this->error_msg = $tmp->_bodys[0]->_value['errorData'];
        }

        if (isset($this->error_msg)) // Change by p627
		{
            $this->SendMsg('ERROR: ' . $this->error_msg);
            if (($this->error_msg == 'AMFPHP_RUNTIME_ERROR') || $this->error_msg == 'OOS' || ($this->error_msg == "User not found") || (strpos($this->error_msg, "There is a new version of the game released")!==false)) 
			{
				$this->SendMsg('The session expired, the bot will restart in 3 seconds');
                sleep(3);
                $this->RestartBot();
			}
        }
		
        if (isset($tmp->_bodys[0]->_value['zySig']['zySig'])) {
           if($this->zySig != $tmp->_bodys[0]->_value['zySig']['zySig'])
             {
                //$this->SendMsg("zySig2 updated ****** Added by p627 ******");
                $this->zySig2 = $tmp->_bodys[0]->_value['zySig']['zySig'];//OK;

                $file= 'tmp_dir/'.$this->uid.'_amf.bin';
                @$content = fread($fl, filesize($file));

                $content =  str_replace($this->zySig, $this->zySig2, $content);
                $this->zySig = $this->zySig2;
             }

        }
        // added by p627 for streak bonus.              Array
        $this->CheckDoober = true;
        if(is_array($tmp->_bodys[0]->_value['data'][0]['data']) && $this->CheckDoober)
        {
          if(isset($tmp->_bodys[0]->_value['data'][0]['data']['doobers']))
           { //We got a Reward.
             foreach($tmp->_bodys[0]->_value['data'][0]['data']['doobers'] as $doober)
               {
                 //$this->SendMsg('Doober2: ' . $doober[0] . ' = ' . $doober[1] . ' Total Doob:' . $this->dooberItems);
				 if($doober[0] == "gold")       { $this->dooberItems++;  $this->dooberItem[$doober[0]] += $doober[1]; }
				 if($doober[0] == "wood")       { $this->dooberItems++;  $this->dooberItem[$doober[1]] += 1;}
				 if($doober[0] == "oil")        { $this->dooberItems++;  $this->dooberItem[$doober[1]] += 1;}
				 if($doober[0] == "copper")     { $this->dooberItems++;  $this->dooberItem[$doober[1]] += 1;}
				 if($doober[0] == "aluminum")   { $this->dooberItems++;  $this->dooberItem[$doober[1]] += 1;}
                 if($doober[0] == "uranium")    { $this->dooberItems++;  $this->dooberItem[$doober[1]] += 1;}
				 if($doober[0] == "iron")       { $this->dooberItems++;  $this->dooberItem[$doober[1]] += 1;}
                 if($doober[0] == "xp")         { $this->dooberItems++;  $this->dooberItem[$doober[0]] += $doober[1]; }
               }
           }
        $this->streakBonusCheck();
        }// end CheckDoober

    }
	
    // ==============================================================================
    function RestartBot() { // Change by p627
		global $headers_file, $amfbin_file;
		if (file_exists($headers_file)) {
			unlink($headers_file);
		}
		if (file_exists($amfbin_file)) {
			unlink($amfbin_file);
		}
		if (file_exists('tmp_dir\CurrentRevision.txt')) {
			unlink('tmp_dir\CurrentRevision.txt');
		}
		SendApi('BotApi.RUNNOW');
		exit;
    }
	
    // ==============================================================================
    function GetSequense()
    {
		$this->sequense += 1;
		return $this->sequense;
    }
		
    // ==============================================================================
    function Add2Report($name)
    {
		if (!isset($this->error_msg)) {
			$this->statistics[$name][] = 1;
			$this->lastAction = $name;
        }
    }
	
    // ==============================================================================
    function DoWork() // Change all actions by p627
    {
		$this->DebugMsg=false;// Info of Hook for Debug..
        $this->SendMsg('DoWork');
			
		$this->Hook('DebugInfos'); // Added by p627
        $this->Hook('before_work'); 

        $this->ReloadConfig();
        $this->SendMsg('Begin saving user inventory to local db file');
        $this->ld->SaveInventory2db($this); // Added by p627
			
		// Use Energy From Inventory
		$this->Hook('FullEnergy');
		$this->Hook('EnergyFull');
			
		// Get Xp & Coins
		$this->Hook('GetCoins&Xp');
			
		// Get Many Items
        $this->Hook('GetItemsEA');
        $this->Hook('GetBuildingsEA');

		// Collect buildings
        $this->Hook('CollectRentB');
        $this->Hook('collect_industry');
			
		// Seed And Harvest
        $this->Hook('seed_crops');
        $this->Hook('harvest_crops');
			
		// Purchase Contracts
        $this->Hook('purchase_contracts');
			
		// Sell Items From City
        $this->Hook('SellItemsCity');
		
		$this->Hook('test_plugin');
		// Searching For Materials
        $this->Hook('search_materials');
		
		$this->Hook('itemhack_plugin');		
		// Building units
        $this->Hook('produce_units');
		
		// Building units
        $this->Hook('produce_units');
		 $this->Hook('produce_coins');

		$this->Hook('produce_coins', 'Produce');
		// function Produce
			
		// Buying Materials
        $this->Hook('buying_materials');

		// upgrade units
		$this->Hook('upgrade_plugin');
			
		// Neighbors Actions
		$this->Hook('help_neighbors');
		$this->Hook('NeighborsVisit');
			
		// Others Actions
        $this->Hook('other_work');
		$this->Hook('Industry_Act');
		$this->Hook('SetCityName');
			
        // Please do not spent any energy in this hook
        $this->Hook('after_work'); //GameInfo plugin
			
		$this->SendMsg(">Coins: ".number_format($this->gold)." Wood: ".number_format($this->wood)." Oil: ".number_format($this->oil)." Energy: $this->energy"); // Added by p627
			
        $this->ReloadConfig();
        $this->SendMsg('Begin saving user profile to local db file');
        $this->ld->SaveProfile2db($this);
        $this->SendMsg('End saving user profile to local db file');
        $this->Hook('download_images'); // Added by p627
			
    }
	
    // ==============================================================================
    function GetCurrentRevision()
    {
		if (file_exists("tmp_dir\CurrentRevision.txt")) {
			$fl = fopen('tmp_dir\CurrentRevision.txt', 'r');
			$currver = fread($fl, filesize("tmp_dir\CurrentRevision.txt"));
			fclose($fl);
            return $currver;
        } else {
			return false;
        }
    }
	
    // ==============================================================================
    function SetCurrentRevision($ver)
    {
		if (file_exists("tmp_dir\CurrentRevision.txt")) {
			unlink("tmp_dir\CurrentRevision.txt");
        }

        $fl = fopen('tmp_dir\CurrentRevision.txt', 'w');
		fwrite($fl, $ver);
        fclose($fl);
    }
		
    // ==============================================================================
    function UserInfo()
    {
		$this->SendMsg('');
        $this->SendMsg('Uid = ' . $this->zyUid);
        $this->SendMsg('Name = ' . $this->usern);
        $this->SendMsg('Level = ' . $this->level);
        $this->SendMsg('XP = ' . number_format($this->xp));
        $this->SendMsg('Cash = ' . $this->cash);
		$this->SendMsg('Coins= ' . number_format($this->gold)); // Added by p627
        $this->SendMsg('Energy = ' . $this->energy);
        $this->SendMsg('EnergyMax = ' . $this->energyMax);
        $this->SendMsg('Host = ' . $this->host);
        $this->SendMsg('x_flash_version = ' . $this->x_flash_version);

        $this->SendMsg('');
    }
	
    // ==============================================================================
	function SendMsg($msg)
	{
		if ($this->Time2Log<>1)
		{ 
			echo $msg . "\n"; 
		} 
		else 
		{ 
			echo date("H:i:s"). " " .$msg . "\n"; 
		}
	}
	
    // ==============================================================================
    function DownloadFile($url, $file_name)
    {
		$this->SendMsg('Downloading ' . $file_name);

		if ($this->GetParamByName("iProxyUse") == 1) {
			GetFile($url, "tmp_dir\\" . $file_name, 1, $this->GetParamByName("sProxyHost"), $this->GetParamByName("iProxyPort"), $this->GetParamByName("sProxyUser"), $this->GetParamByName("sProxyPass"));
		} else {
			GetFile($url, "tmp_dir\\" . $file_name, 0, '', '', '', '');
		}
    }
	
    // ==============================================================================
    function GetTrueXmlUrl($file_name)
    {
		$url_from = $this->assetspath . $this->flashRevision . "/" . $file_name;
		return $url_from;
    }
		
    // ==============================================================================
    function UpdateXML() { // update by p627
        $this->SendMsg('UpdateXML');
        if (strcmp($this->flashRevision, $this->GetCurrentRevision()) != 0) {
            $explicitType=$this->cfg->_value['data'][0]['data']['userInfo']['_explicitType'];
            $tmp=substr($explicitType, 17, strlen($explicitType));
            $tmp=strrev($tmp);
            $tmp=substr($tmp, 20, strlen($tmp));
            $tmp=strrev($tmp);
            $this->assetspath = 'http://empire.static.zgncdn.com/assets/'.$tmp;
			
            $this->DownloadFile($this->GetTrueXmlUrl('gameSettings.xml'), 'gameSettings.xml');
            $this->DownloadFile($this->GetTrueXmlUrl('en_US.xml'), 'en_US.xml');
            $this->DownloadFile($this->GetTrueXmlUrl('questSettings.xml'), 'questSettings.xml');
			$filename ='ZGame.'.$this->flashRevision.'.swf';
			$filelink = 'http://empire.static.zgncdn.com/assets/'.$this->flashRevision.'/ZGame.'.$this->flashRevision.'.swf';
			$this->DownloadFile($filelink, $filename);		// download SWF
			$new_url = "tmp_dir\gameSettings.".$this->flashRevision.'.xml';
			if (!file_exists($new_url)) {			// make copy of gameSettings
                copy('tmp_dir\gameSettings.xml', $new_url);    
            }
            if (file_exists('tmp_dir\fnames.txt')) {
                    unlink('tmp_dir\fnames.txt');
            }
			$this->SetCurrentRevision($this->flashRevision);
       }
       if (!file_exists('tmp_dir\gameSettings.xml')) {
               $this->SendMsg('Cannot find file gameSettings.xml');
               $this->SendMsg('Exit');
               exit;
       }
       $this->xmlsOb = new xmlsOb();
       $this->xmlsOb->GenerateData();
    }
		
	// ==============================================================================
	function nicetime($date)
	{
		if(empty($date)) 
		{
			return "No date provided";
		}
   
		$periods         = array("second", "minute", "hour", "day", "week", "month", "year", "decade");
		$lengths         = array("60","60","24","7","4.35","12","10");
   
		$now             = time();
//  	$unix_date       = strtotime($date);  // Do not provide real date, but unix timestamp
		$unix_date       = $date;
   
        // check validity of date
		if(empty($unix_date)) 
		{   
			return "Bad date";
		}

		// is it future date or past date
		if($now > $unix_date) 
		{   
			$difference    = $now - $unix_date;
			$tense         = "ago";
		} else {
			$difference    = $unix_date - $now;
			$tense         = "from now";
		}
   
		for($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) 
		{
			$difference /= $lengths[$j];
		}
   
		$difference = round($difference);
   
		if($difference != 1) 
		{
			$periods[$j].= "s";
		}
   
		return "$difference $periods[$j] {$tense}";
	
	}

	// ==========================================================================
	function SendMsgDebug($mess) // Added by p627
	{
		if (isset($this->DebugMsg) and $this->DebugMsg)
		$this->SendMsg($mess);
	}
}
  
?>