// deleting the auto pointer deletes what the internal pointer points to...
CMclKernelAutoPtr::~CMclKernelAutoPtr() {
    // no check needed since deleting a NULL
    // pointer is okay in C++...
    safe_delete( m_pObjectPtr ); 
}
Beispiel #2
0
//if itemlist is null, just send wear changes
void NPC::AddLootDrop(const EQEmu::ItemBase *item2, ItemList* itemlist, int16 charges, uint8 minlevel, uint8 maxlevel, bool equipit, bool wearchange) {
	if(item2 == nullptr)
		return;

	//make sure we are doing something...
	if(!itemlist && !wearchange)
		return;

	auto item = new ServerLootItem_Struct;
#if EQDEBUG>=11
		Log.Out(Logs::General, Logs::None, "Adding drop to npc: %s, Item: %i", GetName(), item2->ID);
#endif

	EQApplicationPacket* outapp = nullptr;
	WearChange_Struct* wc = nullptr;
	if(wearchange) {
		outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct));
		wc = (WearChange_Struct*)outapp->pBuffer;
		wc->spawn_id = GetID();
		wc->material=0;
	}

	item->item_id = item2->ID;
	item->charges = charges;
	item->aug_1 = 0;
	item->aug_2 = 0;
	item->aug_3 = 0;
	item->aug_4 = 0;
	item->aug_5 = 0;
	item->aug_6 = 0;
	item->attuned = 0;
	item->min_level = minlevel;
	item->max_level = maxlevel;

	if (equipit) {
		uint8 eslot = 0xFF;
		char newid[20];
		const EQEmu::ItemBase* compitem = nullptr;
		bool found = false; // track if we found an empty slot we fit into
		int32 foundslot = -1; // for multi-slot items

		// Equip rules are as follows:
		// If the item has the NoPet flag set it will not be equipped.
		// An empty slot takes priority. The first empty one that an item can
		// fit into will be the one picked for the item.
		// AC is the primary choice for which item gets picked for a slot.
		// If AC is identical HP is considered next.
		// If an item can fit into multiple slots we'll pick the last one where
		// it is an improvement.

		if (!item2->NoPet) {
			for (int i = 0; !found && i < EQEmu::legacy::EQUIPMENT_SIZE; i++) {
				uint32 slots = (1 << i);
				if (item2->Slots & slots) {
					if(equipment[i])
					{
						compitem = database.GetItem(equipment[i]);
						if (item2->AC > compitem->AC ||
							(item2->AC == compitem->AC && item2->HP > compitem->HP))
						{
							// item would be an upgrade
							// check if we're multi-slot, if yes then we have to keep
							// looking in case any of the other slots we can fit into are empty.
							if (item2->Slots != slots) {
								foundslot = i;
							}
							else {
								equipment[i] = item2->ID;
								foundslot = i;
								found = true;
							}
						} // end if ac
					}
					else
					{
						equipment[i] = item2->ID;
						foundslot = i;
						found = true;
					}
				} // end if (slots)
			} // end for
		} // end if NoPet

		// Possible slot was found but not selected. Pick it now.
		if (!found && foundslot >= 0) {
			equipment[foundslot] = item2->ID;
			found = true;
		}

		// @merth: IDFile size has been increased, this needs to change
		uint16 emat;
		if(item2->Material <= 0
			|| item2->Slots & (1 << EQEmu::legacy::SlotPrimary | 1 << EQEmu::legacy::SlotSecondary)) {
			memset(newid, 0, sizeof(newid));
			for(int i=0;i<7;i++){
				if (!isalpha(item2->IDFile[i])){
					strn0cpy(newid, &item2->IDFile[i],6);
					i=8;
				}
			}

			emat = atoi(newid);
		} else {
			emat = item2->Material;
		}

		if (foundslot == EQEmu::legacy::SlotPrimary) {
			if (item2->Proc.Effect != 0)
				CastToMob()->AddProcToWeapon(item2->Proc.Effect, true);

			eslot = EQEmu::textures::TexturePrimary;
			if (item2->Damage > 0)
				SendAddPlayerState(PlayerState::PrimaryWeaponEquipped);
			if (item2->IsType2HWeapon())
				SetTwoHanderEquipped(true);
		}
		else if (foundslot == EQEmu::legacy::SlotSecondary
			&& (GetOwner() != nullptr || (CanThisClassDualWield() && zone->random.Roll(NPC_DW_CHANCE)) || (item2->Damage==0)) &&
			(item2->IsType1HWeapon() || item2->ItemType == EQEmu::item::ItemTypeShield))
		{
			if (item2->Proc.Effect!=0)
				CastToMob()->AddProcToWeapon(item2->Proc.Effect, true);

			eslot = EQEmu::textures::TextureSecondary;
			if (item2->Damage > 0)
				SendAddPlayerState(PlayerState::SecondaryWeaponEquipped);
		}
		else if (foundslot == EQEmu::legacy::SlotHead) {
			eslot = EQEmu::textures::TextureHead;
		}
		else if (foundslot == EQEmu::legacy::SlotChest) {
			eslot = EQEmu::textures::TextureChest;
		}
		else if (foundslot == EQEmu::legacy::SlotArms) {
			eslot = EQEmu::textures::TextureArms;
		}
		else if (foundslot == EQEmu::legacy::SlotWrist1 || foundslot == EQEmu::legacy::SlotWrist2) {
			eslot = EQEmu::textures::TextureWrist;
		}
		else if (foundslot == EQEmu::legacy::SlotHands) {
			eslot = EQEmu::textures::TextureHands;
		}
		else if (foundslot == EQEmu::legacy::SlotLegs) {
			eslot = EQEmu::textures::TextureLegs;
		}
		else if (foundslot == EQEmu::legacy::SlotFeet) {
			eslot = EQEmu::textures::TextureFeet;
		}

		/*
		what was this about???

		if (((npc->GetRace()==127) && (npc->CastToMob()->GetOwnerID()!=0)) && (item2->Slots==24576) || (item2->Slots==8192) || (item2->Slots==16384)){
			npc->d_melee_texture2=atoi(newid);
			wc->wear_slot_id=8;
			if (item2->Material >0)
				wc->material=item2->Material;
			else
				wc->material=atoi(newid);
			npc->AC+=item2->AC;
			npc->STR+=item2->STR;
			npc->INT+=item2->INT;
		}
		*/

		//if we found an open slot it goes in...
		if(eslot != 0xFF) {
			if(wearchange) {
				wc->wear_slot_id = eslot;
				wc->material = emat;
			}

		}
		if (found) {
			CalcBonuses(); // This is less than ideal for bulk adding of items
		}
		item->equip_slot = item2->Slots;
	}

	if(itemlist != nullptr)
		itemlist->push_back(item);
	else
		safe_delete(item);

	if(wearchange && outapp) {
		entity_list.QueueClients(this, outapp);
		safe_delete(outapp);
	}

	UpdateEquipmentLight();
	if (UpdateActiveLight())
		SendAppearancePacket(AT_Light, GetActiveLightType());
}
Beispiel #3
0
void HGTController::fillDownloadList(bool &usingDiffs)
{
	usingDiffs = false;
	safe_delete(m_vSuperBlockList);
	MCFCore::MCF *webMcf = new MCFCore::MCF();

	try
	{
		webMcf->dlHeaderFromHttp(m_szUrl.c_str());
	}
	catch (gcException &e)
	{
		onErrorEvent(e);
		safe_delete(webMcf);
		return;
	}

	webMcf->sortFileList();

	uint64 mcfOffset = m_pHeader->getSize();
	size_t fsSize = m_rvFileList.size();

	//find the last files offset
	for (size_t x=0; x< fsSize; x++)
	{
		if (!m_rvFileList[x]->isSaved())
			continue;

		if ((m_rvFileList[x]->isComplete() || m_rvFileList[x]->hasStartedDL()) && m_rvFileList[x]->getOffSet() > mcfOffset)
		{
			mcfOffset = m_rvFileList[x]->getOffSet() + m_rvFileList[x]->getCurSize();
		}
	}

	std::deque<Misc::WGTBlock*> vBlockList;
	std::sort(m_rvFileList.begin(), m_rvFileList.end(), SortByOffset);

	for (size_t x=0; x<fsSize; x++)
	{
		//dont download all ready downloaded items
		if (m_rvFileList[x]->isComplete())
			continue;

		//skip files that arnt "saved" in the MCF
		if (!m_rvFileList[x]->isSaved())
			continue;	

		uint32 index = webMcf->findFileIndexByHash(m_rvFileList[x]->getHash());
		auto webFile = webMcf->getFile(index);

		uint64 size = m_rvFileList[x]->getCurSize();
		bool started = m_rvFileList[x]->hasStartedDL();

		if (index == UNKNOWN_ITEM || !webFile || !webFile->isSaved())
		{
			Warning(gcString("File {0} is not in web MCF. Skipping download.\n", m_rvFileList[x]->getName()));

			if (!started)
				m_rvFileList[x]->delFlag(MCFCore::MCFFileI::FLAG_SAVE);

			continue;
		}	


		if (!started)
			m_rvFileList[x]->setOffSet(mcfOffset);


		Misc::WGTBlock* temp = new Misc::WGTBlock;

		temp->fileOffset = m_rvFileList[x]->getOffSet();
		temp->file = m_rvFileList[x];

		if (webFile->hasDiff() && HasAllFlags(m_rvFileList[x]->getFlags(), MCFFileI::FLAG_CANUSEDIFF))
		{
			temp->webOffset = webFile->getDiffOffSet();
			temp->size = webFile->getDiffSize();

			if (!started)
				mcfOffset += webFile->getSize();

			usingDiffs = true;
		}
		else
		{
			m_rvFileList[x]->delFlag(MCFFileI::FLAG_CANUSEDIFF);
			temp->webOffset = webFile->getOffSet();
			temp->size = size;

			if (!started)
				mcfOffset += size;
		}

		vBlockList.push_back(temp);
		m_uiTotal += temp->size;
	}


	std::sort(vBlockList.begin(), vBlockList.end(), &WGTBlockSort);

	while (vBlockList.size() > 0)
	{
		Misc::WGTSuperBlock* sb = new Misc::WGTSuperBlock();
		sb->offset = vBlockList[0]->webOffset;

		do
		{
			Misc::WGTBlock* block = vBlockList.front();
			vBlockList.pop_front();

			sb->size += block->size;
			sb->vBlockList.push_back(block);
		}
		while (vBlockList.size() > 0 && vBlockList[0]->webOffset == (sb->offset + sb->size));

		m_vSuperBlockList.push_back(sb);
	}
}
Beispiel #4
0
bool Group::DelMember(Mob* oldmember,bool ignoresender)
{
	if (oldmember == nullptr)
	{
		return false;
	}

	for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++)
	{
		if (members[i] == oldmember)
		{
			members[i] = nullptr;
			membername[i][0] = '\0';
			memset(membername[i],0,64);
			MemberRoles[i] = 0;
			Log.Out(Logs::Detail, Logs::Group, "DelMember: Removed Member: %s", oldmember->GetCleanName());
			break;
		}
	}

	if(GroupCount() < 2)
	{
		DisbandGroup();
		return true;
	}

	// If the leader has quit and we have 2 or more players left in group, we want to first check the zone the old leader was in for a new leader. 
	// If a suitable replacement cannot be found, we need to go out of zone. If checkleader remains true after this method completes, another
	// loop will be run in DelMemberOOZ.
	bool checkleader = true;
	if (strcmp(GetOldLeaderName(),oldmember->GetCleanName()) == 0 && GroupCount() >= 2)
	{
		for(uint32 nl = 0; nl < MAX_GROUP_MEMBERS; nl++)
		{
			if(members[nl]) 
			{
				if (members[nl]->IsClient())
				{
					ChangeLeader(members[nl]);
					checkleader = false;
					break;
				}
			}
		}
	}
			
	ServerPacket* pack = new ServerPacket(ServerOP_GroupLeave, sizeof(ServerGroupLeave_Struct));
	ServerGroupLeave_Struct* gl = (ServerGroupLeave_Struct*)pack->pBuffer;
	gl->gid = GetID();
	gl->zoneid = zone->GetZoneID();
	gl->instance_id = zone->GetInstanceID();
	strcpy(gl->member_name, oldmember->GetName());
	gl->checkleader = checkleader;
	worldserver.SendPacket(pack);
	safe_delete(pack);

	EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
	GroupJoin_Struct* gu = (GroupJoin_Struct*)outapp->pBuffer;
	gu->action = groupActLeave;
	strcpy(gu->membername, oldmember->GetCleanName());
	strcpy(gu->yourname, oldmember->GetCleanName());

	for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) {
		if (members[i] == nullptr) {
			//if (DEBUG>=5) Log.Out(Logs::Detail, Logs::Group, "Group::DelMember() null member at slot %i", i);
			continue;
		}
		if (members[i] != oldmember) {
			strcpy(gu->yourname, members[i]->GetCleanName());
			if(members[i]->IsClient())
				members[i]->CastToClient()->QueuePacket(outapp);
		}
	}

	if (!ignoresender)
	{
		strcpy(gu->yourname,oldmember->GetCleanName());
		strcpy(gu->membername,oldmember->GetCleanName());
		gu->action = groupActLeave;

		if(oldmember->IsClient())
			oldmember->CastToClient()->QueuePacket(outapp);
	}

	if(oldmember->IsClient())
	{
		database.SetGroupID(oldmember->GetCleanName(), 0, oldmember->CastToClient()->CharacterID());
	}
	
	oldmember->SetGrouped(false);
	disbandcheck = true;

	safe_delete(outapp);

	return true;
}
Beispiel #5
0
bool Database::DBLoadDoors(uint32 iDoorCount, uint32 iMaxDoorID) {
    cout << "Loading Doors from database..." << endl;
    char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
    query = new char[256];
    strcpy(query, "SELECT MAX(id), Count(*) FROM doors");
    if (RunQuery(query, strlen(query), errbuf, &result))
    {
        safe_delete(query);
        row = mysql_fetch_row(result);
        if (row && row[0]) {
            if (atoi(row[0]) > iMaxDoorID) {
                cout << "Error: Insufficient shared memory to load doors." << endl;
                cout << "Max(id): " << atoi(row[0]) << ", iMaxDoorID: " << iMaxDoorID << endl;
                cout << "Fix this by increasing the MMF_MAX_Door_ID define statement" << endl;
                return false;
            }
            if (atoi(row[1]) != iDoorCount) {
                cout << "Error: Insufficient shared memory to load doors." << endl;
                cout << "Count(*): " << atoi(row[1]) << ", iDoorCount: " << iDoorCount << endl;
                return false;
            }
            max_door_type = atoi(row[0]);
            mysql_free_result(result);
            Door tmpDoor;
            MakeAnyLenString(&query, "SELECT id,doorid,zone,name,pos_x,pos_y,pos_z,heading,opentype,guild,lockpick,keyitem,triggerdoor,triggertype from doors");//WHERE zone='%s'", zone_name
            if (RunQuery(query, strlen(query), errbuf, &result))
            {
                safe_delete(query);
                while((row = mysql_fetch_row(result))) {
                    memset(&tmpDoor, 0, sizeof(Door));
                    tmpDoor.db_id = atoi(row[0]);
                    tmpDoor.door_id = atoi(row[1]);
                    strn0cpy(tmpDoor.zone_name,row[2],32);
                    strn0cpy(tmpDoor.door_name,row[3],32);
                    tmpDoor.pos_x = (float)atof(row[4]);
                    tmpDoor.pos_y = (float)atof(row[5]);
                    tmpDoor.pos_z = (float)atof(row[6]);
                    tmpDoor.heading = atoi(row[7]);
                    tmpDoor.opentype = atoi(row[8]);
                    tmpDoor.guild_id = atoi(row[9]);
                    tmpDoor.lockpick = atoi(row[10]);
                    tmpDoor.keyitem = atoi(row[11]);
                    tmpDoor.trigger_door = atoi(row[12]);
                    tmpDoor.trigger_type = atoi(row[13]);
                    EMuShareMemDLL.Doors.cbAddDoor(tmpDoor.db_id, &tmpDoor);
                    Sleep(0);
                }
                mysql_free_result(result);
            }
            else
            {
                cerr << "Error in DBLoadDoors query '" << query << "' " << errbuf << endl;
                delete[] query;
                return false;
            }
        }
    }
    return true;
}
Beispiel #6
0
void Trap::Trigger(Mob* trigger)
{
	Log.Out(Logs::General, Logs::Traps, "Trap %d triggered by %s for the %d time!", trap_id, trigger->GetName(), times_triggered+1);

	int i = 0;
	const NPCType* tmp = 0;
	switch (effect)
	{
		case trapTypeDebuff:
			if(message.empty())
			{
				entity_list.MessageClose(trigger,false,100,CC_Default,"%s triggers a trap!",trigger->GetName());
			}
			else
			{
				entity_list.MessageClose(trigger,false,100,CC_Default,"%s",message.c_str());
			}
			if(hiddenTrigger){
				hiddenTrigger->SpellFinished(effectvalue, trigger, 10, 0, -1, spells[effectvalue].ResistDiff);
			}
			break;
		case trapTypeAlarm:
			if (message.empty())
			{
				entity_list.MessageClose(trigger,false,effectvalue,CC_Default,"A loud alarm rings out through the air...");
			}
			else
			{
				entity_list.MessageClose(trigger,false,effectvalue,CC_Default,"%s",message.c_str());
			}

			entity_list.SendAlarm(this,trigger,effectvalue2);
			break;
		case trapTypeMysticSpawn:
			if (message.empty())
			{
				entity_list.MessageClose(trigger,false,100,CC_Default,"The air shimmers...");
			}
			else
			{
				entity_list.MessageClose(trigger,false,100,CC_Default,"%s",message.c_str());
			}

			for (i = 0; i < effectvalue2; i++)
			{
				if ((tmp = database.GetNPCType(effectvalue)))
				{
					auto randomOffset = glm::vec4(zone->random.Int(-5, 5),zone->random.Int(-5, 5),zone->random.Int(-5, 5), zone->random.Int(0, 249));
					auto spawnPosition = randomOffset + glm::vec4(m_Position, 0.0f);
					NPC* new_npc = new NPC(tmp, nullptr, spawnPosition, FlyMode3);
					new_npc->AddLootTable();
					entity_list.AddNPC(new_npc);
					new_npc->AddToHateList(trigger,1);
				}
			}
			break;
		case trapTypeBanditSpawn:
			if (message.empty())
			{
				entity_list.MessageClose(trigger,false,100,CC_Default,"A bandit leaps out from behind a tree!");
			}
			else
			{
				entity_list.MessageClose(trigger,false,100,CC_Default,"%s",message.c_str());
			}

			for (i = 0; i < effectvalue2; i++)
			{
				if ((tmp = database.GetNPCType(effectvalue)))
				{
					auto randomOffset = glm::vec4(zone->random.Int(-2, 2), zone->random.Int(-2, 2), zone->random.Int(-2, 2), zone->random.Int(0, 249));
					auto spawnPosition = randomOffset + glm::vec4(m_Position, 0.0f);
					NPC* new_npc = new NPC(tmp, nullptr, spawnPosition, FlyMode3);
					new_npc->AddLootTable();
					entity_list.AddNPC(new_npc);
					new_npc->AddToHateList(trigger,1);
				}
			}
			break;
		case trapTypeDamage:
			if (message.empty())
			{
				entity_list.MessageClose(trigger,false,100,CC_Default,"%s triggers a trap!",trigger->GetName());
			}
			else
			{
				entity_list.MessageClose(trigger,false,100,CC_Default,"%s",message.c_str());
			}
			if(trigger->IsClient())
			{
				EQApplicationPacket* outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct));
				CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer;
				int dmg = zone->random.Int(effectvalue, effectvalue2);
				trigger->SetHP(trigger->GetHP() - dmg);
				a->damage = dmg;
				a->sequence = (float)zone->random.Int(0, 511);
				a->source = GetHiddenTrigger()!=nullptr ? GetHiddenTrigger()->GetID() : trigger->GetID();
				a->spellid = 0;
				a->target = trigger->GetID();
				a->type = 253;
				trigger->CastToClient()->QueuePacket(outapp);
				safe_delete(outapp);
			}
	}

	if(trigger && trigger->IsClient())
	{
		trigger->CastToClient()->trapid = trap_id;
		charid = trigger->CastToClient()->CharacterID();
	}

	bool update = false;
	if(despawn_when_triggered)
	{
		Log.Out(Logs::General, Logs::Traps, "Trap %d is despawning after being triggered.", trap_id);
		update = true;
	}
	else
	{
		reset_timer.Start(5000);
	}

	if(triggered_number > 0)
		++times_triggered;

	if(triggered_number > 0 && triggered_number <= times_triggered)
	{
		Log.Out(Logs::General, Logs::Traps, "Triggered number for trap %d reached. %d/%d", trap_id, times_triggered, triggered_number);
		update = true;
	}

	if(update)
	{
		UpdateTrap();
	}
}
Beispiel #7
0
void Doors::HandleClick(Client* sender, uint8 trigger)
{
    //door debugging info dump
    Log.Out(Logs::Detail, Logs::Doors, "%s clicked door %s (dbid %d, eqid %d) at %s", sender->GetName(), door_name, db_id, door_id, to_string(m_Position).c_str());
    Log.Out(Logs::Detail, Logs::Doors, "  incline %d, opentype %d, lockpick %d, key %d, nokeyring %d, trigger %d type %d, param %d", incline, opentype, lockpick, keyitem, nokeyring, trigger_door, trigger_type, door_param);
    Log.Out(Logs::Detail, Logs::Doors, "  size %d, invert %d, dest: %s %s", size, invert_state, dest_zone, to_string(m_Destination).c_str());

    EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoveDoor, sizeof(MoveDoor_Struct));
    MoveDoor_Struct* md = (MoveDoor_Struct*)outapp->pBuffer;
    md->doorid = door_id;
    /////////////////////////////////////////////////////////////////
    //used_pawn: Locked doors! Rogue friendly too =)
    //TODO: add check for other lockpick items
    //////////////////////////////////////////////////////////////////

    //TODO: ADVENTURE DOOR
    if(IsLDoNDoor())
    {
        if(sender)
        {
            if(RuleI(Adventure, ItemIDToEnablePorts) != 0)
            {
                if(!sender->KeyRingCheck(RuleI(Adventure, ItemIDToEnablePorts)))
                {
                    if (sender->GetInv().HasItem(RuleI(Adventure, ItemIDToEnablePorts)) == INVALID_INDEX)
                    {
                        sender->Message_StringID(13, DUNGEON_SEALED);
                        safe_delete(outapp);
                        return;
                    }
                    else
                    {
                        sender->KeyRingAdd(RuleI(Adventure, ItemIDToEnablePorts));
                    }
                }
            }

            if(!sender->GetPendingAdventureDoorClick())
            {
                sender->PendingAdventureDoorClick();
                ServerPacket *pack = new ServerPacket(ServerOP_AdventureClickDoor, sizeof(ServerPlayerClickedAdventureDoor_Struct));
                ServerPlayerClickedAdventureDoor_Struct *ads = (ServerPlayerClickedAdventureDoor_Struct*)pack->pBuffer;
                strcpy(ads->player, sender->GetName());
                ads->zone_id = zone->GetZoneID();
                ads->id = GetDoorDBID();
                worldserver.SendPacket(pack);
                safe_delete(pack);
                safe_delete(outapp);
            }
            return;
        }
    }

    uint32 keyneeded = GetKeyItem();
    uint8 keepoffkeyring = GetNoKeyring();
    uint32 haskey = 0;
    uint32 playerkey = 0;
    const ItemInst *lockpicks = sender->GetInv().GetItem(SlotCursor);

    haskey = sender->GetInv().HasItem(keyneeded, 1);

    if (haskey != INVALID_INDEX)
    {
        playerkey = keyneeded;
    }

    if(GetTriggerType() == 255)
    {   // this object isnt triggered
        if(trigger == 1)
        {   // this door is only triggered by an object
            if(!IsDoorOpen() || (opentype == 58))
            {
                md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
            }
            else
            {
                md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
            }
        }
        else
        {
            safe_delete(outapp);
            return;
        }
    }

    // guild doors
    if(((keyneeded == 0) && (GetLockpick() == 0) && (guild_id == 0)) ||
            (IsDoorOpen() && (opentype == 58)) ||
            ((guild_id > 0) && (guild_id == sender->GuildID())))
    {   //door not locked
        if(!IsDoorOpen() || (opentype == 58))
        {
            md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
        }
        else
        {
            md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
        }
    }
    else
    {   // guild doors
        if((guild_id > 0) && !sender->GetGM())
        {
            std::string tmp;
            char tmpmsg[240]; // guild doors msgs
            if(guild_mgr.GetGuildNameByID(guild_id, tmp))
            {
                sprintf(tmpmsg, "Only members of the <%s> guild may enter here", tmp.c_str());
            }
            else
            {
                strcpy(tmpmsg, "Door is locked by an unknown guild");
            }
            sender->Message(4, tmpmsg);
            safe_delete(outapp);
            return;
        }
        // a key is required or the door is locked but can be picked or both
        sender->Message(4, "This is locked...");		// debug spam - should probably go
        if(sender->GetGM())		// GM can always open locks - should probably be changed to require a key
        {
            sender->Message_StringID(4,DOORS_GM);
            if(!IsDoorOpen() || (opentype == 58))
            {
                md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
            }
            else
            {
                md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
            }
        }
        else if(playerkey)
        {   // they have something they are trying to open it with
            if(keyneeded && (keyneeded == playerkey))
            {   // key required and client is using the right key
                if(!keepoffkeyring)
                {
                    sender->KeyRingAdd(playerkey);
                }
                sender->Message(4, "You got it open!");
                if(!IsDoorOpen() || (opentype == 58))
                {
                    md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
                }
                else
                {
                    md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
                }
            }
        }
        else if(lockpicks != nullptr)
        {
            if(sender->GetSkill(SkillPickLock))
            {
                if(lockpicks->GetItem()->ItemType == ItemTypeLockPick)
                {
                    float modskill=sender->GetSkill(SkillPickLock);
                    sender->CheckIncreaseSkill(SkillPickLock, nullptr, 1);

                    Log.Out(Logs::General, Logs::Skills, "Client has lockpicks: skill=%f", modskill);

                    if(GetLockpick() <= modskill)
                    {
                        if(!IsDoorOpen())
                        {
                            md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
                        }
                        else
                        {
                            md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
                        }
                        sender->Message_StringID(4, DOORS_SUCCESSFUL_PICK);
                    }
                    else
                    {
                        sender->Message_StringID(4, DOORS_INSUFFICIENT_SKILL);
                        safe_delete(outapp);
                        return;
                    }
                }
                else
                {
                    sender->Message_StringID(4, DOORS_NO_PICK);
                    safe_delete(outapp);
                    return;
                }
            }
            else
            {
                sender->Message_StringID(4, DOORS_CANT_PICK);
                safe_delete(outapp);
                return;
            }
        }
        else
        {   // locked door and nothing to open it with
            // search for key on keyring
            if(sender->KeyRingCheck(keyneeded))
            {
                playerkey = keyneeded;
                sender->Message(4, "You got it open!"); // more debug spam
                if(!IsDoorOpen() || (opentype == 58))
                {
                    md->action = invert_state == 0 ? OPEN_DOOR : OPEN_INVDOOR;
                }
                else
                {
                    md->action = invert_state == 0 ? CLOSE_DOOR : CLOSE_INVDOOR;
                }
            }
            else
            {
                sender->Message_StringID(4, DOORS_LOCKED);
                safe_delete(outapp);
                return;
            }
        }
    }

    entity_list.QueueClients(sender, outapp, false);
    if(!IsDoorOpen() || (opentype == 58))
    {
        close_timer.Start();
        SetOpenState(true);
    }
    else
    {
        close_timer.Disable();
        SetOpenState(false);
    }

    //everything past this point assumes we opened the door
    //and met all the reqs for opening
    //everything to do with closed doors has already been taken care of
    //we return because we don't want people using teleports on an unlocked door (exploit!)
    if((md->action == CLOSE_DOOR && invert_state == 0) || (md->action == CLOSE_INVDOOR && invert_state == 1))
    {
        safe_delete(outapp);
        return;
    }

    safe_delete(outapp);

    if((GetTriggerDoorID() != 0) && (GetTriggerType() == 1))
    {
        Doors* triggerdoor = entity_list.FindDoor(GetTriggerDoorID());
        if(triggerdoor && !triggerdoor->triggered)
        {
            triggered=true;
            triggerdoor->HandleClick(sender, 1);
        }
        else
        {
            triggered=false;
        }
    }
    else if((GetTriggerDoorID() != 0) && (GetTriggerType() != 1))
    {
        Doors* triggerdoor = entity_list.FindDoor(GetTriggerDoorID());
        if(triggerdoor && !triggerdoor->triggered)
        {
            triggered=true;
            triggerdoor->HandleClick(sender, 0);
        }
        else
        {
            triggered=false;
        }
    }

    if(((opentype == 57) || (opentype == 58)) && (strncmp(dest_zone, "NONE", strlen("NONE")) != 0))
    {   // Teleport door!
        if (( strncmp(dest_zone,zone_name,strlen(zone_name)) == 0) && (!keyneeded))
        {
            if(!keepoffkeyring)
            {
                sender->KeyRingAdd(playerkey);
            }
            sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w);
        }
        else if (( !IsDoorOpen() || opentype == 58 ) && (keyneeded && ((keyneeded == playerkey) || sender->GetGM())))
        {
            if(!keepoffkeyring)
            {
                sender->KeyRingAdd(playerkey);
            }
            if(database.GetZoneID(dest_zone) == zone->GetZoneID())
            {
                sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w);
            }
            else
            {
                sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w);
            }
        }
        if (( !IsDoorOpen() || opentype == 58 ) && (!keyneeded))
        {
            if(database.GetZoneID(dest_zone) == zone->GetZoneID())
            {
                sender->MovePC(zone->GetZoneID(), zone->GetInstanceID(), m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w);
            }
            else
            {
                sender->MovePC(database.GetZoneID(dest_zone), dest_instance_id, m_Destination.x, m_Destination.y, m_Destination.z, m_Destination.w);
            }
        }
    }
}
Beispiel #8
0
void Corpse::SendEndLootErrorPacket(Client* client) {
	EQApplicationPacket* outapp = new EQApplicationPacket(OP_LootComplete, 0);
	client->QueuePacket(outapp);
	safe_delete(outapp);
}
Beispiel #9
0
bool Corpse::Process() {
	if (player_corpse_depop)
		return false;

	if (corpse_delay_timer.Check()) {
		for (int i = 0; i < MAX_LOOTERS; i++)
			allowed_looters[i] = 0;
		corpse_delay_timer.Disable();
		return true;
	}

	if (corpse_graveyard_timer.Check()) {
		if (zone->HasGraveyard()) {
			Save();
			player_corpse_depop = true;
			database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(),
				(zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->GetGraveyardPoint());
			corpse_graveyard_timer.Disable();
			ServerPacket* pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct));
			SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer;
			spc->player_corpse_id = corpse_db_id;
			spc->zone_id = zone->graveyard_zoneid();
			worldserver.SendPacket(pack);
			safe_delete(pack);
			Log.Out(Logs::General, Logs::None, "Moved %s player corpse to the designated graveyard in zone %s.", this->GetName(), database.GetZoneName(zone->graveyard_zoneid()));
			corpse_db_id = 0;
		}

		corpse_graveyard_timer.Disable();
		return false;
	}
	/*
	if(corpse_res_timer.Check()) {
		can_rez = false;
		corpse_res_timer.Disable();
	}
	*/

	/* This is when a corpse hits decay timer and does checks*/
	if (corpse_decay_timer.Check()) {
		/* NPC */
		if (IsNPCCorpse()){
			corpse_decay_timer.Disable();
			return false;
		}
		/* Client */
		if (!RuleB(Zone, EnableShadowrest)){
			Delete();
		}
		else {
			if (database.BuryCharacterCorpse(corpse_db_id)) {
				Save();
				player_corpse_depop = true;
				corpse_db_id = 0;
				Log.Out(Logs::General, Logs::None, "Tagged %s player corpse has buried.", this->GetName());
			}
			else {
				Log.Out(Logs::General, Logs::Error, "Unable to bury %s player corpse.", this->GetName());
				return true;
			}
		}
		corpse_decay_timer.Disable();
		return false;
	}

	return true;
}
Beispiel #10
0
void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
	/* This gets sent no matter what as a sort of ACK */
	client->QueuePacket(app);

	if (!loot_cooldown_timer.Check()) {
		SendEndLootErrorPacket(client);
		//unlock corpse for others
		if (this->being_looted_by = client->GetID()) {
			being_looted_by = 0xFFFFFFFF;
		}
		return;
	}

	/* To prevent item loss for a player using 'Loot All' who doesn't have inventory space for all their items. */
	if (RuleB(Character, CheckCursorEmptyWhenLooting) && !client->GetInv().CursorEmpty()) {
		client->Message(13, "You may not loot an item while you have an item on your cursor.");
		SendEndLootErrorPacket(client);
		/* Unlock corpse for others */
		if (this->being_looted_by = client->GetID()) {
			being_looted_by = 0xFFFFFFFF;
		}
		return;
	}

	LootingItem_Struct* lootitem = (LootingItem_Struct*)app->pBuffer;

	if (this->being_looted_by != client->GetID()) {
		client->Message(13, "Error: Corpse::LootItem: BeingLootedBy != client");
		SendEndLootErrorPacket(client);
		return;
	}
	if (IsPlayerCorpse() && !CanPlayerLoot(client->CharacterID()) && !become_npc && (char_id != client->CharacterID() && client->Admin() < 150)) {
		client->Message(13, "Error: This is a player corpse and you dont own it.");
		SendEndLootErrorPacket(client);
		return;
	}
	if (is_locked && client->Admin() < 100) {
		SendLootReqErrorPacket(client, 0);
		client->Message(13, "Error: Corpse locked by GM.");
		return;
	}
	if (IsPlayerCorpse() && (char_id != client->CharacterID()) && CanPlayerLoot(client->CharacterID()) && GetPlayerKillItem() == 0){
		client->Message(13, "Error: You cannot loot any more items from this corpse.");
		SendEndLootErrorPacket(client);
		being_looted_by = 0xFFFFFFFF;
		return;
	}
	const Item_Struct* item = 0;
	ItemInst *inst = 0;
	ServerLootItem_Struct* item_data = nullptr, *bag_item_data[10];

	memset(bag_item_data, 0, sizeof(bag_item_data));
	if (GetPlayerKillItem() > 1){
		item = database.GetItem(GetPlayerKillItem());
	}
	else if (GetPlayerKillItem() == -1 || GetPlayerKillItem() == 1){
		item_data = GetItem(lootitem->slot_id - EmuConstants::CORPSE_BEGIN); //dont allow them to loot entire bags of items as pvp reward
	}
	else{
		item_data = GetItem(lootitem->slot_id - EmuConstants::CORPSE_BEGIN, bag_item_data);
	}

	if (GetPlayerKillItem()<=1 && item_data != 0) {
		item = database.GetItem(item_data->item_id);
	}

	if (item != 0) {
		if (item_data){ 
			inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
		}
		else {
			inst = database.CreateItem(item);
		}
	}

	if (client && inst) {
		if (client->CheckLoreConflict(item)) {
			client->Message_StringID(0, LOOT_LORE_ERROR);
			SendEndLootErrorPacket(client);
			being_looted_by = 0;
			delete inst;
			return;
		}

		if (inst->IsAugmented()) {
			for (int i = AUG_BEGIN; i < EmuConstants::ITEM_COMMON_SIZE; i++) {
				ItemInst *itm = inst->GetAugment(i);
				if (itm) {
					if (client->CheckLoreConflict(itm->GetItem())) {
						client->Message_StringID(0, LOOT_LORE_ERROR);
						SendEndLootErrorPacket(client);
						being_looted_by = 0;
						delete inst;
						return;
					}
				}
			}
		}

		char buf[88];
		char corpse_name[64];
		strcpy(corpse_name, corpse_name);
		snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(), EntityList::RemoveNumbers(corpse_name));
		buf[87] = '\0';
		std::vector<EQEmu::Any> args;
		args.push_back(inst);
		args.push_back(this);
		parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args);
		parse->EventItem(EVENT_LOOT, client, inst, this, buf, 0);

		if (!IsPlayerCorpse() && RuleB(Character, EnableDiscoveredItems)) {
			if (client && !client->GetGM() && !client->IsDiscovered(inst->GetItem()->ID))
				client->DiscoverItem(inst->GetItem()->ID);
		}

		if (zone->adv_data) {
			ServerZoneAdventureDataReply_Struct *ad = (ServerZoneAdventureDataReply_Struct*)zone->adv_data;
			if (ad->type == Adventure_Collect && !IsPlayerCorpse()) {
				if (ad->data_id == inst->GetItem()->ID) {
					zone->DoAdventureCountIncrease();
				}
			}
		}

		/* First add it to the looter - this will do the bag contents too */
		if (lootitem->auto_loot) {
			if (!client->AutoPutLootInInventory(*inst, true, true, bag_item_data))
				client->PutLootInInventory(MainCursor, *inst, bag_item_data);
		}
		else {
			client->PutLootInInventory(MainCursor, *inst, bag_item_data);
		}

		/* Update any tasks that have an activity to loot this item */
		if (RuleB(TaskSystem, EnableTaskSystem))
			client->UpdateTasksForItem(ActivityLoot, item->ID);

		/* Remove it from Corpse */
		if (item_data){
			/* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */
			database.DeleteItemOffCharacterCorpse(this->corpse_db_id, item_data->equip_slot, item_data->item_id);
			/* Delete Item Instance */
			RemoveItem(item_data->lootslot);
		}

		/* Remove Bag Contents */
		if (item->ItemClass == ItemClassContainer && (GetPlayerKillItem() != -1 || GetPlayerKillItem() != 1)) {
			for (int i = SUB_BEGIN; i < EmuConstants::ITEM_CONTAINER_SIZE; i++) {
				if (bag_item_data[i]) {
					/* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */
					database.DeleteItemOffCharacterCorpse(this->corpse_db_id, bag_item_data[i]->equip_slot, bag_item_data[i]->item_id);
					/* Delete Item Instance */
					RemoveItem(bag_item_data[i]);
				}
			}
		}

		if (GetPlayerKillItem() != -1) {
			SetPlayerKillItemID(0);
		}

	/* Send message with item link to groups and such */
	Client::TextLink linker;
	linker.SetLinkType(linker.linkItemInst);
	linker.SetItemInst(inst);

	auto item_link = linker.GenerateLink();

	client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, item_link.c_str());

	if (!IsPlayerCorpse()) {
			Group *g = client->GetGroup();
			if(g != nullptr) {
				g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
			}
			else {
				Raid *r = client->GetRaid();
				if(r != nullptr) {
					r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
				}
			}
		}
	}
	else {
		SendEndLootErrorPacket(client);
		safe_delete(inst);
		return;
	}

	if (IsPlayerCorpse()){
		client->SendItemLink(inst);
	}
	else{
		client->SendItemLink(inst, true);
	}

	safe_delete(inst);
}
Beispiel #11
0
void Corpse::Spawn() {
	EQApplicationPacket* app = new EQApplicationPacket;
	this->CreateSpawnPacket(app, this);
	entity_list.QueueClients(this, app);
	safe_delete(app);
}
Beispiel #12
0
BaseMCFThread::~BaseMCFThread()
{
	safe_delete(m_pUPThread);
}
Beispiel #13
0
	void Window::OnResourceUnload()
	{
		OnUnload();

		safe_delete(mLayout);
	}
