Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements and fixes for market transactions; code quality improvements #291

Merged

Conversation

charles-m-knox
Copy link

@charles-m-knox charles-m-knox commented Sep 11, 2024

Summary:

This pull request implements more expected behaviors when doing market transactions. It also implements more support for the NPC traders mentioned throughout the codebase.

It also fixes #96 and #80:

2024-09-11-142651_902x335_scrot

2024-09-11-142700_904x316_scrot

Additionally, it renames TranserFunds to TransferFunds, and offers a series of simple code formatting and legibility improvements.

Also, please accept my apologies for the significant number of files changed in this PR. I usually try to keep it slim, but this one touched upon a few different areas in the codebase. You'll primarily want to review MarketProxyService.cpp, MarketMgr.cpp, and MarketDB.cpp - almost everything else is unchanged aside from formatting/legibility.


More context/details:

One of my goals with evemu has been to seed the market with reasonable buyer and seller activity on the market. During code exploration, I discovered reserved trader NPC character IDs including trader joe. I began to seed the market with bidders across different regions using SQL statements, but shortly discovered that market transactions were not behaving as expected. This led me down the rabbit hole that eventually turned into this pull request today.

So - in my experience, during normal usage, I've encountered a few issues regarding market transactions:

  1. If a buyer is bidding for 1000 of an item, and you opt to sell 1 item, the code currently will loop and create tons of transactions until the stack is empty. This is different from the expected behavior, where only one sale of one item would have occurred.
  2. Market transactions show values of 0 for transactions. Wallet transactions show 0 quantity and 0 credit #96
  3. Market transactions always show yourself as the client. Market Transaction window shows that you're always self-dealing #80

The evemu codebase has scattered mentions of "Trader Joe" as well as a range of character ID ranges from 4xxx-5xxxx that allow trader NPC's to essentially "create" market activity. This pull request fleshes out that logic and it seems stable so far on my system.

In order to get NPC traders to work properly within the wallet transactions view, any time a trader NPC's client ID is detected in MarketDB::GetTransactions, it is swapped with the current player's ID (only when being sent to the game client) so that the game client's subsequent lookups to resolve information about the entity succeed. Without this step, the server fails to lookup an entity for the trader NPCs and throws an exception. We could discuss better options for this - for example, seeding the database with trader NPCs could possibly help. The actual trader NPC character ID is stored in the database as expected.

As part of this implementation, I found that characterID (or memberID) for market transactions in the DB was intended to be reserved for corporation transactions. However, the reason for #80 is because each market transaction in the DB does not have an "owner" currently, it only has the clientID. I found that there was sufficient room to leverage simple ternary statements (many already existed actually) to determine if an entity is part of a corporation or not using the isCorp flags present in the DB - if no corp, then the characterID for the market transaction is set to the player's ID, as expected. This allows a proper market transaction history to be associated with an actual character, while still leaving room for corporation-specific logic to exist in the future.

2024-09-11-144208_1498x199_scrot

In the above screenshot, you can see the before/after behavior - characterID is 0 before, and after, it is now associated with an actual character.

Testing

To seed the market, I ran the following SQL - please note that this will delete all market orders in the entire db, as well as resetting the market seed migrations. You'll notice that this is a slightly modified version of the standard market seeding SQL query that ships with the codebase.

This SQL code essentially seeds the market with sellers and buyers. Bidders place orders at a rate of 3% less than the sell to create a profit margin for the buyer, which somewhat emulates a real marketplace.

Expand here to see SQL that you can copy/paste
truncate table mktOrders;
truncate table seed_migrations;

use evemu;   -- set this to your db name
-- seeds specified regionID
-- some region ids found in seed_data.sql

set @regionid=10000002; -- the forge
set @saturation=0.1; -- fuzzy logic.  % of stations to fill with orders (random selection)
set @issued=133702393558877328;
set @buyqty=1000000;
set @bidratio=0.97;
set @bidder=4000001; -- trader npc id

