278 lines
10 KiB
C#
278 lines
10 KiB
C#
using System.Text.Json;
|
|
using OpenMetaverse;
|
|
using SecondBotEvents.Services;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
|
|
namespace SecondBotEvents.Commands
|
|
{
|
|
[ClassInfo("What is going on with the bot")]
|
|
public class Info(EventsSecondBot setmaster) : CommandsAPI(setmaster)
|
|
{
|
|
[About("Requests a 6-digit login token to be sent via IM to the avatar")]
|
|
[ArgHints("avatar", "The avatar to send the token to", "AVATAR")]
|
|
[CmdTypeDo()]
|
|
public object RequestLoginToken(string avatar)
|
|
{
|
|
ProcessAvatar(avatar);
|
|
if (avataruuid == UUID.Zero) return Failure("Unknown avatar - are you sure the name is correct? (Firstname Lastname)");
|
|
|
|
string token = master.DataStoreService.RequestLoginToken(avataruuid);
|
|
GetClient().Self.InstantMessage(avataruuid, $"[Bot Dashboard] Your login verification code is: {token} (Expires in 5 minutes)");
|
|
return BasicReply("Sent");
|
|
}
|
|
|
|
[About("Verifies a 6-digit login token")]
|
|
[ArgHints("avatar", "The avatar verifying", "AVATAR")]
|
|
[ArgHints("token", "The 6-digit token", "STRING")]
|
|
[CmdTypeGet()]
|
|
public object VerifyLoginToken(string avatar, string token)
|
|
{
|
|
ProcessAvatar(avatar);
|
|
if (avataruuid == UUID.Zero) return Failure("Unknown avatar");
|
|
bool ok = master.DataStoreService.VerifyLoginToken(avataruuid, token);
|
|
if (ok) return BasicReply(avataruuid.ToString());
|
|
return BasicReply("False");
|
|
}
|
|
|
|
[About("Fetchs the current region type the bot is in")]
|
|
[ReturnHints("Region type as string")]
|
|
[ReturnHintsFailure("Error not in a sim")]
|
|
[CmdTypeGet()]
|
|
public object GetCurrentRegionType()
|
|
{
|
|
if(GetClient().Network.CurrentSim == null)
|
|
{
|
|
return Failure("Error not in a sim");
|
|
}
|
|
return BasicReply(GetClient().Network.CurrentSim.ProductName);
|
|
|
|
}
|
|
|
|
[About("Lists objects that are sculpty type in the current sim that the bot can see")]
|
|
[ReturnHints("A json object")]
|
|
[CmdTypeGet()]
|
|
public object ListSculptys()
|
|
{
|
|
Dictionary<uint, Primitive> objects_copy = GetClient().Network.CurrentSim.ObjectsPrimitives.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
|
|
|
Dictionary<uint, uint> mapLocalID = [];
|
|
Dictionary<uint, Primitive> sculpts = [];
|
|
foreach (KeyValuePair<uint, Primitive> Obj in objects_copy)
|
|
{
|
|
mapLocalID.Add(Obj.Value.LocalID, Obj.Key);
|
|
if (PrimType.Sculpt.Equals(Obj.Value.Type) == true)
|
|
{
|
|
sculpts.Add(Obj.Key, Obj.Value);
|
|
}
|
|
}
|
|
List<SculptysInfo> reply = [];
|
|
foreach (KeyValuePair<uint, Primitive> Obj in sculpts)
|
|
{
|
|
Vector3 pos = Obj.Value.Position;
|
|
string name = "?";
|
|
if (Obj.Value.NameValues != null)
|
|
{
|
|
name = Obj.Value.NameValues[0].Value.ToString();
|
|
}
|
|
UUID key = Obj.Value.ID;
|
|
UUID owner = Obj.Value.OwnerID;
|
|
bool asLink = false;
|
|
if (Obj.Value.ParentID > 0)
|
|
{
|
|
if(mapLocalID.ContainsKey(Obj.Value.ParentID) == true)
|
|
{
|
|
Primitive wip = objects_copy[mapLocalID[Obj.Value.ParentID]];
|
|
pos = wip.Position;
|
|
asLink = true;
|
|
owner = wip.OwnerID;
|
|
if (wip.NameValues != null)
|
|
{
|
|
name = wip.NameValues[0].Value.ToString();
|
|
}
|
|
key = wip.ID;
|
|
}
|
|
}
|
|
SculptysInfo A = new()
|
|
{
|
|
isLinked = asLink.ToString(),
|
|
name = name.ToString(),
|
|
owner = owner.ToString(),
|
|
uuid = key.ToString(),
|
|
pos = pos.ToString()
|
|
};
|
|
reply.Add(A);
|
|
}
|
|
if (reply.Count == 0)
|
|
{
|
|
return Failure("No objects found");
|
|
}
|
|
return BasicReply(JsonSerializer.Serialize(reply, JsonOptions.UnsafeRelaxed));
|
|
}
|
|
|
|
[About("Fetchs the current bot")]
|
|
[ReturnHints("The build ID of the bot")]
|
|
[CmdTypeGet()]
|
|
public object Version()
|
|
{
|
|
return BasicReply(master.GetVersion());
|
|
|
|
}
|
|
|
|
[About("Fetchs the name of the bot")]
|
|
[ReturnHints("Firstname Lastname")]
|
|
[CmdTypeGet()]
|
|
public object Name()
|
|
{
|
|
return BasicReply(GetClient().Self.FirstName + " " + GetClient().Self.LastName);
|
|
}
|
|
|
|
[About("Fetchs the current parcels name")]
|
|
[ReturnHints("Parcelname")]
|
|
[ReturnHintsFailure("Error parcel not found")]
|
|
[ReturnHintsFailure("Error not in a sim")]
|
|
[CmdTypeGet()]
|
|
public object ParcelName()
|
|
{
|
|
if (GetClient().Network.CurrentSim == null)
|
|
{
|
|
return Failure("Error not in a sim");
|
|
}
|
|
int localid = GetClient().Parcels.GetParcelLocalID(GetClient().Network.CurrentSim, GetClient().Self.SimPosition);
|
|
if (GetClient().Network.CurrentSim.Parcels.ContainsKey(localid) == false)
|
|
{
|
|
return Failure("Error parcel not found");
|
|
}
|
|
return BasicReply(GetClient().Network.CurrentSim.Parcels[localid].Name);
|
|
}
|
|
|
|
[About("Requests the current unixtime at the bot")]
|
|
[ReturnHints("Unixtime")]
|
|
[CmdTypeGet()]
|
|
public object UnixTimeNow()
|
|
{
|
|
return BasicReply(SecondbotHelpers.UnixTimeNow().ToString());
|
|
}
|
|
|
|
[About("Fetchs the current region name")]
|
|
[ReturnHints("Regionname")]
|
|
[ReturnHintsFailure("Error not in a sim")]
|
|
[CmdTypeGet()]
|
|
public object SimName()
|
|
{
|
|
if (GetClient().Network.CurrentSim == null)
|
|
{
|
|
return Failure("Error not in a sim");
|
|
}
|
|
return BasicReply(GetClient().Network.CurrentSim.Name);
|
|
}
|
|
|
|
[About("Fetchs the current location of the bot")]
|
|
[ReturnHints("array of X,Y,Z values")]
|
|
[ReturnHintsFailure("Error not in a sim")]
|
|
[CmdTypeGet()]
|
|
public object GetPosition()
|
|
{
|
|
if (GetClient().Network.CurrentSim == null)
|
|
{
|
|
return Failure("Error not in a sim");
|
|
}
|
|
uint sittingOn = GetClient().Self.SittingOn;
|
|
string sittingOnUUID = "00000000-0000-0000-0000-000000000000";
|
|
if (sittingOn != 0)
|
|
{
|
|
if (GetClient().Network.CurrentSim.ObjectsPrimitives.TryGetValue(sittingOn, out Primitive prim))
|
|
{
|
|
sittingOnUUID = prim.ID.ToString();
|
|
}
|
|
}
|
|
|
|
Dictionary<string, object> pos = new()
|
|
{
|
|
{ "x", (int)Math.Round(GetClient().Self.SimPosition.X) },
|
|
{ "y", (int)Math.Round(GetClient().Self.SimPosition.Y) },
|
|
{ "z", (int)Math.Round(GetClient().Self.SimPosition.Z) },
|
|
{ "sitting_on", sittingOnUUID }
|
|
};
|
|
return BasicReply(JsonSerializer.Serialize(pos, JsonOptions.UnsafeRelaxed));
|
|
}
|
|
[About("Fetchs the current RLV restrictions applied to the bot")]
|
|
[ReturnHints("A JSON array of RLV rules")]
|
|
[CmdTypeGet()]
|
|
public object RLVStatus()
|
|
{
|
|
if (master.RLV == null)
|
|
{
|
|
return Failure("RLV service is not running");
|
|
}
|
|
var rules = master.RLV.Rules;
|
|
if (rules == null) return BasicReply("[]");
|
|
return BasicReply(JsonSerializer.Serialize(rules, JsonOptions.UnsafeRelaxed));
|
|
}
|
|
|
|
[About("Lists objects near the bot (within 20m)")]
|
|
[ReturnHints("A JSON array of nearby objects")]
|
|
[CmdTypeGet()]
|
|
public object GetNearbyObjects()
|
|
{
|
|
if (GetClient().Network.CurrentSim == null) return Failure("Not in a sim");
|
|
|
|
Vector3 botPos = GetClient().Self.SimPosition;
|
|
uint sittingOn = GetClient().Self.SittingOn;
|
|
List<uint> localIDsToRequest = [];
|
|
|
|
// First pass: Find objects and collect localIDs for properties we don't have
|
|
foreach (var prim in GetClient().Network.CurrentSim.ObjectsPrimitives.Values)
|
|
{
|
|
if (prim.ParentID != 0) continue;
|
|
if (Vector3.Distance(botPos, prim.Position) <= 20.0f)
|
|
{
|
|
if (prim.Properties == null) localIDsToRequest.Add(prim.LocalID);
|
|
}
|
|
}
|
|
|
|
// If we have missing names, request them and wait a short moment
|
|
if (localIDsToRequest.Count > 0)
|
|
{
|
|
GetClient().Objects.SelectObjects(GetClient().Network.CurrentSim, localIDsToRequest.ToArray());
|
|
Thread.Sleep(500); // Wait for properties to arrive
|
|
}
|
|
|
|
List<object> reply = [];
|
|
foreach (var prim in GetClient().Network.CurrentSim.ObjectsPrimitives.Values)
|
|
{
|
|
if (prim.ParentID != 0) continue;
|
|
|
|
float dist = Vector3.Distance(botPos, prim.Position);
|
|
if (dist <= 20.0f)
|
|
{
|
|
string name = prim.Properties?.Name;
|
|
if (string.IsNullOrEmpty(name)) name = "Object #" + prim.LocalID;
|
|
|
|
reply.Add(new {
|
|
name = name,
|
|
uuid = prim.ID.ToString(),
|
|
local_id = prim.LocalID,
|
|
dist = Math.Round(dist, 1),
|
|
pos = prim.Position.ToString(),
|
|
is_sitting = (prim.LocalID == sittingOn)
|
|
});
|
|
}
|
|
}
|
|
|
|
return BasicReply(JsonSerializer.Serialize(reply, JsonOptions.UnsafeRelaxed));
|
|
}
|
|
}
|
|
|
|
public class SculptysInfo
|
|
{
|
|
public string name = "";
|
|
public string isLinked = "False";
|
|
public string owner = "?";
|
|
public string uuid = "?";
|
|
public string pos = "<0,0,0>";
|
|
|
|
}
|
|
}
|