Beispiel #14
0
	virtual void OnShutdown()
	{
		safe_delete(mVideoPlayer);
	}
Beispiel #15
0
static void thread_proc(NodeFunction* pFunc, ParseInfo* pinfo, std::vector<Symbol*>* pvecSyms)
{
	// ignore return value
	Symbol *pRet = task_proc(pFunc, pinfo, pvecSyms);
	safe_delete(pRet, 0, pinfo);
}
Beispiel #16
0
void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* app) {
	// Added 12/08. Started compressing loot struct on live.
	char tmp[10];
	if(player_corpse_depop) {
		SendLootReqErrorPacket(client, 0);
		return;
	}

	if(IsPlayerCorpse() && corpse_db_id == 0) {
		// SendLootReqErrorPacket(client, 0);
		client->Message(13, "Warning: Corpse's dbid = 0! Corpse will not survive zone shutdown!");
		std::cout << "Error: PlayerCorpse::MakeLootRequestPackets: dbid = 0!" << std::endl;
		// return;
	}

	if(is_locked && client->Admin() < 100) {
		SendLootReqErrorPacket(client, 0);
		client->Message(13, "Error: Corpse locked by GM.");
		return;
	}

	if(being_looted_by == 0)
		being_looted_by = 0xFFFFFFFF;

	if(this->being_looted_by != 0xFFFFFFFF) {
		// lets double check....
		Entity* looter = entity_list.GetID(this->being_looted_by);
		if(looter == 0)
			this->being_looted_by = 0xFFFFFFFF;
	}

	uint8 Loot_Request_Type = 1;
	bool loot_coin = false;
	if(database.GetVariable("LootCoin", tmp, 9))
		loot_coin = (atoi(tmp) == 1);

	if (this->being_looted_by != 0xFFFFFFFF && this->being_looted_by != client->GetID()) {
		SendLootReqErrorPacket(client, 0);
		Loot_Request_Type = 0;
	}
	else if (IsPlayerCorpse() && char_id == client->CharacterID()) {
		Loot_Request_Type = 2;
	}
	else if ((IsNPCCorpse() || become_npc) && CanPlayerLoot(client->CharacterID())) {
		Loot_Request_Type = 2;
	}
	else if (GetPlayerKillItem() == -1 && CanPlayerLoot(client->CharacterID())) { /* PVP loot all items, variable cash */
		Loot_Request_Type = 3;
	}
	else if (GetPlayerKillItem() == 1 && CanPlayerLoot(client->CharacterID())) { /* PVP loot 1 item, variable cash */
		Loot_Request_Type = 4;
	}
	else if (GetPlayerKillItem() > 1 && CanPlayerLoot(client->CharacterID())) { /* PVP loot 1 set item, variable cash */
		Loot_Request_Type = 5;
	}

	if (Loot_Request_Type == 1) {
		if (client->Admin() < 100 || !client->GetGM()) {
			SendLootReqErrorPacket(client, 2);
		}
	}

	if(Loot_Request_Type >= 2 || (Loot_Request_Type == 1 && client->Admin() >= 100 && client->GetGM())) {
		this->being_looted_by = client->GetID();
		EQApplicationPacket* outapp = new EQApplicationPacket(OP_MoneyOnCorpse, sizeof(moneyOnCorpseStruct));
		moneyOnCorpseStruct* d = (moneyOnCorpseStruct*) outapp->pBuffer;

		d->response		= 1;
		d->unknown1		= 0x42;
		d->unknown2		= 0xef;

		/* Dont take the coin off if it's a gm peeking at the corpse */
		if(Loot_Request_Type == 2 || (Loot_Request_Type >= 3 && loot_coin)) {
			if(!IsPlayerCorpse() && client->IsGrouped() && client->AutoSplitEnabled() && client->GetGroup()) {
				d->copper		= 0;
				d->silver		= 0;
				d->gold			= 0;
				d->platinum		= 0;
				Group *cgroup = client->GetGroup();
				cgroup->SplitMoney(GetCopper(), GetSilver(), GetGold(), GetPlatinum(), client);
			}
			else {
				d->copper		= this->GetCopper();
				d->silver		= this->GetSilver();
				d->gold			= this->GetGold();
				d->platinum		= this->GetPlatinum();
				client->AddMoneyToPP(GetCopper(), GetSilver(), GetGold(), GetPlatinum(), false);
			}

			RemoveCash();
			Save();
		}

		auto timestamps = database.GetItemRecastTimestamps(client->CharacterID());
		outapp->priority = 6;
		client->QueuePacket(outapp);
		safe_delete(outapp);
		if(Loot_Request_Type == 5) {
			int pkitem = GetPlayerKillItem();
			const Item_Struct* item = database.GetItem(pkitem);
			ItemInst* inst = database.CreateItem(item, item->MaxCharges);
			if(inst) {
				if (item->RecastDelay)
					inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
				client->SendItemPacket(EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
				safe_delete(inst);
			}
			else { client->Message(13, "Could not find item number %i to send!!", GetPlayerKillItem()); }

			client->QueuePacket(app);
			return;
		}

		int i = 0;
		const Item_Struct* item = 0;
		ItemList::iterator cur,end;
		cur = itemlist.begin();
		end = itemlist.end();

		int corpselootlimit = EQLimits::InventoryMapSize(MapCorpse, client->GetClientVersion());

		for(; cur != end; ++cur) {
			ServerLootItem_Struct* item_data = *cur;
			item_data->lootslot = 0xFFFF;

			// Dont display the item if it's in a bag

			// Added cursor queue slots to corpse item visibility list. Nothing else should be making it to corpse.
			if(!IsPlayerCorpse() || item_data->equip_slot <= MainCursor || item_data->equip_slot == MainPowerSource || Loot_Request_Type>=3 ||
				(item_data->equip_slot >= 8000 && item_data->equip_slot <= 8999)) {
				if(i < corpselootlimit) {
					item = database.GetItem(item_data->item_id);
					if(client && item) {
						ItemInst* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
						if(inst) {
							if (item->RecastDelay)
								inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
							// MainGeneral1 is the corpse inventory start offset for Ti(EMu) - CORPSE_END = MainGeneral1 + MainCursor
							client->SendItemPacket(i + EmuConstants::CORPSE_BEGIN, inst, ItemPacketLoot);
							safe_delete(inst);
						}

						item_data->lootslot = i;
					}
				}

				i++;
			}
		}

		if(IsPlayerCorpse() && (char_id == client->CharacterID() || client->GetGM())) {
			if(i > corpselootlimit) {
				client->Message(15, "*** This corpse contains more items than can be displayed! ***");
				client->Message(0, "Remove items and re-loot corpse to access remaining inventory.");
				client->Message(0, "(%s contains %i additional %s.)", GetName(), (i - corpselootlimit), (i - corpselootlimit) == 1 ? "item" : "items");
			}

			if(IsPlayerCorpse() && i == 0 && itemlist.size() > 0) { // somehow, player corpse contains items, but client doesn't see them...
				client->Message(13, "This corpse contains items that are inaccessable!");
				client->Message(15, "Contact a GM for item replacement, if necessary.");
				client->Message(15, "BUGGED CORPSE [DBID: %i, Name: %s, Item Count: %i]", GetCorpseDBID(), GetName(), itemlist.size());

				cur = itemlist.begin();
				end = itemlist.end();
				for(; cur != end; ++cur) {
					ServerLootItem_Struct* item_data = *cur;
					item = database.GetItem(item_data->item_id);
					Log.Out(Logs::General, Logs::None, "Corpse Looting: %s was not sent to client loot window (corpse_dbid: %i, charname: %s(%s))", item->Name, GetCorpseDBID(), client->GetName(), client->GetGM() ? "GM" : "Owner");
					client->Message(0, "Inaccessable Corpse Item: %s", item->Name);
				}
			}
		}
	}

	// Disgrace: Client seems to require that we send the packet back...
	client->QueuePacket(app);

	// This is required for the 'Loot All' feature to work for SoD clients. I expect it is to tell the client that the
	// server has now sent all the items on the corpse.
	if(client->GetClientVersion() >= ClientVersion::SoD) { SendLootReqErrorPacket(client, 6); }
}
Beispiel #17
0
SMTWorker::~SMTWorker()
{
	safe_delete(m_phFhSink);
	safe_delete(m_BZ2Worker);
}
Beispiel #18
0
void MCF::dlHeaderFromWeb()
{
	if (m_bStopped)
		return;

	if (m_vProviderList.size() == 0)
		throw gcException(ERR_ZEROFILE);

	gcException lastE;
	bool successful = false;

	OutBuffer out(MCF_HEADERSIZE_V2);
	MCFCore::Misc::MCFServerCon msc;

	for (size_t x=0; x<m_vProviderList.size(); x++)
	{
		try
		{
			msc.disconnect();
			msc.connect(m_vProviderList[x]->getUrl(), m_pFileAuth);

			msc.downloadRange(0, 5, &out); //4 id bytes and 1 version byte

			if (out.m_uiTotalSize != 5)
				throw gcException(ERR_BADHEADER, "Did not get any data from mcf server.");

			const char* data = out.m_szBuffer;

			if ( !(data[0] == 'L' && data[1] == 'M' && data[2] == 'C' && data[3] == 'F') )
				throw gcException(ERR_BADHEADER, "Failed magic check.");

			size_t headerSize = MCF_HEADERSIZE_V1;

			if (data[4] == 0x01)
				headerSize = MCF_HEADERSIZE_V1;
			else if (data[4] == 0x02)
				headerSize = MCF_HEADERSIZE_V2;
			else
				throw gcException(ERR_BADHEADER, "Bad version number");

			out.reset();
			msc.downloadRange(0, headerSize, &out);

			if (out.m_uiTotalSize != headerSize)
				throw gcException(ERR_BADHEADER, "Did not get correct ammount of data from server.");

			MCFCore::MCFHeader webHeader((uint8*)out.m_szBuffer);

			if (!webHeader.isValid())
				throw gcException(ERR_BADHEADER, "Mcf header was not valid.");

			uint32 ths = webHeader.getXmlSize();
			out = ths;

			msc.downloadRange(webHeader.getXmlStart(), webHeader.getXmlSize(), &out);

			if (out.m_uiTotalSize == 0 || out.m_uiTotalSize != webHeader.getXmlSize())
				throw gcException(ERR_WEBDL_FAILED, "Failed to download MCF xml from web (size is ether zero or didnt match header size)");

			data = out.m_szBuffer;

			if (data[0] == 'L' && data[1] == 'M' && data[2] == 'C' && data[3] == 'F')
				throw gcException(ERR_WEBDL_FAILED, "Server failed 4gb seek.");

			setHeader(&webHeader);
			successful = true;
			break;

		}
		catch (gcException &e)
		{
			lastE = e;
			Warning(gcString("Failed to download MCF Header from {1}: {0}\n", e, m_vProviderList[x]->getUrl()));
		}
	}

	if (!successful)
		throw lastE;

	uint32 bz2BuffLen = getHeader()->getXmlSize()*25;
	char* bz2Buff = NULL;

	if ( isCompressed() )
	{
		bz2Buff = new char[bz2BuffLen];
		UTIL::STRING::zeroBuffer(bz2Buff, bz2BuffLen);

		try
		{
			UTIL::BZIP::BZ2DBuff((char*)bz2Buff, &bz2BuffLen, out.m_szBuffer, out.m_uiTotalSize);
			parseXml(bz2Buff, bz2BuffLen);
			safe_delete(bz2Buff);
		}
		catch (gcException &)
		{
			safe_delete(bz2Buff);
			throw;
		}
	}
	else
	{
		parseXml(out.m_szBuffer, out.m_uiTotalSize);
	}

	//we remove the complete flag due to the files not existing in the MCF
	for (size_t x=0; x< m_pFileList.size(); x++)
	{
		m_pFileList[x]->delFlag(MCFCore::MCFFileI::FLAG_COMPLETE);
	}

	if (m_szFile != "")
		saveMCF_Header();
}
Beispiel #19
0
// Split from the basic MakePet to allow backward compatiblity with existing code while also
// making it possible for petpower to be retained without the focus item having to
// stay equipped when the character zones. petpower of -1 means that the currently equipped petfocus
// of a client is searched for and used instead.
void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
		const char *petname, float in_size) {
	// Sanity and early out checking first.
	if(HasPet() || pettype == nullptr)
		return;

	int16 act_power = 0; // The actual pet power we'll use.
	if (petpower == -1) {
		if (this->IsClient()) {
			act_power = CastToClient()->GetFocusEffect(focusPetPower, spell_id);//Client only
			act_power = CastToClient()->mod_pet_power(act_power, spell_id);
		}
#ifdef BOTS
		else if (this->IsBot())
			act_power = CastToBot()->GetBotFocusEffect(Bot::BotfocusPetPower, spell_id);
#endif
	}
	else if (petpower > 0)
		act_power = petpower;

	// optional rule: classic style variance in pets. Achieve this by
	// adding a random 0-4 to pet power, since it only comes in increments
	// of five from focus effects.

	//lookup our pets table record for this type
	PetRecord record;
	if(!database.GetPoweredPetEntry(pettype, act_power, &record)) {
		Message(13, "Unable to find data for pet %s", pettype);
		Log.Out(Logs::General, Logs::Error, "Unable to find data for pet %s, check pets table.", pettype);
		return;
	}

	//find the NPC data for the specified NPC type
	const NPCType *base = database.LoadNPCTypesData(record.npc_type);
	if(base == nullptr) {
		Message(13, "Unable to load NPC data for pet %s", pettype);
		Log.Out(Logs::General, Logs::Error, "Unable to load NPC data for pet %s (NPC ID %d), check pets and npc_types tables.", pettype, record.npc_type);
		return;
	}

	//we copy the npc_type data because we need to edit it a bit
	auto npc_type = new NPCType;
	memcpy(npc_type, base, sizeof(NPCType));

	// If pet power is set to -1 in the DB, use stat scaling
	if ((this->IsClient() 
#ifdef BOTS
		|| this->IsBot()
#endif
		) && record.petpower == -1)
	{
		float scale_power = (float)act_power / 100.0f;
		if(scale_power > 0)
		{
			npc_type->max_hp *= (1 + scale_power);
			npc_type->cur_hp = npc_type->max_hp;
			npc_type->AC *= (1 + scale_power);
			npc_type->level += 1 + ((int)act_power / 25) > npc_type->level + RuleR(Pets, PetPowerLevelCap) ? RuleR(Pets, PetPowerLevelCap) : 1 + ((int)act_power / 25); // gains an additional level for every 25 pet power
			npc_type->min_dmg = (npc_type->min_dmg * (1 + (scale_power / 2)));
			npc_type->max_dmg = (npc_type->max_dmg * (1 + (scale_power / 2)));
			npc_type->size = npc_type->size * (1 + (scale_power / 2)) > npc_type->size * 3 ? npc_type->size * 3 : npc_type-> size * (1 + (scale_power / 2));
		}
		record.petpower = act_power;
	}

	//Live AA - Elemental Durability
	int16 MaxHP = aabonuses.PetMaxHP + itembonuses.PetMaxHP + spellbonuses.PetMaxHP;

	if (MaxHP){
		npc_type->max_hp += (npc_type->max_hp*MaxHP)/100;
		npc_type->cur_hp = npc_type->max_hp;
	}

	//TODO: think about regen (engaged vs. not engaged)

	// Pet naming:
	// 0 - `s pet
	// 1 - `s familiar
	// 2 - `s Warder
	// 3 - Random name if client, `s pet for others
	// 4 - Keep DB name


	if (petname != nullptr) {
		// Name was provided, use it.
		strn0cpy(npc_type->name, petname, 64);
	} else if (record.petnaming == 0) {
		strcpy(npc_type->name, this->GetCleanName());
		npc_type->name[25] = '\0';
		strcat(npc_type->name, "`s_pet");
	} else if (record.petnaming == 1) {
		strcpy(npc_type->name, this->GetName());
		npc_type->name[19] = '\0';
		strcat(npc_type->name, "`s_familiar");
	} else if (record.petnaming == 2) {
		strcpy(npc_type->name, this->GetName());
		npc_type->name[21] = 0;
		strcat(npc_type->name, "`s_Warder");
	} else if (record.petnaming == 4) {
		// Keep the DB name
	} else if (record.petnaming == 3 && IsClient()) {
		strcpy(npc_type->name, GetRandPetName());
	} else {
		strcpy(npc_type->name, this->GetCleanName());
		npc_type->name[25] = '\0';
		strcat(npc_type->name, "`s_pet");
	}

	//handle beastlord pet appearance
	if(record.petnaming == 2)
	{
		switch(GetBaseRace())
		{
		case VAHSHIR:
			npc_type->race = TIGER;
			npc_type->size *= 0.8f;
			break;
		case TROLL:
			npc_type->race = ALLIGATOR;
			npc_type->size *= 2.5f;
			break;
		case OGRE:
			npc_type->race = BEAR;
			npc_type->texture = 3;
			npc_type->gender = 2;
			break;
		case BARBARIAN:
			npc_type->race = WOLF;
			npc_type->texture = 2;
			break;
		case IKSAR:
			npc_type->race = WOLF;
			npc_type->texture = 0;
			npc_type->gender = 1;
			npc_type->size *= 2.0f;
			npc_type->luclinface = 0;
			break;
		default:
			npc_type->race = WOLF;
			npc_type->texture = 0;
		}
	}

	// handle monster summoning pet appearance
	if(record.monsterflag) {

		uint32 monsterid = 0;

		// get a random npc id from the spawngroups assigned to this zone
		auto query = StringFormat("SELECT npcID "
									"FROM (spawnentry INNER JOIN spawn2 ON spawn2.spawngroupID = spawnentry.spawngroupID) "
									"INNER JOIN npc_types ON npc_types.id = spawnentry.npcID "
									"WHERE spawn2.zone = '%s' AND npc_types.bodytype NOT IN (11, 33, 66, 67) "
									"AND npc_types.race NOT IN (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 44, "
									"55, 67, 71, 72, 73, 77, 78, 81, 90, 92, 93, 94, 106, 112, 114, 127, 128, "
									"130, 139, 141, 183, 236, 237, 238, 239, 254, 266, 329, 330, 378, 379, "
									"380, 381, 382, 383, 404, 522) "
									"ORDER BY RAND() LIMIT 1", zone->GetShortName());
		auto results = database.QueryDatabase(query);
		if (!results.Success()) {
			safe_delete(npc_type);
			return;
		}

		if (results.RowCount() != 0) {
			auto row = results.begin();
			monsterid = atoi(row[0]);
		}

		// since we don't have any monsters, just make it look like an earth pet for now
		if (monsterid == 0)
			monsterid = 567;

		// give the summoned pet the attributes of the monster we found
		const NPCType* monster = database.LoadNPCTypesData(monsterid);
		if(monster) {
			npc_type->race = monster->race;
			npc_type->size = monster->size;
			npc_type->texture = monster->texture;
			npc_type->gender = monster->gender;
			npc_type->luclinface = monster->luclinface;
			npc_type->helmtexture = monster->helmtexture;
			npc_type->herosforgemodel = monster->herosforgemodel;
		} else
			Log.Out(Logs::General, Logs::Error, "Error loading NPC data for monster summoning pet (NPC ID %d)", monsterid);

	}

	//this takes ownership of the npc_type data
	auto npc = new Pet(npc_type, this, (PetType)record.petcontrol, spell_id, record.petpower);

	// Now that we have an actual object to interact with, load
	// the base items for the pet. These are always loaded
	// so that a rank 1 suspend minion does not kill things
	// like the special back items some focused pets may receive.
	uint32 petinv[EQEmu::legacy::EQUIPMENT_SIZE];
	memset(petinv, 0, sizeof(petinv));
	const EQEmu::ItemBase *item = 0;

	if (database.GetBasePetItems(record.equipmentset, petinv)) {
		for (int i = 0; i < EQEmu::legacy::EQUIPMENT_SIZE; i++)
			if (petinv[i]) {
				item = database.GetItem(petinv[i]);
				npc->AddLootDrop(item, &npc->itemlist, 0, 1, 127, true, true);
			}
	}

	npc->UpdateEquipmentLight();

	// finally, override size if one was provided
	if (in_size > 0.0f)
		npc->size = in_size;

	entity_list.AddNPC(npc, true, true);
	SetPetID(npc->GetID());
	// We need to handle PetType 5 (petHatelist), add the current target to the hatelist of the pet


	if (record.petcontrol == petTargetLock)
	{
		Mob* target = GetTarget();

		if (target){
			npc->AddToHateList(target, 1);
			npc->SetPetTargetLockID(target->GetID());
			npc->SetSpecialAbility(IMMUNE_AGGRO, 1);
		}
		else
			npc->Kill(); //On live casts spell 892 Unsummon (Kayen - Too limiting to use that for emu since pet can have more than 20k HP)
	}
}
Beispiel #20
0
	~OutBuffer()
	{
		safe_delete(m_szBuffer);
	}
