Skip to content

Commit

Permalink
Improvements and fixes for market transactions; code quality improvem…
Browse files Browse the repository at this point in the history
…ents (#291)

* show proper clients in wallet transactions view; implement more npc trader features; rename TranserFunds to TransferFunds; code legibility improvements

* adjust debug logging
  • Loading branch information
charles-m-knox authored Sep 13, 2024
1 parent 4e45b36 commit b302a3b
Show file tree
Hide file tree
Showing 25 changed files with 926 additions and 457 deletions.
4 changes: 2 additions & 2 deletions doc/code_and_design_notes/Alasiya_TODO
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ customInfo is actually used in client
- there are many logConst and event** msgs not implemented/researched (LP, FacWar, StandingTransactions, more)

20:41:06 [Bound] InsuranceBound::InsureShip()
20:41:06 [AcctTrace] TranserFunds() - from: 90000000, to: 1000132, entry: 19, refID: 0, amount: 0.33, fKey: 1000, tKey: 1000
20:41:06 [AcctTrace] TranserFunds() - toID: 1000132 is neither player nor player corp.
20:41:06 [AcctTrace] TransferFunds() - from: 90000000, to: 1000132, entry: 19, refID: 0, amount: 0.33, fKey: 1000, tKey: 1000
20:41:06 [AcctTrace] TransferFunds() - toID: 1000132 is neither player nor player corp.
20:41:06 [SvcMsg] New messageID: 1
20:41:06 [SvcMsg] Delivered message from 1000132 to recipient 90000000
- ins mail working. need contractID, expiry date, and few other things...
Expand Down
2 changes: 1 addition & 1 deletion src/eve-common/EVE_Defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@
(itemID == npcTraderJoe)

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


/*
Expand Down
200 changes: 167 additions & 33 deletions src/eve-server/account/AccountService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,7 @@ PyResult AccountService::GiveCash(PyCallArgs& call, PyInt* toID, PyFloat* amount
return GiveCash(call, toID, amount, reason.has_value()?reason.value()->content():std::string());
}

PyResult AccountService::GiveCash(PyCallArgs &call, PyInt* toID, PyFloat* amount, std::string reason)
{
PyResult AccountService::GiveCash(PyCallArgs &call, PyInt* toID, PyFloat* amount, std::string reason) {
if (is_log_enabled(ACCOUNT__CALL_DUMP)) {
sLog.Log( "AccountService::Handle_GiveCash()", "size=%lu", call.tuple->size());
call.Dump(ACCOUNT__CALL_DUMP);
Expand All @@ -233,7 +232,15 @@ PyResult AccountService::GiveCash(PyCallArgs &call, PyInt* toID, PyFloat* amount
reasonStr += reason;
}

TranserFunds(call.client->GetCharacterID(), toID->value(), amount->value(), reasonStr.c_str(), Journal::EntryType::PlayerDonation, call.client->GetCharacterID());
TransferFunds(
call.client->GetCharacterID(),
toID->value(),
amount->value(),
reasonStr.c_str(),
Journal::EntryType::PlayerDonation,
call.client->GetCharacterID()
);

return nullptr;
}

Expand Down Expand Up @@ -273,43 +280,97 @@ PyResult AccountService::GiveCashFromCorpAccount(PyCallArgs &call, PyInt* toID,
reason += call.client->GetCharName();
}

TranserFunds(call.client->GetCorporationID(), toID->value(), amount->value(), reason.c_str(), Journal::EntryType::CorporationAccountWithdrawal, \
call.client->GetCharacterID(), fromAcctKey->value(), toAcctKey, call.client);
TransferFunds(
call.client->GetCorporationID(),
toID->value(),
amount->value(),
reason.c_str(),
Journal::EntryType::CorporationAccountWithdrawal,
call.client->GetCharacterID(),
fromAcctKey->value(),
toAcctKey,
call.client
);

return nullptr;
}

void AccountService::TranserFunds(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, "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(
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;

if (IsAUR(fromKey)) {
fromCurrency = Account::CreditType::AURUM;
} else if (IsDustKey(fromKey)) {
fromCurrency = Account::CreditType::MPLEX;
}

double newBalanceFrom(0), newBalanceTo(0);

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
);
} else if (IsPlayerCorp(fromID)) {
uint32 userID(0);
if (pClient != nullptr)
if (pClient != nullptr) {
userID = pClient->GetCharacterID();
HandleCorpTransaction(fromID, entryTypeID, userID?userID:fromID, toID, fromCurrency, fromKey, -amount, reason, referenceID);
}

HandleCorpTransaction(
fromID,
entryTypeID,
userID ? userID : fromID,
toID,
fromCurrency,
fromKey,
-amount,
reason,
referenceID
);
} // fromID could be npc or _System. nothing to do on this side.

uint8 toCurrency = Account::CreditType::ISK;
Expand All @@ -320,6 +381,7 @@ void AccountService::TranserFunds(uint32 fromID, uint32 toID, double amount, std
}

Client* pClientTo(nullptr);

if (IsCharacterID(toID)) {
pClientTo = sEntityList.FindClientByCharID(toID);
if (pClientTo == nullptr) {
Expand All @@ -329,24 +391,67 @@ void AccountService::TranserFunds(uint32 fromID, uint32 toID, double amount, std
// this will throw if it fails
pClientTo->AddBalance(amount, toCurrency);
/** @todo if this DOES fail, return funds to origin. this needs a try/catch block */
//TranserFunds(corpSCC, fromID, amount, reason, Journal::EntryType::Undefined, referenceID, fromKey, fromKey);
//TransferFunds(corpSCC, fromID, amount, reason, Journal::EntryType::Undefined, referenceID, fromKey, fromKey);
newBalanceTo = pClientTo->GetBalance(toCurrency);
}
AccountDB::AddJournalEntry(toID, entryTypeID, fromID, toID, toCurrency, toKey, amount, newBalanceTo, reason, referenceID);

