/* * Copyright (c) 2006-2007, Second Life Reverse Engineering 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. * - Neither the name of the Second Life Reverse Engineering Team 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 OWNER 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 libsecondlife.Packets; using System.Collections.Generic; namespace libsecondlife { /// /// Estate level administration and utilities /// public class EstateTools { private SecondLife Client; public GroundTextureSettings GroundTextures; /// /// Triggered on incoming LandStatReply /// /// /// /// /// //public delegate void LandStatReply(LandStatReportType reportType, uint requestFlags, int objectCount, List Tasks); /// /// Triggered on incoming LandStatReply when the report type is for "top colliders" /// /// /// public delegate void GetTopCollidersReply(int objectCount, List Tasks); /// /// Triggered on incoming LandStatReply when the report type is for "top scripts" /// /// /// public delegate void GetTopScriptsReply(int objectCount, List Tasks); /// Callback for incoming LandStatReply packets //public event LandStatReply OnLandStatReply; /// Triggered upon a successful .GetTopColliders() public event GetTopCollidersReply OnGetTopColliders; /// Triggered upon a successful .GetTopScripts() public event GetTopScriptsReply OnGetTopScripts; /// /// Constructor for EstateTools class /// /// public EstateTools(SecondLife client) { Client = client; Client.Network.RegisterCallback(PacketType.LandStatReply, new NetworkManager.PacketCallback(LandStatReplyHandler)); //Client.Network.RegisterCallback(PacketType.EstateOwnerMessage, new NetworkManager.PacketCallback(EstateOwnerMessageHandler)); } /// Describes tasks returned in LandStatReply public class EstateTask { public LLVector3 Position; public float Score; public LLUUID TaskID; public uint TaskLocalID; public string TaskName; public string OwnerName; } /// Used in the ReportType field of a LandStatRequest public enum LandStatReportType { TopScripts = 0, TopColliders = 1 } /// Used by EstateOwnerMessage packets public enum EstateAccessDelta { BanUser = 64, UnbanUser = 128 } /// Used by GroundTextureSettings public class GroundTextureRegion { public LLUUID TextureID; public float Low; public float High; } /// Ground texture settings for each corner of the region public class GroundTextureSettings { public GroundTextureRegion Southwest; public GroundTextureRegion Northwest; public GroundTextureRegion Southeast; public GroundTextureRegion Northeast; } /// /// Requests estate information such as top scripts and colliders /// /// /// /// /// public void LandStatRequest(int parcelLocalID, LandStatReportType reportType, uint requestFlags, string filter) { LandStatRequestPacket p = new LandStatRequestPacket(); p.AgentData.AgentID = Client.Self.AgentID; p.AgentData.SessionID = Client.Self.SessionID; p.RequestData.Filter = Helpers.StringToField(filter); p.RequestData.ParcelLocalID = parcelLocalID; p.RequestData.ReportType = (uint)reportType; p.RequestData.RequestFlags = requestFlags; Client.Network.SendPacket(p); } /// Requests the "Top Scripts" list for the current region public void GetTopScripts() { //EstateOwnerMessage("scripts", ""); LandStatRequest(0, LandStatReportType.TopScripts, 0, ""); } /// Requests the "Top Colliders" list for the current region public void GetTopColliders() { //EstateOwnerMessage("colliders", ""); LandStatRequest(0, LandStatReportType.TopColliders, 0, ""); } /// /// /// private void EstateOwnerMessageHandler(Packet packet, Simulator simulator) { EstateOwnerMessagePacket message = (EstateOwnerMessagePacket)packet; string method = Helpers.FieldToUTF8String(message.MethodData.Method); //FIXME - remove debug output Console.WriteLine("--- " + method + " ---"); foreach (EstateOwnerMessagePacket.ParamListBlock block in message.ParamList) { Console.WriteLine(Helpers.FieldToUTF8String(block.Parameter)); } Console.WriteLine("------"); } /// /// /// private void LandStatReplyHandler(Packet packet, Simulator simulator) { //if (OnLandStatReply != null || OnGetTopScripts != null || OnGetTopColliders != null) if (OnGetTopScripts != null || OnGetTopColliders != null) { LandStatReplyPacket p = (LandStatReplyPacket)packet; List Tasks = new List(); foreach (LandStatReplyPacket.ReportDataBlock rep in p.ReportData) { EstateTask task = new EstateTask(); task.Position = new LLVector3(rep.LocationX, rep.LocationY, rep.LocationZ); task.Score = rep.Score; task.TaskID = rep.TaskID; task.TaskLocalID = rep.TaskLocalID; task.TaskName = Helpers.FieldToUTF8String(rep.TaskName); task.OwnerName = Helpers.FieldToUTF8String(rep.OwnerName); Tasks.Add(task); } LandStatReportType type = (LandStatReportType)p.RequestData.ReportType; if (OnGetTopScripts != null && type == LandStatReportType.TopScripts) { OnGetTopScripts((int)p.RequestData.TotalObjectCount, Tasks); } else if (OnGetTopColliders != null && type == LandStatReportType.TopColliders) { OnGetTopColliders((int)p.RequestData.TotalObjectCount, Tasks); } /* if (OnGetTopColliders != null) { //FIXME - System.UnhandledExceptionEventArgs OnLandStatReply( type, p.RequestData.RequestFlags, (int)p.RequestData.TotalObjectCount, Tasks ); } */ } } public void EstateOwnerMessage(string method, string param) { List listParams = new List(); listParams.Add(param); EstateOwnerMessage(method, listParams); } /// /// Used for setting and retrieving various estate panel settings /// /// EstateOwnerMessage Method field /// List of parameters to include public void EstateOwnerMessage(string method, ListlistParams) { EstateOwnerMessagePacket estate = new EstateOwnerMessagePacket(); estate.AgentData.AgentID = Client.Self.AgentID; estate.AgentData.SessionID = Client.Self.SessionID; estate.MethodData.Invoice = LLUUID.Random(); estate.MethodData.Method = Helpers.StringToField(method); estate.ParamList = new EstateOwnerMessagePacket.ParamListBlock[listParams.Count]; for (int i = 0; i < listParams.Count; i++) { estate.ParamList[i] = new EstateOwnerMessagePacket.ParamListBlock(); estate.ParamList[i].Parameter = Helpers.StringToField(listParams[i]); } Client.Network.SendPacket((Packet)estate); } /// /// Kick an avatar from an estate /// /// Key of Agent to remove public void KickUser(LLUUID userID) { EstateOwnerMessage("kickestate", userID.ToString()); } /// Ban an avatar from an estate /// Key of Agent to remove public void BanUser(LLUUID userID) { List listParams = new List(); uint flag = (uint)EstateAccessDelta.BanUser; listParams.Add(Client.Self.AgentID.ToString()); listParams.Add(flag.ToString()); listParams.Add(userID.ToString()); EstateOwnerMessage("estateaccessdelta", listParams); } /// Unban an avatar from an estate /// Key of Agent to remove public void UnbanUser(LLUUID userID) { List listParams = new List(); uint flag = (uint)EstateAccessDelta.BanUser; listParams.Add(Client.Self.AgentID.ToString()); listParams.Add(flag.ToString()); listParams.Add(userID.ToString()); EstateOwnerMessage("estateaccessdelta", listParams); } /// /// Send a message dialog to everyone in an entire estate /// /// Message to send all users in the estate public void EstateMessage(string message) { List listParams = new List(); listParams.Add(Client.Self.FirstName + " " + Client.Self.LastName); listParams.Add(message); EstateOwnerMessage("instantmessage", listParams); } /// /// Send a message dialog to everyone in a simulator /// /// Message to send all users in the simulator public void SimulatorMessage(string message) { List listParams = new List(); listParams.Add("-1"); listParams.Add("-1"); listParams.Add(Client.Self.AgentID.ToString()); listParams.Add(Client.Self.FirstName + " " + Client.Self.LastName); listParams.Add(message); EstateOwnerMessage("simulatormessage", listParams); } /// /// Send an avatar back to their home location /// /// Key of avatar to send home public void TeleportHomeUser(LLUUID pest) { List listParams = new List(); listParams.Add(Client.Self.AgentID.ToString()); listParams.Add(pest.ToString()); EstateOwnerMessage("teleporthomeuser", listParams); } /// /// Begin the region restart process /// public void RestartRegion() { EstateOwnerMessage("restart", "120"); } /// /// Cancels a region restart /// public void CancelRestart() { EstateOwnerMessage("restart", "-1"); } /// Estate panel "Region" tab settings public void SetRegionInfo(bool blockTerraform, bool blockFly, bool allowDamage, bool allowLandResell, bool restrictPushing, bool allowParcelJoinDivide, float agentLimit, float objectBonus, bool mature) { List listParams = new List(); if (blockTerraform) listParams.Add("Y"); else listParams.Add("N"); if (blockFly) listParams.Add("Y"); else listParams.Add("N"); if (allowDamage) listParams.Add("Y"); else listParams.Add("N"); if (allowLandResell) listParams.Add("Y"); else listParams.Add("N"); listParams.Add(agentLimit.ToString()); listParams.Add(objectBonus.ToString()); if (mature) listParams.Add("21"); else listParams.Add("13"); //FIXME - enumerate these settings if (restrictPushing) listParams.Add("Y"); else listParams.Add("N"); if (allowParcelJoinDivide) listParams.Add("Y"); else listParams.Add("N"); EstateOwnerMessage("setregioninfo", listParams); } /// Estate panel "Debug" tab settings public void SetRegionDebug(bool disableScripts, bool disableCollisions, bool disablePhysics) { List listParams = new List(); if (disableScripts) listParams.Add("Y"); else listParams.Add("N"); if (disableCollisions) listParams.Add("Y"); else listParams.Add("N"); if (disablePhysics) listParams.Add("Y"); else listParams.Add("N"); EstateOwnerMessage("setregiondebug", listParams); } } }