View Single Post
  #9  
Old 01-05-2018, 10:53 PM
Minirva
Fire Beetle
 
Join Date: Nov 2012
Posts: 19
Default

Just wondering if I am on the correct path to understanding some of this. Sorry that the code snippet is so long.

Code:
	void Client::SendBazaarResults(uint32 TraderID, uint32 Class_, uint32 Race, uint32 ItemStat, uint32 Slot, uint32 Type,
					char Name[64], uint32 MinPrice, uint32 MaxPrice) {

	std::string searchValues = " COUNT(item_id), trader.*, items.name ";
	std::string searchCriteria = " WHERE trader.item_id = items.id ";

	if(TraderID > 0) {
		Client* trader = entity_list.GetClientByID(TraderID);

		if(trader)
			searchCriteria.append(StringFormat(" AND trader.char_id = %i", trader->CharacterID()));
	}

	if(MinPrice != 0)
		searchCriteria.append(StringFormat(" AND trader.item_cost >= %i", MinPrice));

	if(MaxPrice != 0)
		searchCriteria.append(StringFormat(" AND trader.item_cost <= %i", MaxPrice));

	if(strlen(Name) > 0) {
		char *safeName = RemoveApostrophes(Name);
		searchCriteria.append(StringFormat(" AND items.name LIKE '%%%s%%'", safeName));
		safe_delete_array(safeName);
	}

	if(Class_ != 0xFFFFFFFF)
		searchCriteria.append(StringFormat(" AND MID(REVERSE(BIN(items.classes)), %i, 1) = 1", Class_));

	if(Race != 0xFFFFFFFF)
		searchCriteria.append(StringFormat(" AND MID(REVERSE(BIN(items.races)), %i, 1) = 1", Race));

	if(Slot != 0xFFFFFFFF)
		searchCriteria.append(StringFormat(" AND MID(REVERSE(BIN(items.slots)), %i, 1) = 1", Slot + 1));

	switch(Type){
        case 0xFFFFFFFF:
            break;
        case 0:
            // 1H Slashing
            searchCriteria.append(" AND items.itemtype = 0 AND damage > 0");
            break;
        case 31:
            searchCriteria.append(" AND items.itemclass = 2");
            break;
        case 46:
            searchCriteria.append(" AND items.spellid > 0 AND items.spellid < 65000");
            break;
        case 47:
            searchCriteria.append(" AND items.spellid = 998");
            break;
        case 48:
            searchCriteria.append(" AND items.spellid >= 1298 AND items.spellid <= 1307");
            break;
        case 49:
            searchCriteria.append(" AND items.focuseffect > 0");
            break;

        default:
            searchCriteria.append(StringFormat(" AND items.itemtype = %i", Type));
    }

	switch(ItemStat) {

		case STAT_AC:
			searchCriteria.append(" AND items.ac > 0");
			searchValues.append(", items.ac");
			break;

		case STAT_AGI:
			searchCriteria.append(" AND items.aagi > 0");
			searchValues.append(", items.aagi");
			break;

		case STAT_CHA:
			searchCriteria.append(" AND items.acha > 0");
			searchValues.append(", items.acha");
			break;

		case STAT_DEX:
			searchCriteria.append(" AND items.adex > 0");
			searchValues.append(", items.adex");
			break;

		case STAT_INT:
			searchCriteria.append(" AND items.aint > 0");
			searchValues.append(", items.aint");
			break;

		case STAT_STA:
			searchCriteria.append(" AND items.asta > 0");
			searchValues.append(", items.asta");
			break;

		case STAT_STR:
			searchCriteria.append(" AND items.astr > 0");
			searchValues.append(", items.astr");
			break;

		case STAT_WIS:
			searchCriteria.append(" AND items.awis > 0");
			searchValues.append(", items.awis");
			break;

		case STAT_COLD:
			searchCriteria.append(" AND items.cr > 0");
			searchValues.append(", items.cr");
			break;

		case STAT_DISEASE:
			searchCriteria.append(" AND items.dr > 0");
			searchValues.append(", items.dr");
			break;

		case STAT_FIRE:
			searchCriteria.append(" AND items.fr > 0");
			searchValues.append(", items.fr");
			break;

		case STAT_MAGIC:
            searchCriteria.append(" AND items.mr > 0");
			searchValues.append(", items.mr");
			break;

		case STAT_POISON:
			searchCriteria.append(" AND items.pr > 0");
			searchValues.append(", items.pr");
			break;

		case STAT_HP:
			searchCriteria.append(" AND items.hp > 0");
			searchValues.append(", items.hp");
			break;

		case STAT_MANA:
			searchCriteria.append(" AND items.mana > 0");
			searchValues.append(", items.mana");
			break;

		case STAT_ENDURANCE:
			searchCriteria.append(" AND items.endur > 0");
			searchValues.append(", items.endur");
			break;

		case STAT_ATTACK:
			searchCriteria.append(" AND items.attack > 0");
			searchValues.append(", items.attack");
			break;

		case STAT_HP_REGEN:
			searchCriteria.append(" AND items.regen > 0");
			searchValues.append(", items.regen");
			break;

		case STAT_MANA_REGEN:
			searchCriteria.append(" AND items.manaregen > 0");
			searchValues.append(", items.manaregen");
			break;

		case STAT_HASTE:
			searchCriteria.append(" AND items.haste > 0");
			searchValues.append(", items.haste");
			break;

		case STAT_DAMAGE_SHIELD:
			searchCriteria.append(" AND items.damageshield > 0");
			searchValues.append(", items.damageshield");
			break;

		default:
			searchValues.append(", 0");
			break;
	}

    std::string query = StringFormat("SELECT %s, SUM(charges), items.stackable "
                                    "FROM trader, items %s GROUP BY items.id, charges, char_id LIMIT %i",
                                    searchValues.c_str(), searchCriteria.c_str(), RuleI(Bazaar, MaxSearchResults));
    auto results = database.QueryDatabase(query);
    if (!results.Success()) {
		return;
    }

    Log(Logs::Detail, Logs::Trading, "SRCH: %s", query.c_str());

    int Size = 0;
    uint32 ID = 0;

    if (results.RowCount() == static_cast<unsigned long>(RuleI(Bazaar, MaxSearchResults)))
			Message(15, "Your search reached the limit of %i results. Please narrow your search down by selecting more options.",
					RuleI(Bazaar, MaxSearchResults));

    if(results.RowCount() == 0) {
	    auto outapp2 = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarReturnDone_Struct));
	    BazaarReturnDone_Struct *brds = (BazaarReturnDone_Struct *)outapp2->pBuffer;
	    brds->TraderID = ID;
	    brds->Type = BazaarSearchDone;
	    brds->Unknown008 = 0xFFFFFFFF;
	    brds->Unknown012 = 0xFFFFFFFF;
	    brds->Unknown016 = 0xFFFFFFFF;
	    this->QueuePacket(outapp2);
	    safe_delete(outapp2);
	    return;
	}

    Size = results.RowCount() * sizeof(BazaarSearchResults_Struct);
    auto buffer = new uchar[Size];
    uchar *bufptr = buffer;
    memset(buffer, 0, Size);

    int Action = BazaarSearchResults;
    uint32 Cost = 0;
    int32 SerialNumber = 0;
    char temp_buffer[64] = {0};
    int Count = 0;
    uint32 StatValue = 0;

    for (auto row = results.begin(); row != results.end(); ++row) {
	    VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Action);
	    Count = atoi(row[0]);
	    VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Count);
	    SerialNumber = atoi(row[3]);
	    VARSTRUCT_ENCODE_TYPE(int32, bufptr, SerialNumber);
	    Client *Trader2 = entity_list.GetClientByCharID(atoi(row[1]));
	    if (Trader2) {
		    ID = Trader2->GetID();
		    VARSTRUCT_ENCODE_TYPE(uint32, bufptr, ID);
	    } else {
		    Log(Logs::Detail, Logs::Trading, "Unable to find trader: %i\n", atoi(row[1]));
		    VARSTRUCT_ENCODE_TYPE(uint32, bufptr, 0);
	    }
	    Cost = atoi(row[5]);
	    VARSTRUCT_ENCODE_TYPE(uint32, bufptr, Cost);
	    StatValue = atoi(row[8]);
	    VARSTRUCT_ENCODE_TYPE(uint32, bufptr, StatValue);
	    bool Stackable = atoi(row[10]);
	    if (Stackable) {
		    int Charges = atoi(row[9]);
		    sprintf(temp_buffer, "%s(%i)", row[7], Charges);
	    } else
		    sprintf(temp_buffer, "%s(%i)", row[7], Count);

	    memcpy(bufptr, &temp_buffer, strlen(temp_buffer));

	    bufptr += 64;

	    // Extra fields for SoD+
	    //
	    if (Trader2)
		    sprintf(temp_buffer, "%s", Trader2->GetName());
	    else
		    sprintf(temp_buffer, "Unknown");

	    memcpy(bufptr, &temp_buffer, strlen(temp_buffer));

	    bufptr += 64;

	    VARSTRUCT_ENCODE_TYPE(uint32, bufptr, atoi(row[1])); // ItemID
    }

    auto outapp = new EQApplicationPacket(OP_BazaarSearch, Size);

    memcpy(outapp->pBuffer, buffer, Size);

    this->QueuePacket(outapp);

    safe_delete(outapp);
    safe_delete_array(buffer);

    auto outapp2 = new EQApplicationPacket(OP_BazaarSearch, sizeof(BazaarReturnDone_Struct));
    BazaarReturnDone_Struct *brds = (BazaarReturnDone_Struct *)outapp2->pBuffer;

    brds->TraderID = ID;
    brds->Type = BazaarSearchDone;

    brds->Unknown008 = 0xFFFFFFFF;
    brds->Unknown012 = 0xFFFFFFFF;
    brds->Unknown016 = 0xFFFFFFFF;

    this->QueuePacket(outapp2);

    safe_delete(outapp2);
}
Does void basically cancel out this whole function then? And by removing void it allows all the information in the function to be sent to the client (or vice versa?)? And am I correct that all of that is actually one function?
Reply With Quote