* Patch from Melanie. Mantis 0001037: Add various internal plumbing to the example economy module, implements llSetPayPrice(), money() and llGiveMoney() in scripts. Thanks Melanie!

* Moves module loading before the script engine so the script engine can pick up events from modules registering interfaces with scene.
0.6.0-stable
Teravus Ovares 2008-04-23 22:44:59 +00:00
parent 571bd3a77e
commit 1909d74d5f
10 changed files with 242 additions and 11 deletions

View File

@ -51,6 +51,7 @@ Patches
* krtaylor (IBM) * krtaylor (IBM)
* A_Biondi * A_Biondi
* lulurun * lulurun
* Melanie Thielker
LSL Devs LSL Devs

View File

@ -441,6 +441,7 @@ namespace OpenSim.Framework
public delegate void ObjectIncludeInSearch(IClientAPI remoteClient, bool IncludeInSearch, uint localID); public delegate void ObjectIncludeInSearch(IClientAPI remoteClient, bool IncludeInSearch, uint localID);
public delegate void ScriptAnswer(IClientAPI remoteClient, LLUUID objectID, LLUUID itemID, int answer); public delegate void ScriptAnswer(IClientAPI remoteClient, LLUUID objectID, LLUUID itemID, int answer);
public delegate void RequestPayPrice(IClientAPI remoteClient, LLUUID objectID);
public interface IClientAPI public interface IClientAPI
{ {
@ -557,6 +558,7 @@ namespace OpenSim.Framework
event MoneyBalanceRequest OnMoneyBalanceRequest; event MoneyBalanceRequest OnMoneyBalanceRequest;
event UpdateAvatarProperties OnUpdateAvatarProperties; event UpdateAvatarProperties OnUpdateAvatarProperties;
event ParcelBuy OnParcelBuy; event ParcelBuy OnParcelBuy;
event RequestPayPrice OnRequestPayPrice ;
event ObjectIncludeInSearch OnObjectIncludeInSearch; event ObjectIncludeInSearch OnObjectIncludeInSearch;
@ -621,6 +623,7 @@ namespace OpenSim.Framework
void SendTeleportFailed(string reason); void SendTeleportFailed(string reason);
void SendTeleportLocationStart(); void SendTeleportLocationStart();
void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance); void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance);
void SendPayPrice(LLUUID objectID, int[] payPrice);
void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID,
LLVector3 Pos, byte[] textureEntry, uint parentID); LLVector3 Pos, byte[] textureEntry, uint parentID);

View File

@ -522,6 +522,10 @@ namespace OpenSim
m_log.Info("[MODULES]: Loading Region's modules"); m_log.Info("[MODULES]: Loading Region's modules");
List<IRegionModule> modules = m_moduleLoader.PickupModules(scene, "."); List<IRegionModule> modules = m_moduleLoader.PickupModules(scene, ".");
// This needs to be ahead of the script engine load, so the
// script module can pick up events exposed by a module
m_moduleLoader.InitialiseSharedModules(scene);
//m_moduleLoader.PickupModules(scene, "ScriptEngines"); //m_moduleLoader.PickupModules(scene, "ScriptEngines");
//m_moduleLoader.LoadRegionModules(Path.Combine("ScriptEngines", m_scriptEngine), scene); //m_moduleLoader.LoadRegionModules(Path.Combine("ScriptEngines", m_scriptEngine), scene);
@ -547,7 +551,6 @@ namespace OpenSim
} }
} }
m_moduleLoader.InitialiseSharedModules(scene);
scene.SetModuleInterfaces(); scene.SetModuleInterfaces();
//moved these here as the terrain texture has to be created after the modules are initialized //moved these here as the terrain texture has to be created after the modules are initialized

View File