AccountDB::AddJournalEntry(
toID,
entryTypeID,
fromID,
toID,
toCurrency,
toKey,
amount,
newBalanceTo,
reason,
referenceID
);
} else if (IsPlayerCorp(toID)) {
uint32 userID(0);
if (pClient != nullptr)

if (pClient != nullptr) {
userID = pClient->GetCharacterID();
HandleCorpTransaction(toID, entryTypeID, fromID, userID?userID:toID, toCurrency, toKey, amount, reason, referenceID);
}

HandleCorpTransaction(
toID,
entryTypeID,
fromID,
userID?userID:toID,
toCurrency,
toKey,
amount,
reason,
referenceID
);
return;
} else {
_log(ACCOUNT__TRACE, "TranserFunds() - toID: %s(%u) is neither player nor player corp. Not sending update.", \
sDataMgr.GetCorpName(toID).c_str(), toID);
AccountDB::AddJournalEntry(
toID,
entryTypeID,
fromID,
toID,
toCurrency,
toKey,
amount,
newBalanceTo,
reason,
referenceID
);

_log(ACCOUNT__TRACE,
"TransferFunds() - toID: %s(%u) is neither player nor player corp. Not sending update.",
sDataMgr.GetCorpName(toID).c_str(),
toID
);

return;
}

if ((pClientTo != nullptr) and pClientTo->IsCharCreation())
if ((pClientTo != nullptr) and pClientTo->IsCharCreation()) {
return;
}

/* corp taxes...
* bounty prizes and mission rewards are taxed by the players corp based on corp tax rate.
Expand All @@ -355,13 +460,18 @@ void AccountService::TranserFunds(uint32 fromID, uint32 toID, double amount, std
*/

// are bounty payments grouped on timer?
if ((entryTypeID == Journal::EntryType::BountyPrize)
or (entryTypeID == Journal::EntryType::BountyPrizes))
if (sConfig.server.BountyPayoutDelayed)
if (amount < sConfig.rates.TaxedAmount) // is amount worth taxing? default is 75k
if ((entryTypeID == Journal::EntryType::BountyPrize) || (entryTypeID == Journal::EntryType::BountyPrizes)) {
if (sConfig.server.BountyPayoutDelayed) {
// is amount worth taxing? default is 75k
if (amount < sConfig.rates.TaxedAmount) {
return;
}
}
}

float tax = 0;
uint32 corpID = 0;

