//
// Radegast Metaverse Client
//Copyright (c) 2009-2014, Radegast Development Team
// All rights reserved.
//
// 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 application "Radegast", 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR 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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace Radegast.Automation
{
public class LSLHelper : IDisposable
{
public bool Enabled;
public UUID AllowedOwner;
RadegastInstance instance;
GridClient client
{
get { return instance.Client; }
}
public LSLHelper(RadegastInstance instance)
{
this.instance = instance;
}
public void Dispose()
{
}
public void LoadSettings()
{
if (!client.Network.Connected) return;
try
{
if (!(instance.ClientSettings["LSLHelper"] is OSDMap))
return;
OSDMap map = (OSDMap)instance.ClientSettings["LSLHelper"];
Enabled = map["enabled"];
AllowedOwner = map["allowed_owner"];
}
catch { }
}
public void SaveSettings()
{
if (!client.Network.Connected) return;
try
{
OSDMap map = new OSDMap(2);
map["enabled"] = Enabled;
map["allowed_owner"] = AllowedOwner;
instance.ClientSettings["LSLHelper"] = map;
}
catch { }
}
///
/// Dispatcher for incoming IM automation
///
/// Incoming message
/// If message processed correctly, should GUI processing be halted
public bool ProcessIM(InstantMessageEventArgs e)
{
LoadSettings();
if (!Enabled)
{
return false;
}
switch (e.IM.Dialog)
{
case InstantMessageDialog.MessageFromObject:
{
if (e.IM.FromAgentID != AllowedOwner)
{
return true;
}
string[] args = e.IM.Message.Trim().Split('^');
if (args.Length < 1) return false;
switch (args[0].Trim())
{
case "group_invite":
{
if (args.Length < 4) return false;
ProcessInvite(args);
return true;
}
case "send_im":
{
if (args.Length < 3) return false;
UUID sendTo = UUID.Zero;
if (!UUID.TryParse(args[1].Trim(), out sendTo)) return false;
string msg = args[2].Trim();
client.Self.InstantMessage(sendTo, msg);
return true;
}
case "give_inventory":
{
if (args.Length < 3) return false;
UUID sendTo = UUID.Zero;
UUID invItemID = UUID.Zero;
if (!UUID.TryParse(args[1].Trim(), out sendTo)) return false;
if (!UUID.TryParse(args[2].Trim(), out invItemID)) return false;
if (!client.Inventory.Store.Contains(invItemID))
{
instance.TabConsole.DisplayNotificationInChat(
string.Format("Tried to offer {0} but could not find it in my inventory", invItemID),
ChatBufferTextStyle.Error);
return false;
}
InventoryItem item = client.Inventory.Store[invItemID] as InventoryItem;
if (item == null)
return false;
client.Inventory.GiveItem(item.UUID, item.Name, item.AssetType, sendTo, true);
WorkPool.QueueUserWorkItem(sync =>
instance.TabConsole.DisplayNotificationInChat(
string.Format("Gave {0} to {1}", item.Name, instance.Names.Get(sendTo, true)),
ChatBufferTextStyle.ObjectChat)
);
return true;
}
}
}
break;
}
return false;
}
private void ProcessInvite(string[] args)
{
if (args == null || args.Length < 4)
return;
WorkPool.QueueUserWorkItem(sync =>
{
try
{
UUID invitee = UUID.Zero;
UUID groupID = UUID.Zero;
UUID roleID = UUID.Zero;
if (!UUID.TryParse(args[1].Trim(), out invitee)) return;
if (!UUID.TryParse(args[2].Trim(), out groupID)) return;
if (!UUID.TryParse(args[3].Trim(), out roleID)) return;
if (instance.Groups.ContainsKey(groupID))
{
AutoResetEvent gotMembers = new AutoResetEvent(false);
Dictionary Members = null;
EventHandler handler = (sender, e) =>
{
if (e.GroupID != groupID)
return;
Members = e.Members;
gotMembers.Set();
};
client.Groups.GroupMembersReply += handler;
client.Groups.RequestGroupMembers(groupID);
bool success = gotMembers.WaitOne(30 * 1000, false);
client.Groups.GroupMembersReply -= handler;
if (Members != null && Members.ContainsKey(invitee))
{
instance.TabConsole.DisplayNotificationInChat(
string.Format("Not inviting {0} ({1}) to {2} ({3}), already member", instance.Names.Get(invitee, true), invitee, instance.Groups[groupID].Name, groupID),
ChatBufferTextStyle.ObjectChat);
}
else
{
instance.TabConsole.DisplayNotificationInChat(
string.Format("Inviting {0} ({1}) to {2} ({3})", instance.Names.Get(invitee, true), invitee, instance.Groups[groupID].Name, groupID),
ChatBufferTextStyle.ObjectChat);
client.Groups.Invite(groupID, new List(1) { roleID }, invitee);
}
}
else
{
instance.TabConsole.DisplayNotificationInChat(
string.Format("Cannot invite to group {0}, I don't appear to be in it.", groupID),
ChatBufferTextStyle.Error);
}
}
catch (Exception ex)
{
Logger.Log("Failed proccessing automation IM: " + ex.ToString(), Helpers.LogLevel.Warning);
}
});
}
}
}