@ -234,6 +234,7 @@ namespace OpenSim.Region.ClientStack
private UUIDNameRequest handlerTeleportHomeRequest = null; private UUIDNameRequest handlerTeleportHomeRequest = null;
private ScriptAnswer handlerScriptAnswer = null; private ScriptAnswer handlerScriptAnswer = null;
private RequestPayPrice handlerRequestPayPrice = null;
/* Properties */ /* Properties */
@ -791,6 +792,7 @@ namespace OpenSim.Region.ClientStack
public event UUIDNameRequest OnTeleportHomeRequest; public event UUIDNameRequest OnTeleportHomeRequest;
public event ScriptAnswer OnScriptAnswer; public event ScriptAnswer OnScriptAnswer;
public event RequestPayPrice OnRequestPayPrice;
#region Scene/Avatar to Client #region Scene/Avatar to Client
@ -1167,6 +1169,32 @@ namespace OpenSim.Region.ClientStack
OutPacket(money, ThrottleOutPacketType.Task); OutPacket(money, ThrottleOutPacketType.Task);
} }
public void SendPayPrice(LLUUID objectID, int[] payPrice)
{
if(payPrice[0] == 0 &&
payPrice[1] == 0 &&
payPrice[2] == 0 &&
payPrice[3] == 0 &&
payPrice[4] == 0)
return;
PayPriceReplyPacket payPriceReply = (PayPriceReplyPacket)PacketPool.Instance.GetPacket(PacketType.PayPriceReply);
payPriceReply.ObjectData.ObjectID = objectID;
payPriceReply.ObjectData.DefaultPayPrice = payPrice[0];
payPriceReply.ButtonData=new PayPriceReplyPacket.ButtonDataBlock[4];
payPriceReply.ButtonData[0]=new PayPriceReplyPacket.ButtonDataBlock();
payPriceReply.ButtonData[0].PayButton = payPrice[1];
payPriceReply.ButtonData[1]=new PayPriceReplyPacket.ButtonDataBlock();
payPriceReply.ButtonData[1].PayButton = payPrice[2];
payPriceReply.ButtonData[2]=new PayPriceReplyPacket.ButtonDataBlock();
payPriceReply.ButtonData[2].PayButton = payPrice[3];
payPriceReply.ButtonData[3]=new PayPriceReplyPacket.ButtonDataBlock();
payPriceReply.ButtonData[3].PayButton = payPrice[4];
OutPacket(payPriceReply, ThrottleOutPacketType.Task);
}
public void SendStartPingCheck(byte seq) public void SendStartPingCheck(byte seq)
{ {
StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck); StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck);
@ -4555,6 +4583,14 @@ namespace OpenSim.Region.ClientStack
// TODO: handle this packet // TODO: handle this packet
//m_log.Warn("[CLIENT]: unhandled EconomyDataRequest packet"); //m_log.Warn("[CLIENT]: unhandled EconomyDataRequest packet");
break; break;
case PacketType.RequestPayPrice:
RequestPayPricePacket requestPayPricePacket = (RequestPayPricePacket)Pack;
handlerRequestPayPrice = OnRequestPayPrice;
if (handlerRequestPayPrice != null)
{
handlerRequestPayPrice(this, requestPayPricePacket.ObjectData.ObjectID);
}
break;
#endregion #endregion

View File