Beispiel #21
0
bool Group::AddMember(Mob* newmember, const char *NewMemberName, uint32 CharacterID)
{
	bool InZone = true;

	// This method should either be passed a Mob*, if the new member is in this zone, or a nullptr Mob*
	// and the name and CharacterID of the new member, if they are out of zone.
	//
	if (!newmember && !NewMemberName)
		return false;

	if (GroupCount() >= MAX_GROUP_MEMBERS) //Sanity check for merging groups together.
		return false;

	if (!newmember)
		InZone = false;
	else
	{
		NewMemberName = newmember->GetCleanName();

		if (newmember->IsClient())
			CharacterID = newmember->CastToClient()->CharacterID();
	}

	uint32 i = 0;

	// See if they are already in the group
	//
	for (i = 0; i < MAX_GROUP_MEMBERS; ++i)
		if (!strcasecmp(membername[i], NewMemberName))
			return false;

	// Put them in the group
	for (i = 0; i < MAX_GROUP_MEMBERS; ++i)
	{
		if (membername[i][0] == '\0')
		{
			if (InZone)
				members[i] = newmember;

			break;
		}
	}

	if (i == MAX_GROUP_MEMBERS)
		return false;

	strcpy(membername[i], NewMemberName);
	MemberRoles[i] = 0;

	int x = 1;

	//build the template join packet
	EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
	GroupJoin_Struct* gj = (GroupJoin_Struct*)outapp->pBuffer;
	strcpy(gj->membername, NewMemberName);
	gj->action = groupActJoin;

	for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
		if (members[i] != nullptr && members[i] != newmember) {
			//fill in group join & send it
			strcpy(gj->yourname, members[i]->GetCleanName());
			if (members[i]->IsClient()) {
				members[i]->CastToClient()->QueuePacket(outapp);

				//put new member into existing person's list
				strcpy(members[i]->CastToClient()->GetPP().groupMembers[this->GroupCount() - 1], NewMemberName);
			}

			//put this existing person into the new member's list
			if (InZone && newmember->IsClient()) {
				if (IsLeader(members[i]))
					strcpy(newmember->CastToClient()->GetPP().groupMembers[0], members[i]->GetCleanName());
				else {
					strcpy(newmember->CastToClient()->GetPP().groupMembers[x], members[i]->GetCleanName());
					x++;
				}
			}
		}
	}

	if (InZone)
	{
		//put new member in his own list.
		newmember->SetGrouped(true);

		if (newmember->IsClient())
		{
			strcpy(newmember->CastToClient()->GetPP().groupMembers[x], NewMemberName);
			newmember->CastToClient()->Save();
			database.SetGroupID(NewMemberName, GetID(), newmember->CastToClient()->CharacterID());
		}
	}
	else
		database.SetGroupID(NewMemberName, GetID(), CharacterID);

	safe_delete(outapp);

	return true;
}
Beispiel #22
0
	MOpcodeMesh::~MOpcodeMesh()
	{
		safe_delete (mCollisionModel);
	}
