public void ObjectBuy(IClientAPI remoteClient, UUID agentID, UUID sessionID, UUID groupID, UUID categoryID, uint localID, byte saleType, int salePrice) { if (salePrice < 0) return; if (salePrice > 0) { // allow users with negative balances to buy freebies int avatarFunds = getCurrentBalance(agentID); if (avatarFunds < salePrice) { // The viewer runs a check on monies balance, however, let's make sure another viewer // can't exploit this by removing and check their funds ourselves. remoteClient.SendAgentAlertMessage("Insufficient funds to purchase this item!", false); return; } } IClientAPI sourceAvatarClient = LocateClientObject(remoteClient.AgentId); if (sourceAvatarClient == null) { sourceAvatarClient.SendAgentAlertMessage("Purchase failed. No Controlling client found for sourceAvatar!", false); return; } Scene s = LocateSceneClientIn(remoteClient.AgentId); //Scene s = GetScenePresence(remoteClient.AgentId); SceneObjectPart objectPart = s.GetSceneObjectPart(localID); if (objectPart == null) { sourceAvatarClient.SendAgentAlertMessage("Purchase failed. The object was not found.", false); return; } ///// Prevent purchase spoofing, as well as viewer bugs. ///// // Verify that the object is actually for sale if (objectPart.ObjectSaleType == (byte)SaleType.Not) { remoteClient.SendAgentAlertMessage("Purchase failed. The item is not for sale.", false); return; } // Verify that the viewer sale type actually matches the correct sale type of the object if (saleType != objectPart.ObjectSaleType) { remoteClient.SendAgentAlertMessage("Purchase failed. The sale type does not match.", false); return; } // Verify that the buyer is paying the correct amount if (salePrice != objectPart.SalePrice) { remoteClient.SendAgentAlertMessage("Purchase failed. The payment price does not match the sale price.", false); return; } string objName = objectPart.ParentGroup.RootPart.Name; Vector3 pos = objectPart.AbsolutePosition; int posx = (int)(pos.X + 0.5); int posy = (int)(pos.Y + 0.5); int posz = (int)(pos.Z + 0.5); string transDesc = String.Format("{0} in {1} at <{2},{3},{4}>", objName, objectPart.ParentGroup.Scene.RegionInfo.RegionName, posx, posy, posz); string sourceAlertText = "Purchased " + objName + " for Iz$" + salePrice; string destAlertText = resolveAgentName(agentID) + " paid you Iz$" + salePrice + " via " + objName; int transType = (int)MoneyTransactionType.ObjectSale; UUID transID = UUID.Zero; TransactionInfoBlock transInfo = new TransactionInfoBlock(); transInfo.Amount = salePrice; transInfo.TransactionType = transType; transInfo.SourceID = remoteClient.AgentId; transInfo.DestID = objectPart.OwnerID; transInfo.IsSourceGroup = false; transInfo.IsDestGroup = false; transInfo.ItemDescription = Util.StringToBytes256(objName); if (agentID == objectPart.OwnerID) { // we'll let them test the buy, but nothing happens money wise. if (!s.PerformObjectBuy(remoteClient, categoryID, localID, saleType)) return; sourceAvatarClient.SendBlueBoxMessage(agentID, "", sourceAlertText); } else { if (salePrice == 0) { // We need to add a counter here for Freebies thus bypassing the DB for transactions cause // Freebies are a pain to have to track in the transaction history. if (!s.PerformObjectBuy(remoteClient, categoryID, localID, saleType)) return; } else { UUID originalOwnerID = objectPart.OwnerID; // capture the original seller's UUID for the money transfer if (!s.PerformObjectBuy(remoteClient, categoryID, localID, saleType)) // changes objectPart.OwnerID return; transID = doMoneyTransfer(remoteClient.AgentId, originalOwnerID, salePrice, transType, transDesc); } SendMoneyBalanceTransaction(sourceAvatarClient, transID, true, sourceAlertText, transInfo); } IClientAPI destAvatarClient = LocateClientObject(objectPart.OwnerID); if (destAvatarClient == null) { return; } else { SendMoneyBalanceTransaction(destAvatarClient, transID, true, destAlertText, transInfo); } }
private void processLandBuy(Object osender, EventManager.LandBuyArgs e) { if (e.transactionID != 0) { // Not sure what this error is, duplicate purchase request for if the packet comes in a second time? return; } e.transactionID = Util.UnixTimeSinceEpoch(); // This method should not do any additional validation. // Any required validation should have been performed either // in LandManagementModule handleLandValidationRequest() or // in ValidateLandBuy above. int transType = (int)MoneyTransactionType.LandSale; string transDesc = "Land purchase"; UUID sourceClientID = e.agentId; IClientAPI sourceClient = LocateClientObject(sourceClientID); if (!e.economyValidated) { if (sourceClient != null) sourceClient.SendAgentAlertMessage("Could not validate user account balance for purchase.", false); return; } if ((e.parcel == null) || (!e.landValidated)) return; LandData parcel = e.parcel.landData; int transAmount = e.originalParcelPrice; UUID transID = UUID.Zero; UUID destClientID = e.originalParcelOwner; IClientAPI destClient = LocateClientObject(destClientID); // Pick a spot inside the parcel. Since blocks are 4x4, pick a spot 2m inside the bottom corner block. Vector3 pos = parcel.AABBMin; pos.X += 2; pos.Y += 2; transDesc += " at " + e.parcel.regionName + " (" + pos.X + "," + pos.Y + "): " + parcel.Name; // limit the result to 255 for the db storage if (transDesc.Length > 255) transDesc = transDesc.Substring(0, 255); // requires 2 users: source and dest clients must both be users (not groups, not same) transID = doMoneyTransfer(sourceClientID, destClientID, transAmount, transType, transDesc); TransactionInfoBlock transInfo = new TransactionInfoBlock(); transInfo.Amount = transAmount; transInfo.TransactionType = transType; transInfo.ItemDescription = Util.StringToBytes256(transDesc); transInfo.SourceID = sourceClientID; transInfo.IsSourceGroup = false; transInfo.DestID = e.originalParcelOwner; if (e.originalIsGroup) { // not currently supported (blocked in LandManagementModule handleLandValidationRequest()) // unless price is 0, because we cannot pass a group ID to doMoneyTransfer above. transInfo.IsDestGroup = true; } else { transInfo.IsDestGroup = false; } if (sourceClient != null) { string destName = resolveAgentName(destClientID); if (destName == String.Empty) destName = "a group (or unknown user)"; string sourceText = "You paid Iz$" + transAmount + " to " + destName + " for a parcel of land."; SendMoneyBalanceTransaction(sourceClient, transID, true, sourceText, transInfo); } if (destClient != null) { string destName = resolveAgentName(sourceClientID); if (destName == String.Empty) destName = "a group (or unknown user)"; string destText = "You were paid Iz$" + transAmount + " by " + destName + " for a parcel of land."; SendMoneyBalanceTransaction(destClient, transID, true, destText, transInfo); } }
public bool ObjectGiveMoney(UUID objectID, UUID sourceAvatarID, UUID destAvatarID, int amount) { if (amount < 0) return false; SceneObjectPart part = findPrim(objectID); if (part == null) return false; string objName = part.ParentGroup.Name; string description = String.Format("{0} paid {1}", objName, resolveAgentName(destAvatarID)); int transType = (int)MoneyTransactionType.ObjectPays; if (amount > 0) { // allow users with negative balances to buy freebies int sourceAvatarFunds = getCurrentBalance(sourceAvatarID); if (sourceAvatarFunds < amount) { return false; } } UUID transID = doMoneyTransfer(sourceAvatarID, destAvatarID, amount, transType, description); TransactionInfoBlock transInfo = new TransactionInfoBlock(); transInfo.Amount = amount; transInfo.TransactionType = transType; transInfo.SourceID = sourceAvatarID; transInfo.DestID = destAvatarID; transInfo.IsSourceGroup = false; transInfo.IsDestGroup = false; transInfo.ItemDescription = Util.StringToBytes256(objName); IClientAPI sourceAvatarClient = LocateClientObject(sourceAvatarID); if (sourceAvatarClient == null) { // Just a quick catch for a null reference, just cause they can't be found doesn't // mean the item can't pay out the money. } else { string sourceText = objName + " paid out Iz$" + amount + " to " + resolveAgentName(destAvatarID); SendMoneyBalanceTransaction(sourceAvatarClient, transID, true, sourceText, transInfo); } IClientAPI destAvatarClient = LocateClientObject(destAvatarID); if(destAvatarClient == null) { // Quick catch due to scene issues, don't want to it to fall down if // the destination avatar is not in the same scene list or online at all. } else { string destText = "You were paid Iz$" + amount + " by " + part.ParentGroup.Name; SendMoneyBalanceTransaction(destAvatarClient, transID, true, destText, transInfo); } return true; }
private void MoneyTransferAction(Object osender, EventManager.MoneyTransferArgs e) { if (e.amount < 0) return; //ScenePresence sourceAvatar = m_scene.GetScenePresence(e.sender); //IClientAPI sourceAvatarClient = sourceAvatar.ControllingClient; UUID sourceAvatarID = e.sender; int transType = e.transactiontype; string transDesc = e.description; UUID destAvatarID = e.receiver; int transAmount = e.amount; IClientAPI sourceAvatarClient; IClientAPI destAvatarClient; string sourceText = ""; string destText = ""; TransactionInfoBlock transInfo = new TransactionInfoBlock(); transInfo.Amount = transAmount; transInfo.TransactionType = transType; transInfo.SourceID = sourceAvatarID; transInfo.DestID = destAvatarID; transInfo.IsSourceGroup = false; transInfo.IsDestGroup = false; transInfo.ItemDescription = new byte[0]; sourceAvatarClient = LocateClientObject(sourceAvatarID); if (sourceAvatarClient == null) { m_log.Debug("[CURRENCY]: Source Avatar not found!"); } if (transType == (int)MoneyTransactionType.PayObject) { SceneObjectPart part = findPrim(e.receiver); if (!CheckPayObjectAmount(part, e.amount)) { sourceAvatarClient.SendAgentAlertMessage("Invalid amount used for payment to object.", false); return; } // Check if the object or owner are muted. if (IsMutedObject(part.ParentGroup, sourceAvatarID)) { sourceAvatarClient.SendAgentAlertMessage("Cannot give money to an object or object owner that you have muted. If the viewer has automatically unblocked the owner, you can retry payment.", false); return; } destAvatarID = part.OwnerID; destAvatarClient = LocateClientObject(destAvatarID); Vector3 pos = part.AbsolutePosition; int posx = (int)(pos.X + 0.5); // round to nearest int posy = (int)(pos.Y + 0.5); // round to nearest int posz = (int)(pos.Z + 0.5); // round to nearest transInfo.DestID = destAvatarID; transInfo.ItemDescription = Util.StringToBytes256(part.ParentGroup.RootPart.Name); transDesc = String.Format("Paid {0} via object {1} in {2} at <{3},{4},{5}>", resolveAgentName(destAvatarID), part.ParentGroup.Name, part.ParentGroup.Scene.RegionInfo.RegionName, posx, posy, posz); sourceText = "You paid " + resolveAgentName(destAvatarID) + " Iz$" + transAmount + " via " + part.ParentGroup.Name; destText = resolveAgentName(sourceAvatarID) + " paid you Iz$" + transAmount; } else { destAvatarID = (e.receiver); destAvatarClient = LocateClientObject(destAvatarID); if (destAvatarClient == null) { } else if (LocateSceneClientIn(destAvatarID).GetScenePresence(destAvatarID).IsBot) { sourceAvatarClient.SendAgentAlertMessage("You cannot pay a bot.", false); return; } transDesc = "Gift"; sourceText = "You paid " + resolveAgentName(destAvatarID) + " Iz$" + transAmount; destText = resolveAgentName(sourceAvatarID) + " paid you Iz$" + transAmount; } if (transAmount > 0) { // allow users with negative balances to buy freebies int avatarFunds = getCurrentBalance(sourceAvatarID); if (avatarFunds < transAmount) { sourceAvatarClient.SendAgentAlertMessage("Insufficient funds at this time", false); return; } } UUID transID; bool success; if (sourceAvatarID == destAvatarID) { // catching here, they can test but no reason to stuff crap in the db for testing transID = UUID.Zero; success = true; } else { transID = doMoneyTransfer(sourceAvatarID, destAvatarID, transAmount, transType, transDesc); success = (transID != UUID.Zero); } //if this is a scripted transaction let the script know money has changed hands if (transType == (int)MoneyTransactionType.PayObject) { this.OnObjectPaid(e.receiver, sourceAvatarID, transAmount); } SendMoneyBalanceTransaction(sourceAvatarClient, transID, success, sourceText, transInfo); if (destAvatarClient == null) { // don't want to do anything, as they can not be found, this is ugly but will suffice // until we get the scene working correctly to pull every avatar } else { SendMoneyBalanceTransaction(destAvatarClient, transID, success, destText, transInfo); } }
/// <summary> /// Send the Balance to the viewer /// </summary> /// <param name="client">Client requesting information</param> private void SendMoneyBalanceTransaction(IClientAPI client, UUID transaction, bool success, string transactionDescription, TransactionInfoBlock transInfo) { UUID avatarID = client.AgentId; int avatarFunds = getCurrentBalance(avatarID); client.SendMoneyBalance(transaction, success, transactionDescription, avatarFunds, transInfo); }
public void ApplyMeshUploadCharge(UUID agentID, int meshCount, int textureCount) { int transAmount = MeshUploadCharge(meshCount, textureCount); if (transAmount <= 0) return; string transDesc = "mesh upload"; int transCode = (int)MoneyTransactionType.UploadCharge; UUID transID = ApplyCharge(agentID, transCode, transAmount, transDesc); // The viewer notifies the user for most upload transactions, except for mesh uploads. // So if there's a client, notify them now. IClientAPI client = LocateClientObject(agentID); if (client != null) { TransactionInfoBlock transInfo = new TransactionInfoBlock(); transInfo.Amount = transAmount; transInfo.TransactionType = transCode; transInfo.SourceID = agentID; transInfo.DestID = UUID.Zero; transInfo.IsSourceGroup = false; transInfo.IsDestGroup = false; transInfo.ItemDescription = Util.StringToBytes256(transDesc); string message; if ((transDesc == null) || (transDesc == String.Empty)) message = "You paid $" + transAmount.ToString() + "."; else message = "You paid $" + transAmount.ToString() + " for " + transDesc + "."; SendMoneyBalanceTransaction(client, transID, true, message, transInfo); } }
public void SendMoneyBalance(UUID transaction, bool success, string description, int balance, TransactionInfoBlock transInfo) { }
public void SendMoneyBalance(OpenMetaverse.UUID transaction, bool success, string description, int balance, OpenMetaverse.Packets.MoneyBalanceReplyPacket.TransactionInfoBlock transInfo) { }
// Returns the transaction ID that shows up in the transaction history. public string ObjectGiveMoney(UUID objectID, UUID sourceAvatarID, UUID destAvatarID, int amount, out string reason) { reason = String.Empty; if (amount <= 0) { reason = "INVALID_AMOUNT"; return String.Empty; } SceneObjectPart part = findPrim(objectID); if (part == null) { reason = "MISSING_PERMISSION_DEBIT"; // if you can't find it, no perms either return String.Empty; } string objName = part.ParentGroup.Name; string description = String.Format("{0} paid {1}", objName, resolveAgentName(destAvatarID)); int transType = (int)MoneyTransactionType.ObjectPays; if (amount > 0) { // allow users with negative balances to buy freebies int sourceAvatarFunds = getCurrentBalance(sourceAvatarID); if (sourceAvatarFunds < amount) { reason = "LINDENDOLLAR_INSUFFICIENTFUNDS"; return String.Empty; } } UUID transID = doMoneyTransfer(sourceAvatarID, destAvatarID, amount, transType, description); // the transID UUID is actually a ulong stored in a UUID. string result = transID.GetULong().ToString(); reason = String.Empty; TransactionInfoBlock transInfo = new TransactionInfoBlock(); transInfo.Amount = amount; transInfo.TransactionType = transType; transInfo.SourceID = sourceAvatarID; transInfo.DestID = destAvatarID; transInfo.IsSourceGroup = false; transInfo.IsDestGroup = false; transInfo.ItemDescription = Util.StringToBytes256(objName); IClientAPI sourceAvatarClient = LocateClientObject(sourceAvatarID); if (sourceAvatarClient == null) { // Just a quick catch for a null reference, just cause they can't be found doesn't // mean the item can't pay out the money. } else { string sourceText = objName + " paid out Iz$" + amount + " to " + resolveAgentName(destAvatarID); SendMoneyBalanceTransaction(sourceAvatarClient, transID, true, sourceText, transInfo); } IClientAPI destAvatarClient = LocateClientObject(destAvatarID); if(destAvatarClient == null) { // Quick catch due to scene issues, don't want to it to fall down if // the destination avatar is not in the same scene list or online at all. } else { string destText = "You were paid Iz$" + amount + " by " + part.ParentGroup.Name; SendMoneyBalanceTransaction(destAvatarClient, transID, true, destText, transInfo); } return result; }