@ -53,8 +53,22 @@ namespace OpenSim.Region.Environment.Modules
/// Centralized grid structure example using OpenSimWi Redux revision 9+ /// Centralized grid structure example using OpenSimWi Redux revision 9+
/// svn co https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux /// svn co https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux
/// </summary> /// </summary>
public class BetaGridLikeMoneyModule: IRegionModule
public delegate void ObjectPaid(LLUUID objectID, LLUUID agentID, int amount);
public interface IMoneyModule : IRegionModule
{
bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount);
event ObjectPaid OnObjectPaid;
}
public class BetaGridLikeMoneyModule: IMoneyModule
{ {
public event ObjectPaid OnObjectPaid;
private ObjectPaid handerOnObjectPaid;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary> /// <summary>
@ -120,7 +134,7 @@ namespace OpenSim.Region.Environment.Modules
IConfig startupConfig = m_gConfig.Configs["Startup"]; IConfig startupConfig = m_gConfig.Configs["Startup"];
IConfig economyConfig = m_gConfig.Configs["Economy"]; IConfig economyConfig = m_gConfig.Configs["Economy"];
scene.RegisterModuleInterface<IMoneyModule>(this);
ReadConfigAndPopulate(scene, startupConfig, "Startup"); ReadConfigAndPopulate(scene, startupConfig, "Startup");
ReadConfigAndPopulate(scene, economyConfig, "Economy"); ReadConfigAndPopulate(scene, economyConfig, "Economy");
@ -298,6 +312,7 @@ namespace OpenSim.Region.Environment.Modules
// Subscribe to Money messages // Subscribe to Money messages
client.OnEconomyDataRequest += EconomyDataRequestHandler; client.OnEconomyDataRequest += EconomyDataRequestHandler;
client.OnMoneyBalanceRequest += SendMoneyBalance; client.OnMoneyBalanceRequest += SendMoneyBalance;
client.OnRequestPayPrice += requestPayPrice;
client.OnLogout += ClientClosed; client.OnLogout += ClientClosed;
@ -305,6 +320,21 @@ namespace OpenSim.Region.Environment.Modules
#region event Handlers #region event Handlers
public void requestPayPrice(IClientAPI client, LLUUID objectID)
{
Scene scene=LocateSceneClientIn(client.AgentId);
if(scene == null)
return;
SceneObjectPart task=scene.GetSceneObjectPart(objectID);
if(task == null)
return;
SceneObjectGroup group=task.ParentGroup;
SceneObjectPart root=group.RootPart;
client.SendPayPrice(objectID, root.PayPrice);
}
/// <summary> /// <summary>
/// When the client closes the connection we remove their accounting info from memory to free up resources. /// When the client closes the connection we remove their accounting info from memory to free up resources.
/// </summary> /// </summary>
@ -400,6 +430,48 @@ namespace OpenSim.Region.Environment.Modules
IClientAPI sender = null; IClientAPI sender = null;
IClientAPI receiver = null; IClientAPI receiver = null;
if(m_MoneyAddress.Length > 0) // Handled on server
e.description=String.Empty;
if(e.transactiontype == 5008) // Object gets paid
{
sender = LocateClientObject(e.sender);
if (sender != null)
{
SceneObjectPart part=findPrim(e.receiver);
if(part == null)
return;
string name=resolveAgentName(part.OwnerID);
if(name == String.Empty)
name="(hippos)";
receiver = LocateClientObject(part.OwnerID);
string description=String.Format("Paid {0} via object {1}", name, e.description);
bool transactionresult = doMoneyTransfer(e.sender, part.OwnerID, e.amount, e.transactiontype, description);
if(transactionresult)
{
ObjectPaid handlerOnObjectPaid = OnObjectPaid;
if(handlerOnObjectPaid != null)
{
handlerOnObjectPaid(e.receiver, e.sender, e.amount);
}
}
if (e.sender != e.receiver)
{
sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender));
}
if(receiver != null)
{
receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(part.OwnerID));
}
}
return;
}
sender = LocateClientObject(e.sender); sender = LocateClientObject(e.sender);
if (sender != null) if (sender != null)
{ {
@ -923,6 +995,51 @@ namespace OpenSim.Region.Environment.Modules
return MoneyRespData; return MoneyRespData;
} }
private SceneObjectPart findPrim(LLUUID objectID)
{
lock (m_scenel)
{
foreach (Scene s in m_scenel.Values)
{
SceneObjectPart part=s.GetSceneObjectPart(objectID);
if(part != null)
{
return part;
}
}
}
return null;
}
private string resolveObjectName(LLUUID objectID)
{
SceneObjectPart part=findPrim(objectID);
if(part != null)
{
return part.Name;
}
return String.Empty;
}
private string resolveAgentName(LLUUID agentID)
{
// try avatar username surname
Scene scene=GetRandomScene();
UserProfileData profile = scene.CommsManager.UserService.GetUserProfile(agentID);
if (profile != null)
{
string avatarname = profile.FirstName + " " + profile.SurName;
return avatarname;
}
return String.Empty;
}
public bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount)
{
string description=String.Format("Object {0} pays {1}", resolveObjectName(objectID), resolveAgentName(toID));
return doMoneyTransfer(fromID, toID, amount, 2, description);
}
/// <summary> /// <summary>
/// Informs the Money Grid Server of a transfer. /// Informs the Money Grid Server of a transfer.
/// </summary> /// </summary>

