From ca5aadfbff63e03b7ca081e753204d8da040c9bb Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Tue, 5 Feb 2008 05:26:18 +0000 Subject: * Refactored the sound calls to SceneObjectPart * Fixed a few bugs * Wrote an example module to make certain event systems more mature. --- .../Environment/Modules/BetaGridLikeMoneyModule.cs | 324 +++++++++++++++++++++ OpenSim/Region/Environment/Scenes/Scene.cs | 2 + OpenSim/Region/Environment/Scenes/SceneEvents.cs | 12 + .../Region/Environment/Scenes/SceneObjectPart.cs | 78 +++++ 4 files changed, 416 insertions(+) create mode 100644 OpenSim/Region/Environment/Modules/BetaGridLikeMoneyModule.cs (limited to 'OpenSim/Region/Environment') diff --git a/OpenSim/Region/Environment/Modules/BetaGridLikeMoneyModule.cs b/OpenSim/Region/Environment/Modules/BetaGridLikeMoneyModule.cs new file mode 100644 index 0000000..81478a1 --- /dev/null +++ b/OpenSim/Region/Environment/Modules/BetaGridLikeMoneyModule.cs @@ -0,0 +1,324 @@ +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + +using Nini.Config; +using System; +using System.Collections; +using System.Collections.Generic; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Region.Environment.Interfaces; +using OpenSim.Region.Environment.Scenes; +using libsecondlife; +using MoneyTransferArgs = OpenSim.Region.Environment.Scenes.EventManager.MoneyTransferArgs; + +namespace OpenSim.Region.Environment.Modules +{ + public class BetaGridLikeMoneyModule: IRegionModule + { + + private LogBase m_log; + + private Dictionary m_scenel = new Dictionary(); + + private IConfigSource m_gConfig; + + private bool m_keepMoneyAcrossLogins = true; + + private int m_minFundsBeforeRefresh = 100; + + private int m_stipend = 1000; + + private bool m_enabled = true; + + + + private Dictionary m_KnownClientFunds = new Dictionary(); + + + + private bool gridmode = false; + + public void Initialise(Scene scene, IConfigSource config) + { + m_log = MainLog.Instance; + + m_gConfig = config; + ReadConfigAndPopulate(); + + if (m_enabled) + { + lock (m_scenel) + { + + if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle)) + { + m_scenel[scene.RegionInfo.RegionHandle] = scene; + } + else + { + m_scenel.Add(scene.RegionInfo.RegionHandle, scene); + } + } + + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnMoneyTransfer += MoneyTransferAction; + scene.EventManager.OnClientClosed += ClientClosed; + } + } + private void ReadConfigAndPopulate() + { + IConfig startupConfig = m_gConfig.Configs["Startup"]; + gridmode = startupConfig.GetBoolean("gridmode", false); + m_enabled = (startupConfig.GetString("moneymodule", "BetaGridLikeMoneyModule") == "BetaGridLikeMoneyModule"); + + } + + private void OnNewClient(IClientAPI client) + { + // Here we check if we're in grid mode + // I imagine that the 'check balance' + // function for the client should be here or shortly after + + if (gridmode) + { + CheckExistAndRefreshFunds(client.AgentId); + } + else + { + CheckExistAndRefreshFunds(client.AgentId); + } + + // Subscribe to Money messages + client.OnMoneyBalanceRequest += SendMoneyBalance; + client.OnLogout += ClientClosed; + + } + + public void ClientClosed(LLUUID AgentID) + { + lock (m_KnownClientFunds) + { + if (!m_keepMoneyAcrossLogins) + m_KnownClientFunds.Remove(AgentID); + } + + } + + private void MoneyTransferAction (Object osender, MoneyTransferArgs e) + { + IClientAPI sender = null; + IClientAPI receiver = null; + + sender = LocateClientObject(e.sender); + if (sender != null) + { + + + receiver = LocateClientObject(e.reciever); + bool transactionresult = doMoneyTranfer(e.sender, e.reciever, e.amount); + + if (e.sender != e.reciever) + { + if (sender != null) + { + 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(e.reciever)); + } + + + } + else + { + MainLog.Instance.Warn("MONEY", "Potential Fraud Warning, got money transfer request for avatar that isn't in this simulator - Details; Sender:" + e.sender.ToString() + " Reciver: " + e.reciever.ToString() + " Amount: " + e.amount.ToString()); + } + + + + } + + private bool doMoneyTranfer(LLUUID Sender, LLUUID Receiver, int amount) + { + bool result = false; + if (amount >= 0) + { + lock (m_KnownClientFunds) + { + // If we don't know about the sender, then the sender can't + // actually be here and therefore this is likely fraud or outdated. + if (m_KnownClientFunds.ContainsKey(Sender)) + { + // Does the sender have enough funds to give? + if (m_KnownClientFunds[Sender] >= amount) + { + // Subtract the funds from the senders account + m_KnownClientFunds[Sender] -= amount; + + // do we know about the receiver? + if (!m_KnownClientFunds.ContainsKey(Receiver)) + { + // Make a record for them so they get the updated balance when they login + CheckExistAndRefreshFunds(Receiver); + } + + //Add the amount to the Receiver's funds + m_KnownClientFunds[Receiver] += amount; + result = true; + } + else + { + // These below are redundant to make this clearer to read + result = false; + } + } + else + { + result = false; + } + } + } + return result; + } + + private IClientAPI LocateClientObject(LLUUID AgentID) + { + ScenePresence tPresence = null; + IClientAPI rclient = null; + + lock (m_scenel) + { + foreach (Scene _scene in m_scenel.Values) + { + tPresence = _scene.GetScenePresence(AgentID); + if (tPresence != null) + { + if (!tPresence.IsChildAgent) + { + rclient = tPresence.ControllingClient; + } + } + if (rclient != null) + { + return rclient; + } + } + + } + return null; + } + + public void ClientClosed(IClientAPI client) + { + ClientClosed(client.AgentId); + } + + public void SendMoneyBalance(IClientAPI client, LLUUID agentID, LLUUID SessionID, LLUUID TransactionID) + { + if (client.AgentId == agentID && client.SessionId == SessionID) + { + + int returnfunds = 0; + + try + { + returnfunds = GetFundsForAgentID(agentID); + } + catch (System.Exception e) + { + client.SendAlertMessage(e.Message + " "); + } + + client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds); + } + else + { + client.SendAlertMessage("Unable to send your money balance to you!"); + } + } + + private void CheckExistAndRefreshFunds(LLUUID agentID) + { + lock (m_KnownClientFunds) + { + if (!m_KnownClientFunds.ContainsKey(agentID)) + { + m_KnownClientFunds.Add(agentID, m_stipend); + } + else + { + if (m_KnownClientFunds[agentID] <= m_minFundsBeforeRefresh) + { + m_KnownClientFunds[agentID] = m_stipend; + } + } + } + } + private int GetFundsForAgentID(LLUUID AgentID) + { + int returnfunds = 0; + lock (m_KnownClientFunds) + { + if (m_KnownClientFunds.ContainsKey(AgentID)) + { + returnfunds = m_KnownClientFunds[AgentID]; + } + else + { + throw new Exception("Unable to get funds."); + } + } + return returnfunds; + } + + public void PostInitialise() + { + } + + + + public void Close() + { + } + + public string Name + { + get { return "BetaGridLikeMoneyModule"; } + } + + public bool IsSharedModule + { + get { return true; } + } + } + +} diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 89fd5ea..a80426b 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1315,6 +1315,8 @@ namespace OpenSim.Region.Environment.Scenes avatar.AbsolutePosition.Z); m_sceneGridService.SendCloseChildAgentConnections(avatar); } + + m_eventManager.TriggerClientClosed(agentID); } catch (NullReferenceException) { diff --git a/OpenSim/Region/Environment/Scenes/SceneEvents.cs b/OpenSim/Region/Environment/Scenes/SceneEvents.cs index 51d1b32..cada991 100644 --- a/OpenSim/Region/Environment/Scenes/SceneEvents.cs +++ b/OpenSim/Region/Environment/Scenes/SceneEvents.cs @@ -125,6 +125,10 @@ namespace OpenSim.Region.Environment.Scenes public event NewGridInstantMessage OnGridInstantMessageToGroupsModule; + public delegate void ClientClosed(LLUUID clientID); + + public event ClientClosed OnClientClosed; + public delegate void ScriptChangedEvent(uint localID, uint change); public event ScriptChangedEvent OnScriptChangedEvent; @@ -338,6 +342,14 @@ namespace OpenSim.Region.Environment.Scenes } } + + public void TriggerClientClosed(LLUUID ClientID) + { + if (OnClientClosed != null) + { + OnClientClosed(ClientID); + } + } } } \ No newline at end of file diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 159eaf1..0ba64f2 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -1457,6 +1457,84 @@ namespace OpenSim.Region.Environment.Scenes #endregion + #region Sound + public void PreloadSound(string sound) + { + LLUUID ownerID = OwnerID; + LLUUID objectID = UUID; + LLUUID soundID = LLUUID.Zero; + + if (!LLUUID.TryParse(sound, out soundID)) + { + //Trys to fetch sound id from prim's inventory. + //Prim's inventory doesn't support non script items yet + SceneObjectPart op = this; + foreach (KeyValuePair item in op.TaskInventory) + { + if (item.Value.Name == sound) + { + soundID = item.Value.ItemID; + break; + } + } + } + + List avatarts = m_parentGroup.Scene.GetAvatars(); + foreach (ScenePresence p in avatarts) + { + // TODO: some filtering by distance of avatar + + p.ControllingClient.SendPreLoadSound(objectID, objectID, soundID); + } + } + + public void SendSound(string sound, double volume, bool triggered) + { + if (volume > 1) + volume = 1; + if (volume < 0) + volume = 0; + + LLUUID ownerID = OwnerID; + LLUUID objectID = UUID; + LLUUID parentID = GetRootPartUUID(); + LLUUID soundID = LLUUID.Zero; + LLVector3 position = AbsolutePosition; // region local + ulong regionHandle = m_parentGroup.Scene.RegionInfo.RegionHandle; + + byte flags = 0; + + if (!LLUUID.TryParse(sound, out soundID)) + { + // search sound file from inventory + SceneObjectPart op = this; + foreach (KeyValuePair item in op.TaskInventory) + { + if (item.Value.Name == sound) + { + soundID = item.Value.ItemID; + break; + } + } + } + + List avatarts = m_parentGroup.Scene.GetAvatars(); + foreach (ScenePresence p in avatarts) + { + // TODO: some filtering by distance of avatar + if (triggered) + { + p.ControllingClient.SendTriggeredSound(soundID, ownerID, objectID, parentID, regionHandle, position, (float)volume); + } + else + { + p.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)volume, flags); + } + } + } + + #endregion + #region Resizing/Scale /// -- cgit v1.1