-- select stations to fill
create temporary table if not exists tStations (stationId int, solarSystemID int, regionID int, corporationID int, security float);
truncate table tStations;
select round(count(stationID)*@saturation) into @lim from staStations where regionID=@regionid ;
set @i=0;
insert into tStations
  select stationID,solarSystemID,regionID, corporationID, security from staStations where (@i:=@i+1)<=@lim AND regionID=@regionid  order by rand();

-- automated buy orders are also seeded at a loss of 3% always, this allows
-- the game to have an interactive market
INSERT INTO mktOrders (typeID, ownerID, regionID, stationID, orderRange, bid, price, escrow, volEntered, volRemaining, issued,
minVolume, duration, solarSystemID, jumps)
  SELECT typeID, @bidder, regionID, stationID, 0, 1, (basePrice) * @bidratio, (basePrice) * @bidratio * @buyqty, @buyqty, @buyqty, @issued, 1, 90, solarSystemID, 1
  FROM tStations, invTypes inner join invGroups USING (groupID)
  WHERE invTypes.published = 1
  AND invGroups.categoryID IN (4, 5, 6, 7, 8, 9, 16, 17, 18, 22, 23, 24, 25, 32, 34, 35, 39, 40, 41, 42, 43, 46);
-- UPDATE mktOrders SET price = 100 WHERE price = 0;
UPDATE mktOrders SET escrow = 100 WHERE escrow = 0;

-- automated sell orders
INSERT INTO mktOrders (typeID, ownerID, regionID, stationID, price, volEntered, volRemaining, issued,
minVolume, duration, solarSystemID, jumps)
  SELECT typeID, corporationID, regionID, stationID, basePrice, 550, 550, @issued, 1, 250, solarSystemID, 1
  FROM tStations, invTypes inner join invGroups USING (groupID)
  WHERE invTypes.published = 1
  AND invGroups.categoryID IN (4, 5, 6, 7, 8, 9, 16, 17, 18, 22, 23, 24, 25, 32, 34, 35, 39, 40, 41, 42, 43, 46);
UPDATE mktOrders SET price = 100 WHERE price = 0;

insert into seed_migrations (id, applied_at)  values (1, '2024-09-07 17:09:51');

Test cases

Here are the test cases I did. Where appropriate, I used immediate orders as well as orders of a non-zero duration and fulfilled them on two accounts.

  • player buys from static NPC corp
    • market transaction in player's wallet
    • journal transaction in player's wallet
  • player sells to trader NPC (but not necessarily trader joe)
    • market transaction in player's wallet
    • journal transaction in player's wallet
  • player buys from another player
    • market transaction in seller's wallet
    • journal transaction in seller's wallet
    • market transaction in buyer's wallet
    • journal transaction in buyer's wallet

Corporation transactions are out of scope and are untested due to the fact that the code explicitly forbids a character from doing a corporation transaction at this time.


Other notes

While making these changes, I found that market results are still cached and do not invalidate upon submitting an order. I wasn't able to figure this one out without increasing the scope of this PR, unfortunately.

Summary by Sourcery

Improve market transaction handling by adding support for NPC traders, fixing transaction value and client display issues, and enhancing transaction logic to prevent excessive loops. Rename TranserFunds to TransferFunds and improve code formatting for better readability.

New Features:

  • Implement support for NPC traders in market transactions, allowing them to create market activity and interact with player transactions.

Bug Fixes:

  • Fix issue where market transactions showed values of 0, ensuring correct transaction values are displayed.
  • Resolve problem where market transactions always showed the player as the client, now correctly identifying the transaction parties.

Enhancements:

  • Improve market transaction logic to prevent excessive transaction loops when selling items, ensuring only the intended quantity is sold.
  • Rename TranserFunds to TransferFunds for consistency and clarity across the codebase.
  • Enhance code formatting and legibility across multiple files, improving overall code quality.

Tests:

  • Add test cases for various market transaction scenarios, including player-to-player and player-to-NPC transactions, to ensure correct wallet and journal entries.

…rader features; rename TranserFunds to TransferFunds; code legibility improvements
Copy link
Author