Beispiel #23
0
SFTWorker::~SFTWorker()
{
	stop();
	safe_delete(m_pBzs);
}
Beispiel #24
0
/////////////////
// Destroy accelerators
//
void CCoolMenuManager::DestroyAccel()
{
	m_mapIDtoAccel.RemoveAll();		// delete ACCEL entries in map
	safe_delete(m_pAccel);			// delete current accelerators
}
Beispiel #25
0
PGTaskMgr::~PGTaskMgr() {
    std::for_each(m_Task.begin(), m_Task.end(), safe_delete());
    m_Task.clear();
}
Beispiel #26
0
void ZSList::SendZoneStatus(const char* to, sint16 admin, WorldTCPConnection* connection) {
	LinkedListIterator<ZoneServer*> iterator(list);
	struct in_addr  in;
	
	iterator.Reset();
	char locked[4];
	if (WorldConfig::get()->Locked == true)
		strcpy(locked, "Yes");
	else
		strcpy(locked, "No");

	char* output = 0;
	int32 outsize = 0, outlen = 0;
	if (connection->IsConsole())
		AppendAnyLenString(&output, &outsize, &outlen, "World Locked: %s\r\n", locked);
	else
		AppendAnyLenString(&output, &outsize, &outlen, "World Locked: %s^", locked);
	if (connection->IsConsole())
		AppendAnyLenString(&output, &outsize, &outlen, "Zoneservers online:\r\n");
	else
		AppendAnyLenString(&output, &outsize, &outlen, "Zoneservers online:^");
//	connection->SendEmoteMessage(to, 0, 0, 0, "World Locked: %s", locked);
//	connection->SendEmoteMessage(to, 0, 0, 0, "Zoneservers online:");
	int v=0, w=0, x=0, y=0, z=0;
	char tmpStatic[2] = { 0, 0 }, tmpZone[64];
	memset(tmpZone, 0, sizeof(tmpZone));
	ZoneServer* zs = 0;
	while(iterator.MoreElements()) {
		zs = iterator.GetData();
		in.s_addr = zs->GetIP();

		if(zs->IsStaticZone())
			z++;
		else if (zs->GetZoneID() != 0)
			w++;
		else if(zs->GetZoneID() == 0 && !zs->IsBootingUp())
			v++;

		if (zs->IsStaticZone())
			tmpStatic[0] = 'S';
		else
			tmpStatic[0] = ' ';

		if (admin >= 150) {
			if (zs->GetZoneID())
				snprintf(tmpZone, sizeof(tmpZone), "%s (%i)", zs->GetZoneName(), zs->GetZoneID());
			else if (zs->IsBootingUp())
				strcpy(tmpZone, "...");
			else
				tmpZone[0] = 0;

			AppendAnyLenString(&output, &outsize, &outlen, "  #%-3i %s %15s:%-5i %2i  %s:%i  %s", zs->GetID(), tmpStatic, inet_ntoa(in), zs->GetPort(), zs->NumPlayers(), zs->GetCAddress(), zs->GetCPort(), tmpZone);
			if (outlen >= 3584) {
				connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
				safe_delete(output);
				outsize = 0;
				outlen = 0;
			}
			else {
				if (connection->IsConsole())
					AppendAnyLenString(&output, &outsize, &outlen, "\r\n");
				else
					AppendAnyLenString(&output, &outsize, &outlen, "^");
			}
			x++;
		}
		else if (zs->GetZoneID() != 0) {
			if (zs->GetZoneID())
				strcpy(tmpZone, zs->GetZoneName());
			else
				tmpZone[0] = 0;
			AppendAnyLenString(&output, &outsize, &outlen, "  #%i %s  %s", zs->GetID(), tmpStatic, tmpZone);
			if (outlen >= 3584) {
				connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
				safe_delete(output);
				outsize = 0;
				outlen = 0;
			}
			else {
				if (connection->IsConsole())
					AppendAnyLenString(&output, &outsize, &outlen, "\r\n");
				else
					AppendAnyLenString(&output, &outsize, &outlen, "^");
			}
			x++;
		}
		y++;
		iterator.Advance();
	}
	if (connection->IsConsole())
		AppendAnyLenString(&output, &outsize, &outlen, "%i servers listed. %i servers online.\r\n", x, y);
	else
		AppendAnyLenString(&output, &outsize, &outlen, "%i servers listed. %i servers online.^", x, y);
	AppendAnyLenString(&output, &outsize, &outlen, "%i zones are static zones, %i zones are booted zones, %i zones available.",z,w,v);
//	connection->SendEmoteMessage(to, 0, 0, "%i servers listed. %i servers online.", x, y);
//	connection->SendEmoteMessage(to,0,0,"%i zones are static zones, %i zones are booted zones, %i zones available.",z,w,v);
	if (output)
		connection->SendEmoteMessageRaw(to, 0, 0, 10, output);
	safe_delete(output);
}
Beispiel #27
0
CIPManager::~CIPManager()
{
	safe_delete(m_pThread);
}
Beispiel #28
0
MenuSeperator::~MenuSeperator()
{
	safe_delete(m_imgBG);
}
Beispiel #29
0
HGTController::~HGTController()
{
	safe_delete(m_vSuperBlockList);
}
Beispiel #30
0
ToolTransInfo::~ToolTransInfo()
{
	safe_delete(m_pTransaction);
}