if (pClientTo != nullptr) {
tax = pClientTo->GetCorpTaxRate() * amount;
corpID = pClientTo->GetCorporationID();
Expand All @@ -372,24 +482,48 @@ void AccountService::TranserFunds(uint32 fromID, uint32 toID, double amount, std
}

// just in case something went wrong.....
if (!IsCorp(corpID))
if (!IsCorp(corpID)) {
return;
// is tax worth the accounting hassle? (from corp pov) default is 5k
if (tax < sConfig.rates.TaxAmount)
}

// is tax worth the accounting hassle? (from corp pov) default is 5k
if (tax < sConfig.rates.TaxAmount) {
return;
}

reason = "DESC: Corporation Tax on pirate bounty";
switch (entryTypeID) {
// Corp Taxed payment types
case Journal::EntryType::BountyPrize:
case Journal::EntryType::BountyPrizes: {
TranserFunds(toID, corpID, tax, reason.c_str(), Journal::EntryType::CorporationTaxNpcBounties, referenceID);
TransferFunds(
toID,
corpID,
tax,
reason.c_str(),
Journal::EntryType::CorporationTaxNpcBounties,
referenceID
);
} break;
case Journal::EntryType::AgentMissionReward: {
TranserFunds(toID, corpID, tax, reason.c_str(), Journal::EntryType::CorporationTaxAgentRewards, referenceID);
TransferFunds(
toID,
corpID,
tax,
reason.c_str(),
Journal::EntryType::CorporationTaxAgentRewards,
referenceID
);
} break;
case Journal::EntryType::AgentMissionTimeBonusReward: {
TranserFunds(toID, corpID, tax, reason.c_str(), Journal::EntryType::CorporationTaxAgentBonusRewards, referenceID);
TransferFunds(
toID,
corpID,
tax,
reason.c_str(),
Journal::EntryType::CorporationTaxAgentBonusRewards,
referenceID
);
} break;
}
}
Expand Down
30 changes: 23 additions & 7 deletions src/eve-server/account/AccountService.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,31 @@ class AccountService : public Service <AccountService> {
AccountService();

// this moves currency, adds journal entries, and sends blink event. handles applicable corp taxes internally.
// will throw if fails
static void TranserFunds(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);
// will throw if fails
static void 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
);

// this should be the ONLY method to alter corp balances, and ONLY called from TransferFunds()
static void HandleCorpTransaction(uint32 corpID, int8 entryTypeID, uint32 fromID, uint32 toID, int8 currency, uint16 accountKey, \
double amount, std::string description, uint32 referenceID = 0);
static void HandleCorpTransaction(
uint32 corpID,
int8 entryTypeID,
uint32 fromID,
uint32 toID,
int8 currency,
uint16 accountKey,
double amount,
std::string description,
uint32 referenceID = 0
);

protected:
AccountDB m_db;
Expand Down
4 changes: 2 additions & 2 deletions src/eve-server/agents/AgentBound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,9 @@ PyResult AgentBound::DoAction(PyCallArgs &call, std::optional <PyInt*> actionID)
}
/** @todo add fleet sharing */
if (offer.rewardISK)
AccountService::TranserFunds(m_agent->GetID(), pchar->itemID(), offer.rewardISK, "Mission Reward", Journal::EntryType::AgentMissionReward, m_agent->GetID());
AccountService::TransferFunds(m_agent->GetID(), pchar->itemID(), offer.rewardISK, "Mission Reward", Journal::EntryType::AgentMissionReward, m_agent->GetID());
if ((offer.bonusTime > 0) and (offer.bonusTime < (offer.dateAccepted - GetFileTimeNow())))
AccountService::TranserFunds(m_agent->GetID(), pchar->itemID(), offer.bonusISK, "Mission Bonus Reward", Journal::EntryType::AgentMissionTimeBonusReward, m_agent->GetID());
AccountService::TransferFunds(m_agent->GetID(), pchar->itemID(), offer.bonusISK, "Mission Bonus Reward", Journal::EntryType::AgentMissionTimeBonusReward, m_agent->GetID());
/** @todo add lp, etc, etc */
if (offer.rewardLP)
LPService::AddLP(pchar->itemID(), m_agent->GetCorpID(), offer.rewardLP);
Expand Down
5 changes: 2 additions & 3 deletions src/eve-server/character/CharMgrService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,7 @@ PyResult CharMgrService::GetPublicInfo(PyCallArgs &call, PyInt* ownerID) {
return result;
}

PyResult CharMgrService::AddToBounty(PyCallArgs& call, PyInt* characterID, PyInt* amount)
{
PyResult CharMgrService::AddToBounty(PyCallArgs& call, PyInt* characterID, PyInt* amount) {
if (call.client->GetCharacterID() == characterID->value()){
call.client->SendErrorMsg("You cannot put a bounty on yourself.");
return nullptr;
Expand All @@ -249,7 +248,7 @@ PyResult CharMgrService::AddToBounty(PyCallArgs& call, PyInt* characterID, PyInt
if (amount->value() < call.client->GetBalance()) {
std::string reason = "Placing Bounty on ";
reason += m_db.GetCharName(characterID->value());
AccountService::TranserFunds(call.client->GetCharacterID(), corpCONCORD, amount->value(), reason, Journal::EntryType::Bounty, characterID->value());
AccountService::TransferFunds(call.client->GetCharacterID(), corpCONCORD, amount->value(), reason, Journal::EntryType::Bounty, characterID->value());
m_db.AddBounty(characterID->value(), call.client->GetCharacterID(), amount->value());
// new system gives target a mail from concord about placement of bounty and char name placing it.
} else {
Expand Down
Loading

0 comments on commit b302a3b

Please sign in to comment.