View File

@ -96,6 +96,8 @@ namespace OpenSim.Region.Environment.Scenes
public int SalePrice; public int SalePrice;
public uint Category; public uint Category;
// TODO: This needs to be persisted in next XML version update!
[XmlIgnore] public int[] PayPrice = {0,0,0,0,0};
public Int32 CreationDate; public Int32 CreationDate;
public uint ParentID = 0; public uint ParentID = 0;
@ -2456,6 +2458,7 @@ namespace OpenSim.Region.Environment.Scenes
info.AddValue("m_clickAction", m_clickAction); info.AddValue("m_clickAction", m_clickAction);
info.AddValue("m_shape", m_shape); info.AddValue("m_shape", m_shape);
info.AddValue("m_parentGroup", m_parentGroup); info.AddValue("m_parentGroup", m_parentGroup);
info.AddValue("PayPrice", PayPrice);
} }
} }

View File

@ -167,6 +167,7 @@ namespace OpenSim.Region.Examples.SimpleModule
public event UUIDNameRequest OnTeleportHomeRequest; public event UUIDNameRequest OnTeleportHomeRequest;
public event ScriptAnswer OnScriptAnswer; public event ScriptAnswer OnScriptAnswer;
public event RequestPayPrice OnRequestPayPrice;
#pragma warning restore 67 #pragma warning restore 67
@ -342,6 +343,10 @@ namespace OpenSim.Region.Examples.SimpleModule
{ {
} }
public virtual void SendPayPrice(LLUUID objectID, int[] payPrice)
{
}
public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID,
uint avatarLocalID, LLVector3 Pos, byte[] textureEntry, uint parentID) uint avatarLocalID, LLVector3 Pos, byte[] textureEntry, uint parentID)
{ {

View File

@ -36,6 +36,7 @@ using libsecondlife;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Environment; using OpenSim.Region.Environment;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Modules;
using OpenSim.Region.Environment.Modules.LandManagement; using OpenSim.Region.Environment.Modules.LandManagement;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase; using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase;
@ -1609,8 +1610,42 @@ namespace OpenSim.Region.ScriptEngine.Common
public int llGiveMoney(string destination, int amount) public int llGiveMoney(string destination, int amount)
{ {
LLUUID invItemID=InventorySelf();
if(invItemID == LLUUID.Zero)
return 0;
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
NotImplemented("llGiveMoney");
if(m_host.TaskInventory[invItemID].PermsGranter == LLUUID.Zero)
return 0;
if((m_host.TaskInventory[invItemID].PermsMask & BuiltIn_Commands_BaseClass.PERMISSION_DEBIT) == 0)
{
LSLError("No permissions to give money");
return 0;
}
LLUUID toID=new LLUUID();
if(!LLUUID.TryParse(destination, out toID))
{
LSLError("Bad key in llGiveMoney");
return 0;
}
IMoneyModule money=World.RequestModuleInterface<IMoneyModule>();
if(money == null)
{
NotImplemented("llGiveMoney");
return 0;
}
bool result=money.ObjectGiveMoney(m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
if(result)
return 1;
return 0; return 0;
} }
@ -5101,7 +5136,17 @@ namespace OpenSim.Region.ScriptEngine.Common
public void llSetPayPrice(int price, LSL_Types.list quick_pay_buttons) public void llSetPayPrice(int price, LSL_Types.list quick_pay_buttons)
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
NotImplemented("llSetPayPrice");
if(quick_pay_buttons.Data.Length != 4)
{
LSLError("List must have 4 elements");
return;
}
m_host.ParentGroup.RootPart.PayPrice[0]=price;
m_host.ParentGroup.RootPart.PayPrice[1]=(int)quick_pay_buttons.Data[0];
m_host.ParentGroup.RootPart.PayPrice[2]=(int)quick_pay_buttons.Data[1];
m_host.ParentGroup.RootPart.PayPrice[3]=(int)quick_pay_buttons.Data[2];
m_host.ParentGroup.RootPart.PayPrice[4]=(int)quick_pay_buttons.Data[3];
} }
public LSL_Types.Vector3 llGetCameraPos() public LSL_Types.Vector3 llGetCameraPos()

View File

@ -28,6 +28,9 @@
using System; using System;
using libsecondlife; using libsecondlife;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Environment;
using OpenSim.Region.Environment.Modules;
using OpenSim.Region.Environment.Scenes;
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{ {
@ -68,6 +71,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript; myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript;
myScriptEngine.World.EventManager.OnScriptChangedEvent += changed; myScriptEngine.World.EventManager.OnScriptChangedEvent += changed;
// TODO: HOOK ALL EVENTS UP TO SERVER! // TODO: HOOK ALL EVENTS UP TO SERVER!
IMoneyModule money=myScriptEngine.World.RequestModuleInterface<IMoneyModule>();
if(money != null)
{
money.OnObjectPaid+=HandleObjectPaid;
}
} }
} }
@ -75,6 +84,15 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
{ {
} }
private void HandleObjectPaid(LLUUID objectID, LLUUID agentID, int amount)
{
SceneObjectPart part=myScriptEngine.World.GetSceneObjectPart(objectID);
if(part != null)
{
money(part.LocalId, agentID, amount);
}
}
public void changed(uint localID, uint change) public void changed(uint localID, uint change)
{ {
// Add to queue for all scripts in localID, Object pass change. // Add to queue for all scripts in localID, Object pass change.
@ -112,6 +130,11 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
); );
} }
public void money(uint localID, LLUUID agentID, int amount)
{
myScriptEngine.m_EventQueueManager.AddToObjectQueue(localID, "money", EventQueueManager.llDetectNull, new object[] { agentID.ToString(), (int)amount });
}
// TODO: Replace placeholders below // TODO: Replace placeholders below
// NOTE! THE PARAMETERS FOR THESE FUNCTIONS ARE NOT CORRECT! // NOTE! THE PARAMETERS FOR THESE FUNCTIONS ARE NOT CORRECT!
// These needs to be hooked up to OpenSim during init of this class // These needs to be hooked up to OpenSim during init of this class
@ -194,11 +217,6 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "control", EventQueueManager.llDetectNull); myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "control", EventQueueManager.llDetectNull);
} }
public void money(uint localID, LLUUID itemID)
{
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "money", EventQueueManager.llDetectNull);
}
public void email(uint localID, LLUUID itemID) public void email(uint localID, LLUUID itemID)
{ {
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "email", EventQueueManager.llDetectNull); myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "email", EventQueueManager.llDetectNull);

View File

@ -55,7 +55,7 @@ namespace OpenSim.Region.ScriptEngine.Common
void sensor(uint localID, LLUUID itemID); void sensor(uint localID, LLUUID itemID);
void no_sensor(uint localID, LLUUID itemID); void no_sensor(uint localID, LLUUID itemID);
void control(uint localID, LLUUID itemID); void control(uint localID, LLUUID itemID);
void money(uint localID, LLUUID itemID); void money(uint LocalID, LLUUID agentID, int amount);
void email(uint localID, LLUUID itemID); void email(uint localID, LLUUID itemID);
void at_target(uint localID, LLUUID itemID); void at_target(uint localID, LLUUID itemID);
void not_at_target(uint localID, LLUUID itemID); void not_at_target(uint localID, LLUUID itemID);