@charles-m-knox charles-m-knox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added helpful comments for reviewers. Please feel free to message me on our Discord if you have further questions or need help. Thank you

@@ -396,7 +396,7 @@
(itemID == npcTraderJoe)

#define IsTrader(itemID) \
(((itemID >= minTrader) && (itemID <= maxTrader))
((itemID >= minTrader) && (itemID <= maxTrader))
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This macro contained an extra parenthetical at the beginning, causing usage of IsTrader to fail immediately anywhere. I have fixed it here.

Comment on lines +235 to +243
TransferFunds(
call.client->GetCharacterID(),
toID->value(),
amount->value(),
reasonStr.c_str(),
Journal::EntryType::PlayerDonation,
call.client->GetCharacterID()
);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legibility improvements only.

Comment on lines +283 to +294
TransferFunds(
call.client->GetCorporationID(),
toID->value(),
amount->value(),
reason.c_str(),
Journal::EntryType::CorporationAccountWithdrawal,
call.client->GetCharacterID(),
fromAcctKey->value(),
toAcctKey,
call.client
);

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legibility improvements only.

Comment on lines +298 to +323
void AccountService::TransferFunds(
uint32 fromID,
uint32 toID,
double amount,
std::string reason /*""*/,
uint8 entryTypeID /*Journal::EntryType::Undefined*/,
uint32 referenceID /*0*/,
uint16 fromKey /*Account::KeyType::Cash*/,
uint16 toKey /*Account::KeyType::Cash*/,
Client* pClient /*nullptr*/
) {
if (is_log_enabled(ACCOUNT__TRACE)) {
_log(ACCOUNT__TRACE,
"TransferFunds() - from: %u, to: %u, entry: %u, refID: %u, amount: %.2f, fKey: %u, tKey: %u",
fromID,
toID,
entryTypeID,
referenceID,
amount,
fromKey,
toKey
);
}

uint8 fromCurrency = Account::CreditType::ISK;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legibility improvements only.

Comment on lines +331 to +356

Client* pClientFrom(nullptr);

if (IsCharacterID(fromID)) {
pClientFrom = sEntityList.FindClientByCharID(fromID);
if (pClientFrom == nullptr) {
// sender is offline. xfer funds thru db.
// sender is offline. transfer funds through the database instead
newBalanceFrom = AccountDB::OfflineFundXfer(fromID, -amount, fromCurrency);
} else {
// this will throw if it fails
pClientFrom->AddBalance(-amount, fromCurrency);
newBalanceFrom = pClientFrom->GetBalance(fromCurrency);
}
AccountDB::AddJournalEntry(fromID, entryTypeID, fromID, toID, fromCurrency, fromKey, -amount, newBalanceFrom, reason, referenceID);

AccountDB::AddJournalEntry(
fromID,
entryTypeID,
fromID,
toID,
fromCurrency,
fromKey,
-amount,
newBalanceFrom,
reason,
referenceID
);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legibility improvements only.

Comment on lines +176 to +184

AccountService::TransferFunds(
call.client->GetCharacterID(),
corpSCC,
amount->value(),
reason,
Journal::EntryType::Insurance,
-shipRef->itemID()
); // for paying ins, shipID should be negative
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legibility improvements only.

Comment on lines -1246 to 1248
AccountService::TranserFunds(corpCONCORD, cur.first, cur.second.amount, reason, Journal::EntryType::BountyPrizes, m_data.systemID);

AccountService::TransferFunds(corpCONCORD, cur.first, cur.second.amount, reason, Journal::EntryType::BountyPrizes, m_data.systemID);
count = 0;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legibility improvements only.

std::string method_name ("GetOrders_");
method_name += std::to_string(regionID);
method_name += "_";
method_name += std::to_string(typeID);
ObjectCachedMethodID method_id("marketProxy", method_name.c_str());
this->m_cache->InvalidateCache( method_id );
this->m_cache->InvalidateCache(method_id);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legibility improvements only.

Comment on lines +299 to +322
/*
* Does not currently handle aurum transactions, but it would be good to do that
* in the future.
*/
bool MarketMgr::ExecuteBuyOrder(Client* seller, uint32 orderID, InventoryItemRef iRef, uint32 quantity, bool useCorp, uint32 typeID, uint32 stationID, double price, uint16 accountKey/*Account::KeyType::Cash*/) {
Market::OrderInfo oInfo = Market::OrderInfo();
if (!MarketDB::GetOrderInfo(orderID, oInfo)) {
_log(MARKET__ERROR, "ExecuteBuyOrder - Failed to get order info for #%u.", orderID);
return true;

return false;
}

/* will this method also be used to buy/sell using aurm?
* unknown yet
*/
// get buyer id and determine if buyer is player, corp, or npc/bot
bool isPlayer(false), isCorp(false), isTraderJoe(false), isTrader(false);

// get buyer id and determine if buyer is player or corp (or bot for later)
bool isPlayer(false), isCorp(false), isTrader(false);
if (IsPlayerCorp(oInfo.ownerID)) {
// buyer is player corp
isCorp = true;
} else if (oInfo.ownerID == 1) {
oInfo.ownerID = stDataMgr.GetOwnerID(stationID);
} else if (IsCharacterID(oInfo.ownerID)) {
isPlayer = true;
} else if (IsTraderJoe(oInfo.ownerID)) {
isTraderJoe = true;
} else if (IsTrader(oInfo.ownerID)) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function as well as ExecuteSellOrder have been slightly refactored and modified to support the aims of this pull request.

Comment on lines 467 to 501
// set an upper bound (this used to be a while loop that spun
// forever in some cases)
for (int i = 0; i < 1000; i++) {
_log(MARKET__DUMP, "Mkt::PlaceCharOrder(): issue 16 - finding buy order: %i, %i, %i, %.2f", typeID->value(), stationID->value(), quantity->value(), price->value());

orderID = MarketDB::FindBuyOrder(typeID->value(), stationID->value(), quantity->value(), price->value());
if (orderID) {
_log(MARKET__TRACE, "PlaceCharOrder - Found buy order #%u in %s for %s.", \
orderID, stDataMgr.GetStationName(stationID->value()).c_str(), call.client->GetName());
search = sMktMgr.ExecuteBuyOrder(call.client, orderID, iRef, quantity->value(), useCorp->value(), typeID->value(), stationID->value(), price->value());

if (!orderID) {
continue;
}

_log(MARKET__TRACE,
"PlaceCharOrder - Found buy order #%u in %s for %s.",
orderID,
stDataMgr.GetStationName(stationID->value()).c_str(),
call.client->GetName()
);

completedOrder = sMktMgr.ExecuteBuyOrder(
call.client,
orderID,
iRef,
quantity->value(),
useCorp->value(),
typeID->value(),
stationID->value(),
price->value()
);

if (!completedOrder) {
continue;
}

_log(MARKET__DUMP, "Mkt::PlaceCharOrder(): issue 16 - order completed");
break;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code changes in this PR fix infinite loop issues that occurred in the previous version of this function, right here.

@charles-m-knox charles-m-knox marked this pull request as ready for review September 11, 2024 21:55
Copy link

sourcery-ai bot commented Sep 11, 2024

Reviewer's Guide by Sourcery

This pull request enhances market transaction behaviors, adds support for NPC traders, fixes transaction-related issues, renames a key function for clarity, and improves code formatting and legibility.

File-Level Changes

Change Details Files
Implemented expected behaviors for market transactions and added support for NPC traders.
  • Fixed issue where multiple transactions were created instead of a single sale when selling items.
  • Resolved issue where market transactions showed values of 0.
  • Fixed issue where market transactions always showed the user as the client.
src/eve-server/market/MarketProxyService.cpp
src/eve-server/market/MarketMgr.cpp
src/eve-server/market/MarketDB.cpp
Renamed function TranserFunds to TransferFunds and updated its usage across the codebase.
  • Renamed TranserFunds to TransferFunds for clarity and corrected spelling.
  • Updated all instances of TranserFunds to use the new function name TransferFunds.
src/eve-server/account/AccountService.cpp
src/eve-server/account/AccountService.h
src/eve-server/planet/PlanetMgr.cpp
src/eve-server/corporation/CorpRegistryBound.cpp
src/eve-server/corporation/LPService.cpp
src/eve-server/ship/Ship.cpp
src/eve-server/manufacturing/RamProxyService.cpp
src/eve-server/system/SystemManager.cpp
src/eve-server/station/InsuranceService.cpp
src/eve-server/character/Character.cpp
src/eve-server/market/MarketMgr.h
src/eve-server/contract/ContractProxy.cpp
src/eve-server/character/CharMgrService.cpp
src/eve-server/character/CharUnboundMgrService.cpp
src/eve-server/agents/AgentBound.cpp
src/eve-server/station/TradeService.cpp
src/eve-server/system/SystemEntity.cpp
Improved code formatting and legibility.
  • Removed unnecessary blank lines and adjusted indentation for consistency.
  • Reformatted comments and code blocks for better readability.
src/eve-server/market/MarketProxyService.cpp
src/eve-server/market/MarketMgr.cpp
src/eve-server/account/AccountService.cpp
src/eve-server/planet/PlanetMgr.cpp
src/eve-server/corporation/CorpRegistryBound.cpp
src/eve-server/corporation/LPService.cpp
src/eve-server/ship/Ship.cpp
src/eve-server/manufacturing/RamProxyService.cpp
src/eve-server/system/SystemManager.cpp
src/eve-server/station/InsuranceService.cpp
src/eve-server/character/Character.cpp
src/eve-server/market/MarketMgr.h
src/eve-server/contract/ContractProxy.cpp
src/eve-server/character/CharMgrService.cpp
src/eve-server/character/CharUnboundMgrService.cpp
src/eve-server/agents/AgentBound.cpp
src/eve-server/station/TradeService.cpp
src/eve-server/system/SystemEntity.cpp

Tips
  • Trigger a new Sourcery review by commenting @sourcery-ai review on the pull request.
  • Continue your discussion with Sourcery by replying directly to review comments.
  • You can change your review settings at any time by accessing your dashboard:
    • Enable or disable the Sourcery-generated pull request summary or reviewer's guide;
    • Change the review language;
  • You can always contact us if you have any questions or feedback.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @charles-m-knox - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Consider splitting the PR into smaller, more focused changes to facilitate easier review and testing.
  • Add more inline comments to explain complex logic, particularly around NPC trader handling and transaction adjustments.
Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟡 Complexity: 1 issue found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment to tell me if it was helpful.

data.accountKey = Account::KeyType::Cash;

data.clientID = clientID->IsNone() ? 0 : PyRep::IntegerValueU32(clientID);
data.isBuy = sellBuy->IsNone() ? -1 : PyRep::IntegerValueU32(sellBuy);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider replacing the magic number '-1' with a named constant for better readability.

Using a named constant instead of '-1' for the isBuy field would improve code readability and maintainability. It would make it clear what this value represents, reducing potential confusion for future developers.

Suggested change
data.isBuy = sellBuy->IsNone() ? -1 : PyRep::IntegerValueU32(sellBuy);
const int BUY_UNDEFINED = -1;
data.isBuy = sellBuy->IsNone() ? BUY_UNDEFINED : PyRep::IntegerValueU32(sellBuy);

if (is_log_enabled(ACCOUNT__TRACE))
_log(ACCOUNT__TRACE, "TranserFunds() - from: %u, to: %u, entry: %u, refID: %u, amount: %.2f, fKey: %u, tKey: %u", \
fromID, toID, entryTypeID, referenceID, amount, fromKey, toKey);
void AccountService::TransferFunds(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider breaking down the long function into smaller helper functions.

The TransferFunds function is quite long and could benefit from being broken down into smaller, focused helper functions. This would improve readability and maintainability.

void AccountService::TransferFunds(uint32 fromID, uint32 toID, uint32 entryTypeID, uint32 referenceID, double amount, uint32 fromKey, uint32 toKey) {
    if (is_log_enabled(ACCOUNT__TRACE)) {
        LogTransferDetails(fromID, toID, entryTypeID, referenceID, amount, fromKey, toKey);
    }
    // Existing logic for transferring funds
}

void AccountService::LogTransferDetails(uint32 fromID, uint32 toID, uint32 entryTypeID, uint32 referenceID, double amount, uint32 fromKey, uint32 toKey) {
    _log(ACCOUNT__TRACE, "TransferFunds() - from: %u, to: %u, entry: %u, refID: %u, amount: %.2f, fKey: %u, tKey: %u", 
         fromID, toID, entryTypeID, referenceID, amount, fromKey, toKey);
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactoring this function is out of scope, but... good bot.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for acknowledging the suggestion! It's completely understandable to keep the scope focused on the current improvements and fixes. If you decide to revisit this area in the future, breaking down the function could enhance readability and maintainability. Let me know if there's anything else you'd like to discuss or need help with!

/*
* Does not currently handle aurum transactions, but it would be good to do that
* in the future.
*/
bool MarketMgr::ExecuteBuyOrder(Client* seller, uint32 orderID, InventoryItemRef iRef, uint32 quantity, bool useCorp, uint32 typeID, uint32 stationID, double price, uint16 accountKey/*Account::KeyType::Cash*/) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider refactoring the quantity handling logic into separate functions.

The ExecuteBuyOrder function has become complex due to multiple boolean flags and nested conditionals. To improve readability and maintainability, consider refactoring the quantity handling logic into separate functions. This will reduce nesting and make the code more modular.

Here's a suggestion:

void HandleCompleteOrder(InventoryItemRef iRef, Market::OrderInfo& oInfo, uint32 stationID, bool isPlayer, bool isCorp) {
    if (isPlayer) {
        iRef->Donate(oInfo.ownerID, stationID, flagHangar, true);
    } else if (isCorp) {
        iRef->Donate(oInfo.ownerID, stationID, flagCorpMarket, true);
    }
}

void HandleOverOrder(InventoryItemRef iRef, Market::OrderInfo& oInfo, uint32 stationID, bool isPlayer, bool isCorp) {
    InventoryItemRef siRef = iRef->Split(oInfo.quantity);
    if (siRef.get() == nullptr) {
        _log(MARKET__ERROR, "Failed to split item.");
        return;
    }
    if (isPlayer) {
        siRef->Donate(oInfo.ownerID, stationID, flagHangar, true);
    } else if (isCorp) {
        siRef->Donate(oInfo.ownerID, stationID, flagCorpMarket, true);
    }
}

// In ExecuteBuyOrder
if (qtyStatus == Market::QtyStatus::Complete) {
    HandleCompleteOrder(iRef, oInfo, stationID, isPlayer, isCorp);
} else if (qtyStatus == Market::QtyStatus::Over) {
    HandleOverOrder(iRef, oInfo, stationID, isPlayer, isCorp);
}

This refactoring reduces the complexity of the main function by moving specific logic into helper functions, making it easier to follow and maintain.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to see it refactored too, but it's out of scope for this PR. Again, good bot.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's completely understandable, Charles. Refactoring can sometimes be a larger task that might not fit within the scope of a specific PR, especially when the focus is on fixing bugs and implementing new features. It's great to hear that you're considering it for the future, though. If you decide to tackle it later, breaking down complex functions into smaller, more manageable pieces can definitely improve readability and maintainability. Let me know if you need any assistance or further suggestions when you get to that point!

@jdhirst
Copy link
Contributor

jdhirst commented Sep 13, 2024

@charles-m-knox Thanks for the excellent and detailed contribution and cleanup!! ❤️ I looked it over and it looks good to me, so here's your merge!

As a side note, it seems like the bot is actually quite useful for things like that, I'm glad to see that it seems to have been worthwhile adding it 🙂

@jdhirst jdhirst merged commit b302a3b into EvEmu-Project:staging Sep 13, 2024
2 checks passed
@charles-m-knox charles-m-knox deleted the market-transactions-improvements branch September 13, 2024 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants