LCKB
Send struct with dinamic size inside of other struct - Printable Version

+- LCKB (https://lckb.dev/forum)
+-- Forum: ** OLD LCKB DATABASE ** (https://lckb.dev/forum/forumdisplay.php?fid=109)
+--- Forum: Guides & Help Section (https://lckb.dev/forum/forumdisplay.php?fid=193)
+---- Forum: Help & Support (https://lckb.dev/forum/forumdisplay.php?fid=157)
+----- Forum: Ep4 Support (https://lckb.dev/forum/forumdisplay.php?fid=128)
+----- Thread: Send struct with dinamic size inside of other struct (/showthread.php?tid=5044)



- nicolasg - 04-29-2023


Hello, I am trying to modify the existing merchant system, specifically I want to send an array with some data, in addition to the data that was originally sent...

This is the struct with the changes

// NICOLASG MARK (AUCTIONS) // Testing
struct TradeAgentBiddersList {
int bid_pos;
int bidder_job;
char bidder_charName[MAX_ID_NAME_LENGTH];
int bid_value;

TradeAgentBiddersList() {
bid_pos = 0;
bidder_job = 0;
strcpy(bidder_charName, "\0");
bid_value = 0;
}
};
// NICOLASG MARK END

struct TradeAgentItem {
tradeAgentIndex_t index; // °íÀ¯ ¹øÈ£
int item_index;
unsigned char plus; // °­È­ ¼öÄ¡
unsigned char plus2; // Ãß°¡ ¼öÄ¡
int flag;
char serial[MAX_SERIAL_LENGTH + 1];
int item_jobclass;
int quantity;
int option_count;
int option_type[MAX_ITEM_OPTION];
int option_level[MAX_ITEM_OPTION];
int socketCount;
int socket[MAX_SOCKET_COUNT];
int item_origin[MAX_ORIGIN_OPTION];
GoldType_t nas;
int regist_date;
int expire_date;
int item_num0; //¾ÆÀÌÅÛ ¹°¸®°ø°Ý·Â
int item_num1; //¾ÆÀÌÅÛ ¸¶¹ý°ø°Ý·Â
int item_level;
int rareGrade;
char sell_charName[MAX_ID_NAME_LENGTH]; //MAX_ID_NAME_LENGTH = 64
#ifdef DURABILITY
int now_durability;
int max_durability;
#endif
// NICOLASG MARK (AUCTIONS) // Testing
int bidsListCount;
TradeAgentBiddersList* bidsList;
// NICOLASG MARK END

TradeAgentItem() {
memset(this, 0x00, sizeof(*this));
memset(this->socket, -1, sizeof(this->socket));

#ifdef DURABILITY
now_durability = 0;
max_durability = 0;
#endif
}
};

And this is the part of the code where I populate the package with the information

size_t BidsListSize = 0; // NICOLASG MARK (AUCTIONS)

for (int i = 0; i < packet->count; i++) {
cmd.GetRec("a_index", packet->list.index);
cmd.GetRec("a_item_serial", packet->list[i].item_index);
cmd.GetRec("a_item_plus", packet->list[i].plus);
cmd.GetRec("a_item_plus2", packet->list[i].plus2);
cmd.GetRec("a_item_flag", packet->list[i].flag);
cmd.GetRec("a_option_count", packet->list[i].option_count);
cmd.GetRec("a_option_0_type", packet->list[i].option_type[0]);
cmd.GetRec("a_option_0_level", packet->list[i].option_level[0]);
cmd.GetRec("a_option_1_type", packet->list[i].option_type[1]);
cmd.GetRec("a_option_1_level", packet->list[i].option_level[1]);
cmd.GetRec("a_option_2_type", packet->list[i].option_type[2]);
cmd.GetRec("a_option_2_level", packet->list[i].option_level[2]);
cmd.GetRec("a_option_3_type", packet->list[i].option_type[3]);
cmd.GetRec("a_option_3_level", packet->list[i].option_level[3]);
cmd.GetRec("a_option_4_type", packet->list[i].option_type[4]);
cmd.GetRec("a_option_4_level", packet->list[i].option_level[4]);
cmd.GetRec("a_quantity", packet->list[i].quantity);
cmd.GetRec("a_totalmoney", packet->list[i].nas);
cmd.GetRec("a_item_level", packet->list[i].item_level);
cmd.GetRec("a_item_origin_0", packet->list[i].item_origin[0]);
cmd.GetRec("a_item_origin_1", packet->list[i].item_origin[1]);
cmd.GetRec("a_item_origin_2", packet->list[i].item_origin[2]);
cmd.GetRec("a_item_origin_3", packet->list[i].item_origin[3]);
cmd.GetRec("a_item_origin_4", packet->list[i].item_origin[4]);
cmd.GetRec("a_item_origin_5", packet->list[i].item_origin[5]);
cmd.GetRec("a_socketCount", packet->list[i].socketCount);
cmd.GetRec("a_socket0", packet->list[i].socket[0]);
cmd.GetRec("a_socket1", packet->list[i].socket[1]);
cmd.GetRec("a_socket2", packet->list[i].socket[2]);
cmd.GetRec("a_socket3", packet->list[i].socket[3]);
cmd.GetRec("a_socket4", packet->list[i].socket[4]);
cmd.GetRec("a_socket5", packet->list[i].socket[5]);
cmd.GetRec("a_socket6", packet->list[i].socket[6]);
#ifdef DURABILITY
cmd.GetRec("a_now_dur", packet->list[i].now_durability);
cmd.GetRec("a_max_dur", packet->list[i].max_durability);
#endif
cmd.GetRec("a_num0", packet->list[i].item_num0);
cmd.GetRec("a_num1", packet->list[i].item_num1);
cmd.GetRec("regist_date", packet->list[i].regist_date);
cmd.GetRec("expire_date", packet->list[i].expire_date);

// NICOLASG MARK (AUCTIONS)
if (p->SellType == 1) {
sprintf(sql, "SELECT a_bid_pos, a_bidder_job, a_bidder_name, a_bidder_bid, a_show_name FROM t_tradeagent_auctions_history WHERE a_auction_index=%d", packet->list[i].index);
CDBCmd cmdHistory;
cmdHistory.Init(&gserver.m_dbchar);
cmdHistory.SetQuery(sql);

if (cmdHistory.Open()) {
int ListCount = cmdHistory.m_nrecords;

if (ListCount > 0) {
packet->list[i].bidsListCount = ListCount;
packet->list[i].bidsList = new TradeAgentBiddersList[ListCount];

int k = 0;

while (cmdHistory.MoveNext()) {
cmdHistory.GetRec("a_bid_pos", packet->list[i].bidsList[k].bid_pos);
cmdHistory.GetRec("a_bidder_job", packet->list[i].bidsList[k].bidder_job);

// TODO: if show name is 0
CLCString sell_charName(MAX_ID_NAME_LENGTH);
cmdHistory.GetRec("a_bidder_name", sell_charName);
strcpy(packet->list[i].bidsList[k].bidder_charName, (const char*)sell_charName);

cmdHistory.GetRec("a_bidder_bid", packet->list[i].bidsList[k].bid_value);

k++;
}

BidsListSize += sizeof(TradeAgentBiddersList) * k;
} else {
LOG_INFO("NICOLASG - No bids yet");

packet->list[i].bidsListCount = 0;
//packet->list[i].bidsList = NULL;

BidsListSize += sizeof(TradeAgentBiddersList);
}
} else {
LOG_INFO("NICOLASG - Bids listing for Auction:%d not found", packet->list[i].index);

packet->list[i].bidsListCount = 0;
//packet->list[i].bidsList = NULL;

BidsListSize += sizeof(TradeAgentBiddersList);
}
} else {
LOG_INFO("NICOLASG - Is not Auctions list request");

packet->list[i].bidsListCount = 0;
//packet->list[i].bidsList = NULL;

BidsListSize += sizeof(TradeAgentBiddersList);
}
// NICOLASG MARK END

cmd.MoveNext();
}

rmsg->setSize(sizeof(ResponseClient::TradeAgentSystemList) + (packet->count * sizeof(TradeAgentItem)) + BidsListSize); // NICOLASG MARK (AUCTIONS) OG: rmsg->setSize(sizeof(ResponseClient::TradeAgentSystemList) + (packet->count * sizeof(TradeAgentItem)));
SEND_Q(rmsg, desc);

My question is the following, so far have I done things correctly or am I a disaster? Also, is it possible to "retrieve" the structure: TradeAgentBiddersList once the package is delivered to the client?

To provide more information to contribute to an answer, this is the code I have modified on the client side

ResponseClient::TradeAgentSystemList* pPack = reinterpret_cast<ResponseClient::TradeAgentSystemList*>(istr->GetBuffer());

clearSearchList();

m_sCurPage = pPack->pageNo;
m_ucNextPage = pPack->nextPage;
m_nServerTime = pPack->curServerTime;

if (pPack->count > 0) {
m_nSearchCount = pPack->count;
m_pSearchList = new TradeAgentItem[pPack->count];

// NICOLASG MARK (AUCTIONS)
for (int i = 0; i < pPack->count; i++) {
m_pSearchList[i].index = pPack->list[i].index;
m_pSearchList[i].item_index = pPack->list[i].item_index;
m_pSearchList[i].plus = pPack->list[i].plus;
m_pSearchList[i].plus2 = pPack->list[i].plus2;
m_pSearchList[i].flag = pPack->list[i].flag;
strncpy(m_pSearchList[i].serial, pPack->list[i].serial, MAX_SERIAL_LENGTH);
m_pSearchList[i].item_jobclass = pPack->list[i].item_jobclass;
m_pSearchList[i].quantity = pPack->list[i].quantity;
m_pSearchList[i].option_count = pPack->list[i].option_count;
memcpy(m_pSearchList[i].option_type, pPack->list[i].option_type, sizeof(pPack->list[i].option_type));
memcpy(m_pSearchList[i].option_level, pPack->list[i].option_level, sizeof(pPack->list[i].option_level));
m_pSearchList[i].socketCount = pPack->list[i].socketCount;
memcpy(m_pSearchList[i].socket, pPack->list[i].socket, sizeof(pPack->list[i].socket));
memcpy(m_pSearchList[i].item_origin, pPack->list[i].item_origin, sizeof(pPack->list[i].item_origin));
m_pSearchList[i].nas = pPack->list[i].nas;
m_pSearchList[i].regist_date = pPack->list[i].regist_date;
m_pSearchList[i].expire_date = pPack->list[i].expire_date;
m_pSearchList[i].item_num0 = pPack->list[i].item_num0;
m_pSearchList[i].item_num1 = pPack->list[i].item_num1;
m_pSearchList[i].item_level = pPack->list[i].item_level;
m_pSearchList[i].rareGrade = pPack->list[i].rareGrade;
strncpy(m_pSearchList[i].sell_charName, pPack->list[i].sell_charName, MAX_ID_NAME_LENGTH);
#ifdef DURABILITY
m_pSearchList[i].now_durability = pPack->list[i].now_durability;
m_pSearchList[i].max_durability = pPack->list[i].max_durability;
#endif
int ListCount = pPack->list[i].bidsListCount;

if (ListCount > 0) {
m_pSearchList[i].bidsListCount = ListCount;
m_pSearchList[i].bidsList = new TradeAgentBiddersList[ListCount];
for (int k = 0; k < ListCount; k++) {
m_pSearchList[i].bidsList[k].bid_pos = pPack->list[i].bidsList[k].bid_pos;
m_pSearchList[i].bidsList[k].bidder_job = pPack->list[i].bidsList[k].bidder_job;
//strncpy(m_pSearchList[i].bidsList[k].bidder_charName, pPack->list[i].bidsList[k].bidder_charName, MAX_ID_NAME_LENGTH);
strcpy(m_pSearchList[i].bidsList[k].bidder_charName, pPack->list[i].bidsList[k].bidder_charName);
m_pSearchList[i].bidsList[k].bid_value = pPack->list[i].bidsList[k].bid_value;
}
} else {
m_pSearchList[i].bidsListCount = 0;
m_pSearchList[i].bidsList = new TradeAgentBiddersList;
//m_pSearchList[i].bidsList = NULL;
}
}
// Original
// memcpy(m_pSearchList, pPack->list, sizeof(TradeAgentItem) * pPack->count);
// NICOLASG MARK END

My client crashes when executing the line: m_pSearchList[i].bidsList[k].bidder_job = pPack->list
[i].bidsList[k].bidder_job;, so I understand that something is wrong with the package...
[/i]

[i]
[/i]