Пример #1
0
PyTuple *Character::GetSkillQueue() {
    // return skills from skill queue
    PyList *list = new PyList;

    SkillQueue::iterator cur, end;
    cur = m_skillQueue.begin();
    end = m_skillQueue.end();
    for(; cur != end; cur++)
    {
        SkillQueue_Element el;

        el.typeID = cur->typeID;
        el.level = cur->level;

        list->AddItem( el.Encode() );
    }

	// now encapsulate it in a tuple with the free points
	PyTuple *tuple = new PyTuple(2);
	tuple->SetItem(0, list);
	// sending 0, as done on retail, doesn't f**k up calculation for some reason
	// so we can take the same shortcut here
	tuple->SetItem(1, new PyInt(0));

    return tuple;
}
Пример #2
0
PyTuple* CRowSet::_CreateArgs()
{
	PyTuple* args = new PyTuple( 1 );
	args->SetItem( 0, new PyToken( "dbutil.CRowset" ) );

	return args;
}
Пример #3
0
PyRep* ClientSession::_GetCurrent( const char* name ) const
{
    PyTuple* v = _GetValueTuple( name );
    if( v == NULL )
        return NULL;
    return v->GetItem( 1 );
}
Пример #4
0
PyTuple* GPSTransportClosed::_CreateArgs( const char* reason )
{
    PyTuple* args = new PyTuple( 1 );
    args->SetItem( 0, new PyString( reason ) );

    return args;
}
Пример #5
0
PyTuple *DBResultToRowList(DBQueryResult &result, const char *type) {
    uint32 cc = result.ColumnCount();
    if(cc == 0)
        return(new PyTuple(0));
    uint32 r;

    PyTuple *res = new PyTuple(2);
    PyList *cols = new PyList(cc);
    PyList *reslist = new PyList();
    res->SetItem( 0, cols );
    res->SetItem( 1, reslist );

    //list off the column names:
    for(r = 0; r < cc; r++) {
        cols->SetItemString(r, result.ColumnName(r));
    }

    //add a line entry for each result row:
    DBResultRow row;
    while(result.GetRow(row)) {
        //this could be more efficient by not building the column list each time, but cloning it instead.
        PyObject *o = DBRowToRow(row, type);
        reslist->items.push_back(o);
    }

    return res;
}
Пример #6
0
PyTuple* UserError::_CreateArgs( const char* msg )
{
    PyTuple* args = new PyTuple( 2 );
    args->SetItem( 0, new PyString( msg ) );
    args->SetItem( 1, new PyDict );

    return args;
}
Пример #7
0
PyTuple* PasswordString::_CreateArgs( PyWString* password )
{
    PyTuple* head = new PyTuple( 2 );
    head->SetItem( 0, new PyToken( "util.PasswordString" ) );
    head->SetItem( 1, password );

    return head;
}
Пример #8
0
PyTuple* DBRowDescriptor::_CreateArgs()
{
	PyTuple* columnList = new PyTuple( 0 );

	PyTuple* args = new PyTuple( 1 );
	args->SetItem( 0, columnList );

	return args;
}
Пример #9
0
void HybridTurret::_ShowCycle()
{
	//m_Item->SetActive(true, effectProjectileFired, m_Item->GetAttribute(AttrSpeed).get_float(), true);

	// Create Destiny Updates:
	Notify_OnGodmaShipEffect shipEff;
	shipEff.itemID = m_Item->itemID();
	shipEff.effectID = effectProjectileFired;		// From EVEEffectID::
	shipEff.when = Win32TimeNow();
	shipEff.start = 1;
	shipEff.active = 1;

	PyList* env = new PyList;
	env->AddItem(new PyInt(shipEff.itemID));
	env->AddItem(new PyInt(m_Ship->ownerID()));
	env->AddItem(new PyInt(m_Ship->itemID()));
	env->AddItem(new PyInt(m_targetID));
	env->AddItem(new PyNone);
	env->AddItem(new PyNone);
	env->AddItem(new PyInt(shipEff.effectID));

	shipEff.environment = env;
	shipEff.startTime = shipEff.when;
	shipEff.duration = m_Item->GetAttribute(AttrSpeed).get_float();
	shipEff.repeat = new PyInt(1000);
	shipEff.randomSeed = new PyNone;
	shipEff.error = new PyNone;

	PyTuple* tmp = new PyTuple(3);
	//tmp->SetItem(1, dmgMsg.Encode());
	tmp->SetItem(2, shipEff.Encode());

	std::vector<PyTuple*> events;
	//events.push_back(dmgMsg.Encode());
	events.push_back(shipEff.Encode());

	std::vector<PyTuple*> updates;
	//updates.push_back(dmgChange.Encode());

	m_Ship->GetOperator()->GetDestiny()->SendDestinyUpdate(updates, events, false);

	// Create Special Effect:
	m_Ship->GetOperator()->GetDestiny()->SendSpecialEffect
	(
		m_Ship,
		m_Item->itemID(),
		m_Item->typeID(),
		m_targetID,
		m_chargeRef->typeID(),
		"effects.HybridFired",
		1,
		1,
		1,
		m_Item->GetAttribute(AttrSpeed).get_float(),
		1000
	);
}
Пример #10
0
void DBRowDescriptor::AddColumn( const char* name, DBTYPE type )
{
	PyTuple* col = new PyTuple( 2 );

	col->SetItem( 0, new PyString( name ) );
	col->SetItem( 1, new PyInt( type ) );

	_GetColumnList()->items.push_back( col );
}
Пример #11
0
PyTuple* ShipDB::GetFormations()
{
    //vicious crap... but this is gunna be a bit of work to load from the DB (nested tuples)
    PyTuple* res = new PyTuple( 2 );

    Beyonce_Formation f;

    //Diamond formation
    f.name = "Diamond";

    f.pos1.x = 100;
    f.pos1.y = 0;
    f.pos1.z = 0;

    f.pos2.x = 0;
    f.pos2.y = 100;
    f.pos2.z = 0;

    f.pos3.x = -100;
    f.pos3.y = 0;
    f.pos3.z = 0;

    f.pos4.x = 0;
    f.pos4.y = -100;
    f.pos4.z = 0;

    res->SetItem( 0, f.Encode() );

    //Arrow formation
    f.name = "Arrow";

    f.pos1.x = 100;
    f.pos1.y = 0;
    f.pos1.z = -50;

    f.pos2.x = 50;
    f.pos2.y = 0;
    f.pos2.z = 0;

    f.pos3.x = -100;
    f.pos3.y = 0;
    f.pos3.z = -50;

    f.pos4.x = -50;
    f.pos4.y = 0;
    f.pos4.z = 0;

    res->SetItem( 1, f.Encode() );

    return res;
}
Пример #12
0
void ClientSession::EncodeChanges( PyDict* into )
{
    PyDict::const_iterator cur, end;
    cur = mSession->begin();
    end = mSession->end();
    for(; cur != end; cur++)
    {
        PyString* str = cur->first->AsString();
        PyTuple* value = cur->second->AsTuple();

        PyRep* last = value->GetItem( 0 );
        PyRep* current = value->GetItem( 1 );

        if( last->hash() != current->hash() )
        {
            // Duplicate tuple
            PyTuple* t = new PyTuple( 2 );
            t->SetItem( 0, last ); PyIncRef( last );
            t->SetItem( 1, current ); PyIncRef( current );
            into->SetItem( str, t ); PyIncRef( str );

            // Update our tuple
            value->SetItem( 0, current ); PyIncRef( current );
        }
    }

	mDirty = false;
}
Пример #13
0
/* function not used */
PyTuple *DBResultToPackedRowListTuple( DBQueryResult &result )
{
    DBRowDescriptor * header = new DBRowDescriptor( result );

    size_t row_count = result.GetRowCount();
    PyList * list = new PyList( row_count );

    DBResultRow row;
    uint32 i = 0;
    while( result.GetRow(row) )
    {
        list->SetItem( i++, CreatePackedRow( row, header ) );
        PyIncRef( header );
    }

    PyTuple * root = new PyTuple(2);
    root->SetItem( 0, header );
    root->SetItem( 1, list );

    return root;
}
Пример #14
0
void ClientSession::_Set( const char* name, PyRep* value )
{
    PyTuple* v = _GetValueTuple( name );
    if( v == NULL )
    {
        v = new PyTuple( 2 );
        v->SetItem( 0, new PyNone );
        v->SetItem( 1, new PyNone );
        mSession->SetItemString( name, v );
    }

    PyRep* current = v->GetItem( 1 );
    if( value->hash() != current->hash() )
    {
        v->SetItem( 1, value );

        mDirty = true;
    }
    else
    {
        PyDecRef( value );
    }
}
Пример #15
0
// TODO: hangarGraphicID went missing. maybe no longer in the dump?
PyRep *StationDB::GetStationItemBits(uint32 sid) {
	DBQueryResult res;

	if(!sDatabase.RunQuery(res,
		" SELECT "
		" staStations.stationID, "
		" staStations.stationTypeID, staStations.corporationID AS ownerID, "
		" staStationTypes.hangarGraphicID, "
		// damn mysql returns the result of the sum as string and so it is sent to the client as string and so it freaks out...
		" CAST(SUM(staOperationServices.serviceID) as UNSIGNED INTEGER) AS serviceMask "
		" FROM staStations "
		" LEFT JOIN staStationTypes ON staStations.stationTypeID = staStationTypes.stationTypeID "
		" LEFT JOIN staOperationServices ON staStations.operationID = staOperationServices.operationID "
		" WHERE staStations.stationID = %u "
		" GROUP BY staStations.stationID ", sid
	))
	{
		_log(SERVICE__ERROR, "Error in GetStationItemBits query: %s", res.error.c_str());
		return NULL;
	}

	DBResultRow row;
	if(!res.GetRow(row)) {
		_log(SERVICE__ERROR, "Error in GetStationItemBits query: no station for id %d", sid);
		return NULL;
	}

	PyTuple * result = new PyTuple(5);
	result->SetItem(0, new PyInt(row.GetUInt(3)));
	result->SetItem(1, new PyInt(row.GetUInt(2)));
	result->SetItem(2, new PyInt(row.GetUInt(0)));
	result->SetItem(3, new PyInt(row.GetUInt(4)));
	result->SetItem(4, new PyInt(row.GetUInt(1)));

	return result;
}
Пример #16
0
bool AttributeMap::Add( uint32 attributeID, EvilNumber& num )
{
    mChanged = true;
    PyTuple* AttrChange = new PyTuple(7);
    AttrChange->SetItem(0, new PyString( "OnModuleAttributeChange" ));
    AttrChange->SetItem(1, new PyInt( mItem.ownerID() ));
    AttrChange->SetItem(2, new PyInt( mItem.itemID() ));
    AttrChange->SetItem(3, new PyInt( attributeID ));
    AttrChange->SetItem(4, new PyLong( Win32TimeNow() ));
    AttrChange->SetItem(5, num.GetPyObject());
    AttrChange->SetItem(6, num.GetPyObject());

    return SendAttributeChanges(AttrChange);
}
Пример #17
0
void MiningLaser::checkAsteroidDepleted(uint32 remainingOreUnits)
{
    if (remainingOreUnits == 0)
    {
        // Asteroid is empty now, so remove it
        m_targetEntity->Bubble()->Remove(m_targetEntity);
        m_targetEntity->Item()->Delete();
        // Send client asteroid depleted message.
        PyDict *dict = new PyDict();
        dict->SetItem(new PyString("asteroidname"), new PyString(""));
        PyTuple *tuple = new PyTuple(2);
        tuple->SetItem(0, new PyInt(MOD_ACTIVATED)); //???? what is this really?
        tuple->SetItem(1, new PyInt(m_item->typeID()));
        dict->SetItem(new PyString("modulename"), tuple);
        PyTuple *error = new PyTuple(2);
        error->SetItem(0, new PyString("MiningDronesDeactivatedAsteroidEmpty"));
        error->SetItem(1, dict);
        m_error = error;
    }
}
Пример #18
0
void SuperWeapon::_ShowCycle()
{
	std::string effectString;
	switch (m_Item->typeID())
	{
	case 24550:
		effectString = "effects.SuperWeaponAmarr";
		m_effectID = effectSuperWeaponAmarr;
		break;

	case 24552:
		effectString = "effects.SuperWeaponCaldari";
		m_effectID = effectSuperWeaponCaldari;
		break;

	case 24554:
		effectString = "effects.SuperWeaponGallente";
		m_effectID = effectSuperWeaponGallente;
		break;

	case 23674:
		effectString = "effects.SuperWeaponMinmatar";
		m_effectID = effectSuperWeaponMinmatar;
		break;

	default:
		effectString = "";
		m_effectID = 0;
		break;
	}

	// Create Destiny Updates:
	Notify_OnGodmaShipEffect shipEff;
	shipEff.itemID = m_Item->itemID();
	shipEff.effectID = m_effectID;		// From EVEEffectID::
	shipEff.when = Win32TimeNow();
	shipEff.start = 1;
	shipEff.active = 1;

	PyList* env = new PyList;
	env->AddItem(new PyInt(shipEff.itemID));
	env->AddItem(new PyInt(m_Ship->ownerID()));
	env->AddItem(new PyInt(m_Ship->itemID()));
	env->AddItem(new PyInt(m_targetID));
	env->AddItem(new PyNone);
	env->AddItem(new PyNone);
	env->AddItem(new PyInt(shipEff.effectID));

	shipEff.environment = env;
	shipEff.startTime = shipEff.when;
	shipEff.duration = m_Item->GetAttribute(AttrDuration).get_float();
	shipEff.repeat = new PyInt(1000);
	shipEff.randomSeed = new PyNone;
	shipEff.error = new PyNone;

	PyTuple* tmp = new PyTuple(3);
	//tmp->SetItem(1, dmgMsg.Encode());
	tmp->SetItem(2, shipEff.Encode());

	std::vector<PyTuple*> events;
	//events.push_back(dmgMsg.Encode());
	events.push_back(shipEff.Encode());

	std::vector<PyTuple*> updates;
	//updates.push_back(dmgChange.Encode());

	m_Ship->GetOperator()->GetDestiny()->SendDestinyUpdate(updates, events, false);

	// Create Special Effect:
	m_Ship->GetOperator()->GetDestiny()->SendSpecialEffect
		(
		m_Ship,
		m_Item->itemID(),
		m_Item->typeID(),
		m_targetID,
		0,
		effectString,
		1,
		1,
		1,
		m_Item->GetAttribute(AttrDuration).get_float(),
		1000
		);
}
Пример #19
0
void EnergyTurret::DoCycle()
{
	if( m_ActiveModuleProc->ShouldProcessActiveCycle() )
	{
		// Check to see if our target is still in this bubble or has left or been destroyed:
		if( !(m_Ship->GetOperator()->GetSystemEntity()->Bubble()->GetEntity(m_targetID)) )
		{
			// Target has left our bubble or been destroyed, deactivate this module:
			Deactivate();
			return;
		}

		// Create Destiny Updates:
		DoDestiny_OnDamageStateChange dmgChange;
		dmgChange.entityID = m_targetEntity->GetID();

		PyList *states = new PyList;
		states->AddItem(new PyFloat(0));
		states->AddItem(new PyFloat(0));
		states->AddItem(new PyFloat(0.99));
		dmgChange.state = states;

		Notify_OnDamageMessage dmgMsg;
		dmgMsg.messageID = "";		// Can be left blank as Damage.cpp fills this in.  This can be one in this set {"AttackHit1", "AttackHit2", "AttackHit3", "AttackHit4", "AttackHit5", "AttackHit6"}
		dmgMsg.weapon = m_Item->itemID();
		dmgMsg.splash = "";
		dmgMsg.target = m_targetEntity->GetID();
		dmgMsg.damage = (m_Item->GetAttribute(AttrDamageMultiplier).get_float() * 48.0);

		Notify_OnGodmaShipEffect shipEff;
		shipEff.itemID = m_Item->itemID();
		shipEff.effectID = effectTargetAttack;		// From EVEEffectID::
		shipEff.when = Win32TimeNow();
		shipEff.start = 1;
		shipEff.active = 1;

		PyList* env = new PyList;
		env->AddItem(new PyInt(shipEff.itemID));
		env->AddItem(new PyInt(m_Ship->ownerID()));
		env->AddItem(new PyInt(m_Ship->itemID()));
		env->AddItem(new PyInt(m_targetEntity->GetID()));
		env->AddItem(new PyNone);
		env->AddItem(new PyNone);
		env->AddItem(new PyInt(10));

		shipEff.environment = env;
		shipEff.startTime = shipEff.when;
		shipEff.duration = m_Item->GetAttribute(AttrSpeed).get_float();
		shipEff.repeat = new PyInt(1000);
		shipEff.randomSeed = new PyNone;
		shipEff.error = new PyNone;

		PyTuple* tmp = new PyTuple(3);
		tmp->SetItem(1, dmgMsg.Encode());
		tmp->SetItem(2, shipEff.Encode());

		std::vector<PyTuple*> events;
		events.push_back(dmgMsg.Encode());
		events.push_back(shipEff.Encode());

		std::vector<PyTuple*> updates;
		updates.push_back(dmgChange.Encode());

		m_Ship->GetOperator()->GetDestiny()->SendDestinyUpdate(updates, events, true);

		// Create Special Effect:
		m_Ship->GetOperator()->GetDestiny()->SendSpecialEffect
		(
			m_Ship,
			m_Item->itemID(),
			m_Item->typeID(),
			m_targetID,
			m_chargeRef->itemID(),
			"effects.Laser",
			1,
			1,
			m_Item->GetAttribute(AttrSpeed).get_float(),
			1
		);

		// Create Damage action:
		//Damage( SystemEntity *_source,
        //    InventoryItemRef _weapon,
        //    double _kinetic,
        //    double _thermal,
        //    double _em,
        //    double _explosive,
        //    EVEEffectID _effect );
		double kinetic_damage = 0.0;
		double thermal_damage = 0.0;
		double em_damage = 0.0;
		double explosive_damage = 0.0;

		// This still somehow needs skill, ship, module, and implant bonuses to be applied:
		// This still somehow needs to have optimal range and falloff attributes applied as a damage modification factor:
		if( m_chargeRef->HasAttribute(AttrKineticDamage) )
			kinetic_damage = (m_Item->GetAttribute(AttrDamageMultiplier) * m_chargeRef->GetAttribute(AttrKineticDamage)).get_float();
		if( m_chargeRef->HasAttribute(AttrThermalDamage) )
			thermal_damage = (m_Item->GetAttribute(AttrDamageMultiplier) * m_chargeRef->GetAttribute(AttrThermalDamage)).get_float();
		if( m_chargeRef->HasAttribute(AttrEmDamage) )
			em_damage = (m_Item->GetAttribute(AttrDamageMultiplier) * m_chargeRef->GetAttribute(AttrEmDamage)).get_float();
		if( m_chargeRef->HasAttribute(AttrExplosiveDamage) )
			explosive_damage = (m_Item->GetAttribute(AttrDamageMultiplier) * m_chargeRef->GetAttribute(AttrExplosiveDamage)).get_float();

		Damage damageDealt
		(
			m_Ship->GetOperator()->GetSystemEntity(),
			m_Item,
			kinetic_damage,			// kinetic damage
			thermal_damage,			// thermal damage
			em_damage,				// em damage
			explosive_damage,		// explosive damage
			effectTargetAttack		// from EVEEffectID::
		);
		
		m_targetEntity->ApplyDamage( damageDealt );
	}
}
Пример #20
0
void Afterburner::_ShowCycle()
{
	//m_Item->SetActive(true, 1253, m_Item->GetAttribute(AttrDuration).get_float(), true);

	double implantBonuses = 1.0;	// TODO: gather and accumulate all implant bonuses for MWDs/Afterburners
	double accelerationControlSkillLevel = 0.0;	// TODO: Figure out how to get access to skills list of character running this ship and get this value
	double boostSpeed = m_Ship->GetAttribute(AttrMaxVelocity).get_float() * (1.0 + (m_Item->GetAttribute(AttrSpeedFactor).get_float() / 100.0 * (1 + accelerationControlSkillLevel * 0.05) * (implantBonuses) * (m_Item->GetAttribute(AttrSpeedBoostFactor).get_float() / (m_Ship->GetAttribute(AttrMass).get_float()))));

	// Tell Destiny Manager about our new speed so it properly tracks ship movement:
	m_Ship->GetOperator()->GetDestiny()->SetMaxVelocity(boostSpeed);
	m_Ship->GetOperator()->GetDestiny()->SetSpeedFraction(1.0);

	DoDestiny_SetBallMass mass;
	mass.entityID = m_Ship->itemID();
	mass.mass = m_Ship->GetAttribute(AttrMass).get_float();

	DoDestiny_SetMaxSpeed speed;
	speed.entityID = m_Ship->itemID();
	speed.speedValue = boostSpeed;

	std::vector<PyTuple *> updates;
	updates.push_back(mass.Encode());
	updates.push_back(speed.Encode());

	//m_Ship->GetOperator()->GetDestiny()->SendDestinyUpdate(updates, false);

	// Create Destiny Updates:
	Notify_OnGodmaShipEffect shipEff;
	shipEff.itemID = m_Item->itemID();
	shipEff.effectID = 1254;		// From EVEEffectID::
	shipEff.when = Win32TimeNow();
	shipEff.start = 1;
	shipEff.active = 1;

	PyList* env = new PyList;
	env->AddItem(new PyInt(shipEff.itemID));
	env->AddItem(new PyInt(m_Ship->ownerID()));
	env->AddItem(new PyInt(m_Ship->itemID()));
	env->AddItem(new PyNone);
	env->AddItem(new PyNone);
	env->AddItem(new PyNone);
	env->AddItem(new PyInt(shipEff.effectID));

	shipEff.environment = env;
	shipEff.startTime = shipEff.when;
	shipEff.duration = m_Item->GetAttribute(AttrDuration).get_float();
	shipEff.repeat = new PyInt(1000);
	shipEff.randomSeed = new PyNone;
	shipEff.error = new PyNone;

	PyTuple* tmp = new PyTuple(3);
	//tmp->SetItem(1, dmgMsg.Encode());
	tmp->SetItem(2, shipEff.Encode());

	std::vector<PyTuple*> events;
	//events.push_back(dmgMsg.Encode());
	events.push_back(shipEff.Encode());

	//std::vector<PyTuple*> updates;
	//updates.push_back(dmgChange.Encode());

	m_Ship->GetOperator()->GetDestiny()->SendDestinyUpdate(updates, events, false);

	// Create Special Effect:
	m_Ship->GetOperator()->GetDestiny()->SendSpecialEffect
		(
		m_Ship,
		m_Item->itemID(),
		m_Item->typeID(),
		0,
		0,
		"effects.SpeedBoost",
		0,
		1,
		1,
		m_Item->GetAttribute(AttrDuration).get_float(),
		1000
		);
}
Пример #21
0
void MissileLauncher::_ShowCycle()
{
	// Create Destiny Updates:
	Notify_OnGodmaShipEffect shipEff;
	shipEff.itemID = m_Item->itemID();
	shipEff.effectID = effectMissileLaunching;		// From EVEEffectID::
	shipEff.when = Win32TimeNow();
	shipEff.start = 1;
	shipEff.active = 1;

	PyList* env = new PyList;
	env->AddItem(new PyInt(shipEff.itemID));
	env->AddItem(new PyInt(m_Ship->ownerID()));
	env->AddItem(new PyInt(m_Ship->itemID()));
	env->AddItem(new PyInt(m_targetID));
	env->AddItem(new PyNone);
	env->AddItem(new PyNone);
	env->AddItem(new PyInt(shipEff.effectID));

	shipEff.environment = env;
	shipEff.startTime = shipEff.when;
	shipEff.duration = m_Item->GetAttribute(AttrSpeed).get_float();
	shipEff.repeat = new PyInt(1000);
	shipEff.randomSeed = new PyNone;
	shipEff.error = new PyNone;

	PyTuple* tmp = new PyTuple(3);
	//tmp->SetItem(1, dmgMsg.Encode());
	tmp->SetItem(2, shipEff.Encode());

	std::vector<PyTuple*> events;
	//events.push_back(dmgMsg.Encode());
	events.push_back(shipEff.Encode());

	std::vector<PyTuple*> updates;
	//updates.push_back(dmgChange.Encode());

	m_Ship->GetOperator()->GetDestiny()->SendDestinyUpdate(updates, events, false);

	// Create Special Effect:
	m_Ship->GetOperator()->GetDestiny()->SendSpecialEffect
	(
		m_Ship,
		m_Item->itemID(),
		m_Item->typeID(),
		m_targetID,
		m_chargeRef->typeID(),
		"effects.MissileDeployment",
		1,
		1,
		1,
		m_Item->GetAttribute(AttrSpeed).get_float(),
		1000
	);

	// Actually Launch a missile, creating a new Destiny object for it, but we don't know how to do this yet...

	// TODO - RESEARCH
	// (packets sent by server upon missile launch)
	/*
	Packet #1
[PyObjectData Name: macho.Notification]
  [PyTuple 7 items]
    [PyInt 12]
    [PyObjectData Name: macho.MachoAddress]
      [PyTuple 4 items]
        [PyInt 1]
        [PyInt 790408]
        [PyNone]
        [PyNone]
    [PyObjectData Name: macho.MachoAddress]
      [PyTuple 4 items]
        [PyInt 4]
        [PyString "DoDestinyUpdate"]
        [PyList 0 items]
        [PyString "clientID"]
    [PyInt 5894042]
    [PyTuple 1 items]
      [PyTuple 2 items]
        [PyInt 0]
        [PySubStream 888 bytes]
          [PyTuple 2 items]
            [PyInt 0]
            [PyTuple 2 items]
              [PyInt 1]
              [PyTuple 3 items]
                [PyList 3 items]
                  [PyTuple 2 items]
                    [PyInt 62665]
                    [PyTuple 2 items]
                      [PyString "PackagedAction"]
                      [PySubStream 270 bytes]
                        [PyList 1 items]
                          [PyTuple 2 items]
                            [PyInt 62665]
                            [PyTuple 2 items]
                              [PyString "AddBalls2"]
                              [PyTuple 1 items]
                                [PyTuple 2 items]
                                  [PyString "??  ?+??Pl?|  ?C????8?B)??u3??As"?E??B     ??@ ????????7)a[?? ?E                          zD  ???"]
                                  [PyList 1 items]
                                    [PyDict 11 kvp]
                                      [PyString "itemID"]
                                      [PyIntegerVar missileEntityID]
                                      [PyString "typeID"]
                                      [PyInt 203]
                                      [PyString "name"]
                                      [PyString "Cruise Missile"]
                                      [PyString "sourceModuleID"]
                                      [PyIntegerVar moduleID]		- the missile launcher module
                                      [PyString "corpID"]
                                      [PyInt corpID]
                                      [PyString "allianceID"]
                                      [PyInt allianceID]
                                      [PyString "warFactionID"]
                                      [PyNone]						- would by PyInt with warFactionID
                                      [PyString "securityStatus"]
                                      [PyFloat 2.65811580082965]
                                      [PyString "ownerID"]
                                      [PyInt ownerID]				- this is probably characterID
                                      [PyString "numLaunchers"]
                                      [PyInt 1]
                                      [PyString "nameID"]
                                      [PyInt 63844]
                  [PyTuple 2 items]
                    [PyInt 62665]
                    [PyTuple 2 items]
                      [PyString "OnDamageStateChange"]
                      [PyTuple 2 items]
                        [PyIntegerVar xxxxxx]
                        [PyList 3 items]
                          [PyTuple 3 items]
                            [PyFloat 0.570742342960805]
                            [PyFloat 200000]
                            [PyIntegerVar xxxxxx]
                          [PyFloat 1]
                          [PyFloat 1]
                  [PyTuple 2 items]
                    [PyInt 62665]
                    [PyTuple 2 items]
                      [PyString "OnDamageStateChange"]
                      [PyTuple 2 items]
                        [PyIntegerVar xxxxxx]
                        [PyList 3 items]
                          [PyTuple 3 items]
                            [PyFloat 6.93745520230552E-06]
                            [PyFloat 425000]
                            [PyIntegerVar timeStamp]
                          [PyFloat 0.810598232437212]
                          [PyFloat 1]
                [PyBool True]
                [PyList 10 items]
                  [PyTuple 7 items]
                    [PyString "OnModuleAttributeChange"]
                    [PyInt xxxxxx]
                    [PyIntegerVar xxxxxx]
                    [PyInt 266]
                    [PyIntegerVar xxxxxx]
                    [PyFloat 3320.81907103188]
                    [PyFloat 3640.81907103188]
                  [PyTuple 7 items]
                    [PyString "OnModuleAttributeChange"]
                    [PyInt xxxxxx]
                    [PyIntegerVar xxxxxx]
                    [PyInt 18]
                    [PyIntegerVar timeStamp]
                    [PyFloat 4077.04701492647]
                    [PyList 4 items]
                      [PyFloat 4077.04701492647]
                      [PyIntegerVar timeStamp]
                      [PyFloat 104400]
                      [PyFloat 4860]
                  [PyTuple 5 items]
                    [PyString "OnEffectHit"]
                    [PyIntegerVar xxxxxx]
                    [PyInt 10]
                    [PyIntegerVar xxxxxx]
                    [PyFloat 42.3334296258933]
                  [PyList 3 items]
                    [PyString "OnDamageMessage"]
                    [PyString "AttackHit2"]
                    [PyDict 4 kvp]
                      [PyString "weapon"]
                      [PyInt 21638]
                      [PyString "splash"]
                      [PyString ""]
                      [PyString "target"]
                      [PyIntegerVar xxxxxx]
                      [PyString "damage"]
                      [PyFloat 42.3334296258933]
                  [PyTuple 5 items]
                    [PyString "OnEffectHit"]
                    [PyIntegerVar xxxxxx]
                    [PyInt 10]
                    [PyIntegerVar xxxxxx]
                    [PyFloat 59.3261381082436]
                  [PyList 3 items]
                    [PyString "OnDamageMessage"]
                    [PyString "AttackHit3"]
                    [PyDict 4 kvp]
                      [PyString "weapon"]
                      [PyInt 21638]
                      [PyString "splash"]
                      [PyString ""]
                      [PyString "target"]
                      [PyIntegerVar xxxxxx]
                      [PyString "damage"]
                      [PyFloat 59.3261381082436]
                  [PyTuple 5 items]
                    [PyString "OnEffectHit"]
                    [PyIntegerVar xxxxxx]
                    [PyInt 10]
                    [PyIntegerVar xxxxxx]
                    [PyFloat 69.8373107175934]
                  [PyList 3 items]
                    [PyString "OnDamageMessage"]
                    [PyString "AttackHit4"]
                    [PyDict 4 kvp]
                      [PyString "weapon"]
                      [PyInt 21638]
                      [PyString "splash"]
                      [PyString ""]
                      [PyString "target"]
                      [PyIntegerVar xxxxxx]
                      [PyString "damage"]
                      [PyFloat 69.8373107175934]
                  [PyTuple 7 items]
                    [PyString "OnModuleAttributeChange"]
                    [PyInt 649670823]
                    [PyTuple 3 items]
                      [PyIntegerVar xxxxxx]
                      [PyInt 31]
                      [PyInt 203]
                    [PyInt 805]
                    [PyIntegerVar timeStamp]
                    [PyInt 23]
                    [PyInt 24]
                  [PyTuple 12 items]
                    [PyString "OnGodmaShipEffect"]
                    [PyIntegerVar xxxxxx]
                    [PyInt 101]
                    [PyIntegerVar timeStamp]
                    [PyInt 1]
                    [PyInt 1]
                    [PyList 7 items]
                      [PyIntegerVar xxxxxx]
                      [PyIntegerVar xxxxxx]
                      [PyIntegerVar xxxxxx]
                      [PyIntegerVar xxxxxx]
                      [PyTuple 3 items]
                        [PyIntegerVar xxxxxx]
                        [PyInt 31]
                        [PyInt 203]
                      [PyList 0 items]
                      [PyInt 101]
                    [PyIntegerVar timeStamp]
                    [PyFloat 10454.4]
                    [PyInt 1000]
                    [PyNone]
                    [PyNone]
    [PyNone]
    [PyNone]


	Packet #2
		[PyObjectData Name: macho.Notification]
		  [PyTuple 7 items]
			[PyInt 12]
			[PyObjectData Name: macho.MachoAddress]
			  [PyTuple 4 items]
				[PyInt 1]
				[PyInt 790408]
				[PyNone]
				[PyNone]
			[PyObjectData Name: macho.MachoAddress]
			  [PyTuple 4 items]
				[PyInt 4]
				[PyString "DoDestinyUpdate"]
				[PyList 0 items]
				[PyString "clientID"]
			[PyInt 5894042]
			[PyTuple 1 items]
			  [PyTuple 2 items]
				[PyInt 0]
				[PySubStream 145 bytes]
				  [PyTuple 2 items]
					[PyInt 0]
					[PyTuple 2 items]
					  [PyInt 1]
					  [PyTuple 2 items]
						[PyList 2 items]
						  [PyTuple 2 items]
							[PyInt 62665]
							[PyTuple 2 items]
							  [PyString "OnSpecialFX"]
							  [PyTuple 14 items]
								[PyIntegerVar shipID]
								[PyIntegerVar moduleID]
								[PyInt 16519]
								[PyIntegerVar targetID]
								[PyInt 203]
								[PyList 0 items]
								[PyString "effects.MissileDeployment"]
								[PyBool True]
								[PyInt 1]
								[PyInt 1]
								[PyFloat 10454.4]
								[PyInt 1000]
								[PyIntegerVar timeStamp]
								[PyNone]
						  [PyTuple 2 items]
							[PyInt 62665]
							[PyTuple 2 items]
							  [PyString "LaunchMissile"]
							  [PyTuple 5 items]
								[PyIntegerVar missileEntityID]
								[PyIntegerVar targetID]
								[PyIntegerVar shipID]
								[PyInt 1]
								[PyInt 1]
						[PyBool False]
			[PyNone]
			[PyNone]
	*/
}
Пример #22
0
bool EVENotificationStream::Decode(const std::string &pkt_type, const std::string &notify_type, PyTuple *&in_payload) {
    PyTuple *payload = in_payload;   //consume
    in_payload = NULL;

    PySafeDecRef(args);
    args = NULL;

    if(pkt_type != "macho.Notification") {
        codelog(NET__PACKET_ERROR, "notification payload has unknown string type %s", pkt_type.c_str());
        PyDecRef(payload);
        return false;
    }

    //decode payload tuple
    if(payload->items.size() != 2) {
        codelog(NET__PACKET_ERROR, "invalid tuple length %lu", payload->items.size());
        PyDecRef(payload);
        return false;
    }
    if(!payload->items[0]->IsTuple()) {
        codelog(NET__PACKET_ERROR, "non-tuple payload[0]");
        PyDecRef(payload);
        return false;
    }
    PyTuple *payload2 = (PyTuple *) payload->items[0];
    if(payload2->items.size() != 2) {
        codelog(NET__PACKET_ERROR, "invalid tuple2 length %lu", payload2->items.size());
        PyDecRef(payload);
        return false;
    }

    //decode inner payload tuple
    //ignore tuple 0, it should be an int, dont know what it is
    if(!payload2->items[1]->IsSubStream()) {
        codelog(NET__PACKET_ERROR, "non-substream type");
        PyDecRef(payload);
        return false;
    }
    PySubStream *ss = (PySubStream *) payload2->items[1];

    ss->DecodeData();
    if(ss->decoded() == NULL) {
        codelog(NET__PACKET_ERROR, "Unable to decode call stream");
        PyDecRef(payload);
        return false;
    }

    if(!ss->decoded()->IsTuple()) {
        codelog(NET__PACKET_ERROR, "packet body does not contain a tuple");
        PyDecRef(payload);
        return false;
    }

    PyTuple *robjt = (PyTuple *) ss->decoded();
    if(robjt->items.size() != 2) {
        codelog(NET__PACKET_ERROR, "packet body has %lu elements, expected %d", robjt->items.size(), 2);
        PyDecRef(payload);
        return false;
    }

    //parse first tuple element, remote object
    if(robjt->items[0]->IsInt()) {
        PyInt *tuple0 = (PyInt *) robjt->items[0];
        remoteObject = tuple0->value();
        remoteObjectStr = "";
    } else if(robjt->items[0]->IsString()) {
        PyString *tuple0 = (PyString *) robjt->items[0];
        remoteObject = 0;
        remoteObjectStr = tuple0->content();
    } else {
        codelog(NET__PACKET_ERROR, "main tuple[0] has invalid type %s", robjt->items[0]->TypeString());
        _log(NET__PACKET_ERROR, " in:");
        payload->Dump( NET__PACKET_ERROR, "" );
        PyDecRef(payload);
        return false;
    }

    if(!robjt->items[1]->IsTuple()) {
        codelog(NET__PACKET_ERROR, "main tuple[1] has non-tuple type %s", robjt->items[0]->TypeString());
        _log(NET__PACKET_ERROR, " it is:");
        payload->Dump( NET__PACKET_ERROR, "" );
        PyDecRef(payload);
        return false;
    }



    PyTuple *subt = (PyTuple *) robjt->items[1];
    if(subt->items.size() != 2) {
        codelog(NET__PACKET_ERROR, "packet body has %lu elements, expected %d", subt->items.size(), 2);
        PyDecRef(payload);
        return false;
    }

    //parse first tuple element, remote object
    if(subt->items[0]->IsInt()) {
        //PyInt *tuple0 = (PyInt *) maint->items[0];
        //no idea what this is.
    } else {
        codelog(NET__PACKET_ERROR, "sub tuple[0] has invalid type %s", subt->items[0]->TypeString());
        _log(NET__PACKET_ERROR, " in:");
        payload->Dump( NET__PACKET_ERROR, "" );
        PyDecRef(payload);
        return false;
    }



    if(!subt->items[1]->IsTuple()) {
        codelog(NET__PACKET_ERROR, "subt tuple[1] has non-tuple type %s", robjt->items[0]->TypeString());
        _log(NET__PACKET_ERROR, " it is:");
        payload->Dump( NET__PACKET_ERROR, "" );
        PyDecRef(payload);
        return false;
    }

    args = (PyTuple *) subt->items[1];
    subt->items[1] = NULL;

    notifyType = notify_type;

    PyDecRef(payload);
    return true;
}
Пример #23
0
bool PyCallStream::Decode(const std::string &type, PyTuple *&in_payload) {
    PyTuple *payload = in_payload;   //consume
    in_payload = NULL;

    PySafeDecRef(arg_tuple);
    PySafeDecRef(arg_dict);
    arg_tuple = NULL;
    arg_dict = NULL;

    if(type != "macho.CallReq") {
        codelog(NET__PACKET_ERROR, "failed: packet payload has unknown string type '%s'", type.c_str());
        PyDecRef(payload);
        return false;
    }

    if (payload->items.size() != 1) {
        codelog(NET__PACKET_ERROR, "invalid tuple length %lu", payload->items.size());
        PyDecRef(payload);
        return false;
    }
    if (!payload->items[0]->IsTuple()) {
        codelog(NET__PACKET_ERROR, "non tuple payload[0]");
        PyDecRef(payload);
        return false;
    }

    PyTuple *payload2 = (PyTuple *) payload->items[0];
    if(payload2->items.size() != 2) {
        codelog(NET__PACKET_ERROR, "invalid tuple2 length %lu", payload2->items.size());
        PyDecRef(payload);
        return false;
    }

    //decode inner payload tuple
    //ignore tuple 0, it should be an int, dont know what it is
    if(!payload2->items[1]->IsSubStream()) {
        codelog(NET__PACKET_ERROR, "non-substream type");
        PyDecRef(payload);
        return false;
    }
    PySubStream *ss = (PySubStream *) payload2->items[1];

    ss->DecodeData();
    if(ss->decoded() == NULL) {
        codelog(NET__PACKET_ERROR, "Unable to decode call stream");
        PyDecRef(payload);
        return false;
    }

    if(!ss->decoded()->IsTuple()) {
        codelog(NET__PACKET_ERROR, "packet body does not contain a tuple");
        PyDecRef(payload);
        return false;
    }

    PyTuple *maint = (PyTuple *) ss->decoded();
    if(maint->items.size() != 4) {
        codelog(NET__PACKET_ERROR, "packet body has %lu elements, expected %d", maint->items.size(), 4);
        PyDecRef(payload);
        return false;
    }

    //parse first tuple element, unknown
    if(maint->items[0]->IsInt()) {
        PyInt *tuple0 = (PyInt *) maint->items[0];
        remoteObject = tuple0->value();
        remoteObjectStr = "";
    } else if(maint->items[0]->IsString()) {
        PyString *tuple0 = (PyString *) maint->items[0];
        remoteObject = 0;
        remoteObjectStr = tuple0->content();
    } else {
        codelog(NET__PACKET_ERROR, "tuple[0] has invalid type %s", maint->items[0]->TypeString());
        codelog(NET__PACKET_ERROR, " in:");
        payload->Dump(NET__PACKET_ERROR, "    ");
        PyDecRef(payload);
        return false;
    }

    //parse tuple[1]: method name
    if(maint->items[1]->IsString()) {
        PyString *i = (PyString *) maint->items[1];
        method = i->content();
    } else {
        codelog(NET__PACKET_ERROR, "tuple[1] has non-string type");
        maint->items[1]->Dump(NET__PACKET_ERROR, " --> ");
        codelog(NET__PACKET_ERROR, " in:");
        payload->Dump(NET__PACKET_ERROR, "    ");
        PyDecRef(payload);
        return false;
    }

    //grab argument list.
    if(!maint->items[2]->IsTuple()) {
        codelog(NET__PACKET_ERROR, "argument list has non-tuple type");
        maint->items[2]->Dump(NET__PACKET_ERROR, " --> ");
        codelog(NET__PACKET_ERROR, "in:");
        payload->Dump(NET__PACKET_ERROR, "    ");
        PyDecRef(payload);
        return false;
    }
    arg_tuple = (PyTuple *) maint->items[2];
    maint->items[2] = NULL; //we keep this one

    //options dict
    if(maint->items[3]->IsNone()) {
        arg_dict = NULL;
    } else if(maint->items[3]->IsDict()) {
        arg_dict = (PyDict *) maint->items[3];
        maint->items[3] = NULL; //we keep this too.
    } else {
        codelog(NET__PACKET_ERROR, "tuple[3] has non-dict type");
        maint->items[3]->Dump(NET__PACKET_ERROR, " --> ");
        codelog(NET__PACKET_ERROR, "in:");
        payload->Dump(NET__PACKET_ERROR, "    ");
        PyDecRef(payload);
        return false;
    }

    PyDecRef(payload);
    return true;
}
Пример #24
0
bool PyAddress::Decode(PyRep *&in_object) {
    PyRep *base = in_object;
    in_object = NULL;

    if(!base->IsObject()) {
        codelog(NET__PACKET_ERROR, "Invalid element type, expected object");
        PyDecRef(base);
        return false;
    }

    PyObject *obj = (PyObject *) base;
    //do we care about the object type? should be "macho.MachoAddress"

    if(!obj->arguments()->IsTuple()) {
        codelog(NET__PACKET_ERROR, "Invalid argument type, expected tuple");
        PyDecRef(base);
        return false;
    }

    PyTuple *args = (PyTuple *) obj->arguments();
    if(args->items.size() < 3) {
        codelog(NET__PACKET_ERROR, "Not enough elements in address tuple: %lu", args->items.size());
        args->Dump(NET__PACKET_ERROR, "  ");
        PyDecRef(base);
        return false;
    }

    //decode the address type.
    if(!args->items[0]->IsInt()) {
        codelog(NET__PACKET_ERROR, "Wrong type on address type element (0)");
        args->items[0]->Dump(NET__PACKET_ERROR, "  ");
        PyDecRef(base);
        return false;
    }
    PyInt *typei = (PyInt *) args->items[0];
    switch(typei->value()) {
    case Any: {
        if(args->items.size() != 3) {
            codelog(NET__PACKET_ERROR, "Invalid number of elements in Any address tuple: %lu", args->items.size());
            PyDecRef(base);
            return false;
        }
        type = Any;

        if(!_DecodeService(args->items[1])
        || !_DecodeCallID(args->items[2])) {
            PyDecRef(base);
            return false;
        }

        break;
    }
    case Node: {
        if(args->items.size() != 4) {
            codelog(NET__PACKET_ERROR, "Invalid number of elements in Node address tuple: %lu", args->items.size());
            PyDecRef(base);
            return false;
        }
        type = Node;

        if(!_DecodeTypeID(args->items[1])
        || !_DecodeService(args->items[2])
        || !_DecodeCallID(args->items[3])) {
            PyDecRef(base);
            return false;
        }
        break;
    }
    case Client: {
        if(args->items.size() != 4) {
            codelog(NET__PACKET_ERROR, "Invalid number of elements in Client address tuple: %lu", args->items.size());
            PyDecRef(base);
            return false;
        }
        type = Client;

        if(!_DecodeTypeID(args->items[1])
        || !_DecodeCallID(args->items[2])
        || !_DecodeService(args->items[3])) {
            PyDecRef(base);
            return false;
        }

        break;
    }
    case Broadcast: {
        if(args->items.size() != 4) {
            codelog(NET__PACKET_ERROR, "Invalid number of elements in Broadcast address tuple: %lu", args->items.size());
            PyDecRef(base);
            return false;
        }
        type = Broadcast;

        if(!args->items[1]->IsString()) {
            codelog(NET__PACKET_ERROR, "Invalid type %s for brodcastID", args->items[1]->TypeString());
            PyDecRef(base);
            return false;
        } else if(!args->items[3]->IsString()) {
            codelog(NET__PACKET_ERROR, "Invalid type %s for idtype", args->items[3]->TypeString());
            PyDecRef(base);
            return false;
        }

        PyString *bid = (PyString *) args->items[1];
        PyString *idt = (PyString *) args->items[3];

        service = bid->content();
        bcast_idtype = idt->content();

        //items[2] is either a list or a tuple.
        /*
        //PyList *nclist = (PyList *) args->items[2];
        if(!nclist->items.empty()) {
            printf("Not decoding narrowcast list:");
            nclist->Dump(NET__PACKET_ERROR, "     ");
        }*/

        break;
    }
    default:
        codelog(NET__PACKET_ERROR, "Unknown address type: %c", typei->value() );
        PyDecRef(base);
        return false;
    }

    PyDecRef(base);
    return true;
}
Пример #25
0
void EnergyTurret::Activate(uint32 targetID)
{

	DoDestiny_OnDamageStateChange dmgChange;
	dmgChange.entityID = targetID;

	PyList *states = new PyList;
	states->AddItem(new PyFloat(0));
	states->AddItem(new PyFloat(0));
	states->AddItem(new PyFloat(0.99));
	dmgChange.state = states;

	m_Ship->SetAttribute(AttrCharge, 139);
	
	Notify_OnEffectHit effHit;
	effHit.itemID = m_Item->itemID();
	effHit.effectID = 10;
	effHit.targetID = targetID;
	effHit.damage = 5;

	Notify_OnDamageMessage dmgMsg;
	dmgMsg.messageID = "AttackHit3";
	dmgMsg.weapon = 3634;
	dmgMsg.splash = "";
	dmgMsg.target = targetID;
	dmgMsg.damage = 5;

	Notify_OnGodmaShipEffect shipEff;
	shipEff.itemID = m_Item->itemID();
	shipEff.effectID = 10;
	shipEff.when = Win32TimeNow();
	shipEff.start = 1;
	shipEff.active = 1;

	PyList* env = new PyList;
	env->AddItem(new PyInt(shipEff.itemID));
	env->AddItem(new PyInt(m_Ship->ownerID()));
	env->AddItem(new PyInt(m_Ship->itemID()));
	env->AddItem(new PyInt(targetID));
	env->AddItem(new PyNone);
	env->AddItem(new PyNone);
	env->AddItem(new PyInt(10));

	shipEff.environment = env;
	shipEff.startTime = shipEff.when;
	shipEff.duration = 1584;
	shipEff.repeat = new PyInt(1000);
	shipEff.randomSeed = new PyNone;
	shipEff.error = new PyNone;

	PyTuple* tmp = new PyTuple(3);
	tmp->SetItem(0, effHit.Encode());
	tmp->SetItem(1, dmgMsg.Encode());
	tmp->SetItem(2, shipEff.Encode());

	std::vector<PyTuple*> events;
	events.push_back(effHit.Encode());
	events.push_back(dmgMsg.Encode());
	events.push_back(shipEff.Encode());

	std::vector<PyTuple*> updates;
	updates.push_back(dmgChange.Encode());

	m_Ship->GetOperator()->GetDestiny()->SendDestinyUpdate(updates, events, true);
}
Пример #26
0
bool MiningLaser::endCycle(bool continuing)
{
    // Check to see if our target is still in this bubble or has left or been destroyed:
    if( m_ship->GetOperator()->GetSystemEntity()->Bubble()->GetEntity(m_targetID) == nullptr )
    {
        // Target has left our bubble or been destroyed, deactivate this module:
        return false;
    }
    if (m_ship->GetOperator()->GetSystemEntity()->targets.getTarget(m_targetID, true) == nullptr)
    {
        // Target no longer targeted.
        return false;
    }
    // Check range
    double maxRange = m_item->GetAttribute(AttrMaxRange).get_float();
    double targetRange = m_targetEntity->DistanceTo2(m_ship->GetOperator()->GetSystemEntity());
    targetRange = std::sqrt(targetRange);
    targetRange -= m_targetEntity->GetRadius();
    if (targetRange > maxRange)
    {
        // We must have drifted out of range.
        // TO-DO: send proper out or range response.
        SysLog::Error("MiningLaser::Activate()", "ERROR: mining laser target moved out of range!");
        return false;
    }
    // Retrieve ore from target Asteroid and put into flagCargoHold
    InventoryItemRef asteroidRef = m_targetEntity->Item();
	uint32 remainingOreUnits = asteroidRef->GetAttribute(AttrQuantity).get_int();
	double oreUnitVolume = asteroidRef->GetAttribute(AttrVolume).get_float();

    // Calculate how many units of ore to pull from the asteroid on this cycle:
    // Get base mining amount.
    double oreUnitsToPull = m_item->GetAttribute(AttrMiningAmount).get_float() / oreUnitVolume;
    // Do we have a crystal?
	if( m_chargeRef )
    {
        // Yes, apply yield multiplier.
        if (m_chargeRef->HasAttribute(AttrSpecialisationAsteroidYieldMultiplier))
        {
            // TO-DO: check for correct type of crystal.
            oreUnitsToPull *= m_chargeRef->GetAttribute(AttrSpecialisationAsteroidYieldMultiplier).get_float();
        }
        // TO-DO: do crystal damage.
    }
    // Get percent cycle complete.
    double cycleTime = getTotalCycleTimeMS();
    double percent = 1.0; // Assume full cycle if timer disabled.
    if(cycleTime != -1)
    {
        double usedTime = getElapsedCycleTimeMS();
        percent = usedTime / cycleTime;
        // Limit to range 0.0 - 1.0.
        percent = std::min(1.0, std::max(0.0, percent));
        if(percent == 0.0)
        {
            percent = 1.0;
        }
    }
    // Round down to next lowest integer value.
    oreUnitsToPull = floor(oreUnitsToPull * percent);

    // Limit to units remaining in asteroid.
    oreUnitsToPull = std::min(oreUnitsToPull, (double) remainingOreUnits);

    // Find what cargo hold to use.
    EVEItemFlags cargoFlag = flagCargoHold;
    // Check for specialized cargo hold.
    if (m_ship->HasAttribute(AttrSpecialOreHoldCapacity))
    {
        // We have a specialized ore hold all or goes here.
        cargoFlag = flagSpecializedOreHold;
    }
    // Get cargo hold and remaining capacity.
    double remainingCargoVolume = m_ship->GetRemainingVolumeByFlag(cargoFlag);
    // Do we have enough room for the whole stack?
    if (remainingCargoVolume < (floor((oreUnitsToPull * oreUnitVolume) * 100.0)/100.0))
    {
        // No, Do we have room for at least one unit?
        if (remainingCargoVolume < oreUnitVolume)
        {
            // No, Send cargo full message.
            PyDict *dict = new PyDict();
            PyTuple *tuple = new PyTuple(2);
            tuple->SetItem(0, new PyInt(MOD_ACTIVATED)); //???? what is this really?
            tuple->SetItem(1, new PyInt(m_item->typeID()));
            dict->SetItem(new PyString("modulename"), tuple);
            PyTuple *error = new PyTuple(2);
            error->SetItem(0, new PyString("MiningDronesDeactivatedCargoHoldNowFull"));
            error->SetItem(1, dict);
            m_error = error;
            return false;
        }
        // Yes, reduce the stack size.
        oreUnitsToPull = floor(remainingCargoVolume / oreUnitVolume);
    }
    // Are we actually pulling anything?
    if (oreUnitsToPull <= 0.0)
    {
        // No, hmmm... thats bad!
        // TO-DO: send client miner deactivated because hold full message.
        SysLog::Warning("MiningLaser::DoCycle()", "Somehow MiningLaser could not extract ore from current target asteroid '%s' (id %u)", m_targetEntity->Item()->itemName().c_str(), m_targetEntity->GetID());
        checkAsteroidDepleted(remainingOreUnits);
        return false;
    }

    // Check for an existing ore item in the cargo.
    InventoryItemRef existing = m_ship->GetByTypeFlag(asteroidRef->typeID(), cargoFlag);
    if (existing.get() != nullptr)
    {
        // We have an existing ore sample, add to it.
        m_ship->AlterCargoQty(existing, oreUnitsToPull);
    }
    else
    {
        // No existing ore sample, create one.
        ItemData idata(
                       asteroidRef->typeID(),
                       m_ship->ownerID(),
                       0, //temp location
                       cargoFlag,
                       oreUnitsToPull
                       );

        InventoryItemRef ore = ItemFactory::SpawnItem(idata);
        if (ore)
        {
            m_ship->AddItem(cargoFlag, ore);
        }
        else
        {
            SysLog::Error("MiningLaser::DoCycle()", "ERROR: Could not create ore stack for '%s' ship (id %u)!", m_ship->itemName().c_str(), m_ship->itemID());
            return false;
        }
    }
    // Finally, reduce the amount of ore in the asteroid by how much we took out:
    remainingOreUnits -= oreUnitsToPull;
    asteroidRef->SetAttribute(AttrQuantity, remainingOreUnits);

    // Check to see is ship is full or asteroid depleted.
    remainingCargoVolume = m_ship->GetRemainingVolumeByFlag(cargoFlag);
    if ((remainingCargoVolume < oreUnitVolume) || remainingOreUnits == 0)
    {
        // Asteroid is empty OR cargo hold is entirely full, either way, DEACTIVATE module immediately!
        checkAsteroidDepleted(remainingOreUnits);
        return false;
    }
    return true;
}