public bool AllowDetach(InventoryItem item) { if (!Enabled || item == null) return true; List<Primitive> myAtt = client.Network.CurrentSim.ObjectsPrimitives.FindAll((Primitive p) => p.ParentID == client.Self.LocalID); foreach (var att in myAtt) { if (CurrentOutfitFolder.GetAttachmentItem(att) == item.UUID) { if (rules.FindAll((RLVRule r) => { return r.Behaviour == "detach" && r.Sender == att.ID; }).Count > 0) { return false; } break; } } return true; }
public bool AllowDetach(InventoryItem item) { if (!Enabled || item == null) { return(true); } List <Primitive> myAtt = client.Network.CurrentSim.ObjectsPrimitives.FindAll(p => p.ParentID == client.Self.LocalID); foreach (var att in myAtt.Where(att => CurrentOutfitFolder.GetAttachmentItem(att) == item.UUID)) { if (rules.FindAll(r => r.Behaviour == "detach" && r.Sender == att.ID).Count > 0) { return(false); } break; } return(true); }
public bool TryProcessCMD(ChatEventArgs e) { if (!Enabled || !e.Message.StartsWith("@")) { return(false); } if (e.Message == "@clear") { Clear(e.SourceID); return(true); } foreach (var cmd in e.Message.Substring(1).Split(',')) { var m = rlv_regex.Match(cmd); if (!m.Success) { continue; } var rule = new RLVRule { Behaviour = m.Groups["behaviour"].ToString().ToLower(), Option = m.Groups["option"].ToString().ToLower(), Param = m.Groups["param"].ToString().ToLower(), Sender = e.SourceID, SenderName = e.FromName }; Logger.DebugLog(rule.ToString()); if (rule.Param == "rem") { rule.Param = "y"; } if (rule.Param == "add") { rule.Param = "n"; } switch (rule.Param) { case "n": lock (rules) { var existing = rules.Find(r => r.Behaviour == rule.Behaviour && r.Sender == rule.Sender && r.Option == rule.Option); if (existing != null) { rules.Remove(existing); } rules.Add(rule); OnRLVRuleChanged(new RLVEventArgs(rule)); } continue; case "y": lock (rules) { if (rule.Option == "") { rules.RemoveAll((RLVRule r) => r.Behaviour == rule.Behaviour && r.Sender == rule.Sender); } else { rules.RemoveAll((RLVRule r) => r.Behaviour == rule.Behaviour && r.Sender == rule.Sender && r.Option == rule.Option); } } OnRLVRuleChanged(new RLVEventArgs(rule)); continue; } switch (rule.Behaviour) { case "version": int chan = 0; if (int.TryParse(rule.Param, out chan) && chan > 0) { Respond(chan, "RestrainedLife viewer v1.23 (" + Properties.Resources.RadegastTitle + " " + Assembly.GetExecutingAssembly().GetName().Version + ")"); } break; case "versionnew": chan = 0; if (int.TryParse(rule.Param, out chan) && chan > 0) { Respond(chan, "RestrainedLove viewer v1.23 (" + Properties.Resources.RadegastTitle + " " + Assembly.GetExecutingAssembly().GetName().Version + ")"); } break; case "versionnum": if (int.TryParse(rule.Param, out chan) && chan > 0) { Respond(chan, "1230100"); } break; case "getgroup": if (int.TryParse(rule.Param, out chan) && chan > 0) { UUID gid = client.Self.ActiveGroup; if (instance.Groups.ContainsKey(gid)) { Respond(chan, instance.Groups[gid].Name); } } break; case "setgroup": { if (rule.Param == "force") { foreach (var g in instance.Groups.Values) { if (g.Name.ToLower() == rule.Option) { client.Groups.ActivateGroup(g.ID); } } } } break; case "getsitid": if (int.TryParse(rule.Param, out chan) && chan > 0) { Avatar me; if (client.Network.CurrentSim.ObjectsAvatars.TryGetValue(client.Self.LocalID, out me)) { if (me.ParentID != 0) { Primitive seat; if (client.Network.CurrentSim.ObjectsPrimitives.TryGetValue(me.ParentID, out seat)) { Respond(chan, seat.ID.ToString()); break; } } } Respond(chan, UUID.Zero.ToString()); } break; case "getstatusall": case "getstatus": if (int.TryParse(rule.Param, out chan) && chan > 0) { string sep = "/"; string filter = ""; if (!string.IsNullOrEmpty(rule.Option)) { var parts = rule.Option.Split(';'); if (parts.Length > 1 && parts[1].Length > 0) { sep = parts[1].Substring(0, 1); } if (parts.Length > 0 && parts[0].Length > 0) { filter = parts[0].ToLower(); } } lock (rules) { string res = ""; rules .FindAll(r => (rule.Behaviour == "getstatusall" || r.Sender == rule.Sender) && r.Behaviour.Contains(filter)) .ForEach(objRule => { res += sep + objRule.Behaviour; if (!string.IsNullOrEmpty(objRule.Option)) { res += ":" + objRule.Option; } }); Respond(chan, res); } } break; case "sit": UUID sitTarget = UUID.Zero; if (rule.Param == "force" && UUID.TryParse(rule.Option, out sitTarget) && sitTarget != UUID.Zero) { instance.State.SetSitting(true, sitTarget); } break; case "unsit": if (rule.Param == "force") { instance.State.SetSitting(false, UUID.Zero); } break; case "setrot": double rot = 0.0; if (rule.Param == "force" && double.TryParse(rule.Option, System.Globalization.NumberStyles.Float, Utils.EnUsCulture, out rot)) { client.Self.Movement.UpdateFromHeading(Math.PI / 2d - rot, true); } break; case "tpto": var coord = rule.Option.Split('/'); try { float gx = float.Parse(coord[0], Utils.EnUsCulture); float gy = float.Parse(coord[1], Utils.EnUsCulture); float z = float.Parse(coord[2], Utils.EnUsCulture); float x = 0, y = 0; instance.TabConsole.DisplayNotificationInChat("Starting teleport..."); ulong h = Helpers.GlobalPosToRegionHandle(gx, gy, out x, out y); client.Self.RequestTeleport(h, new Vector3(x, y, z)); } catch (Exception) { } break; #region #RLV folder and outfit manipulation case "getoutfit": if (int.TryParse(rule.Param, out chan) && chan > 0) { var wearables = client.Appearance.GetWearables(); string res = ""; // Do we have a specific wearable to check, ie @getoutfit:socks=99 if (!string.IsNullOrEmpty(rule.Option)) { res = wearables.ContainsKey(WearableFromString(rule.Option)) ? "1" : "0"; } else { foreach (var t in RLVWearables) { if (wearables.ContainsKey(t.Type)) { res += "1"; } else { res += "0"; } } } Respond(chan, res); } break; case "getattach": if (int.TryParse(rule.Param, out chan) && chan > 0) { string res = ""; var attachments = client.Network.CurrentSim.ObjectsPrimitives.FindAll(p => p.ParentID == client.Self.LocalID); if (attachments.Count > 0) { var myPoints = new List <AttachmentPoint>(attachments.Count); foreach (var p in attachments) { if (!myPoints.Contains(p.PrimData.AttachmentPoint)) { myPoints.Add(p.PrimData.AttachmentPoint); } } // Do we want to check one single attachment if (!string.IsNullOrEmpty(rule.Option)) { res = myPoints.Contains(AttachmentPointFromString(rule.Option)) ? "1" : "0"; } else { foreach (var a in RLVAttachments) { if (myPoints.Contains(a.Point)) { res += "1"; } else { res += "0"; } } } } Respond(chan, res); } break; case "remattach": case "detach": if (rule.Param == "force") { if (!string.IsNullOrEmpty(rule.Option)) { var point = RLVAttachments.Find(a => a.Name == rule.Option); if (point.Name == rule.Option) { var attachment = client.Network.CurrentSim.ObjectsPrimitives.Find(p => p.ParentID == client.Self.LocalID && p.PrimData.AttachmentPoint == point.Point); if (attachment != null && client.Inventory.Store.Items.ContainsKey(CurrentOutfitFolder.GetAttachmentItem(attachment))) { instance.COF.Detach((InventoryItem)client.Inventory.Store.Items[CurrentOutfitFolder.GetAttachmentItem(attachment)].Data); } } else { InventoryNode folder = FindFolder(rule.Option); if (folder != null) { var outfit = (from item in folder.Nodes.Values where CurrentOutfitFolder.CanBeWorn(item.Data) select(InventoryItem) (item.Data)).ToList(); instance.COF.RemoveFromOutfit(outfit); } } } else { client.Network.CurrentSim.ObjectsPrimitives.FindAll(p => p.ParentID == client.Self.LocalID).ForEach(attachment => { if (client.Inventory.Store.Items.ContainsKey(CurrentOutfitFolder.GetAttachmentItem(attachment))) { instance.COF.Detach((InventoryItem)client.Inventory.Store.Items[CurrentOutfitFolder.GetAttachmentItem(attachment)].Data); } }); } } break; case "remoutfit": if (rule.Param == "force") { if (!string.IsNullOrEmpty(rule.Option)) { var w = RLVWearables.Find(a => a.Name == rule.Option); if (w.Name == rule.Option) { var items = instance.COF.GetWornAt(w.Type); instance.COF.RemoveFromOutfit(items); } } } break; case "attach": case "attachoverorreplace": case "attachover": case "attachall": case "attachallover": if (rule.Param == "force") { if (!string.IsNullOrEmpty(rule.Option)) { InventoryNode folder = FindFolder(rule.Option); if (folder != null) { List <InventoryItem> outfit = new List <InventoryItem>(); if (rule.Behaviour == "attachall" || rule.Behaviour == "attachallover") { GetAllItems(folder, true, ref outfit); } else { GetAllItems(folder, false, ref outfit); } if (rule.Behaviour == "attachover" || rule.Behaviour == "attachallover") { instance.COF.AddToOutfit(outfit, false); } else { instance.COF.AddToOutfit(outfit, true); } } } } break; case "getinv": if (int.TryParse(rule.Param, out chan) && chan > 0) { string res = string.Empty; InventoryNode folder = FindFolder(rule.Option); if (folder != null) { res = folder.Nodes.Values.Where( f => f.Data is InventoryFolder && !f.Data.Name.StartsWith(".")).Aggregate( res, (current, f) => current + (f.Data.Name + ",")); } Respond(chan, res.TrimEnd(',')); } break; case "getinvworn": if (int.TryParse(rule.Param, out chan) && chan > 0) { string res = string.Empty; InventoryNode root = FindFolder(rule.Option); if (root != null) { res += "|" + GetWornIndicator(root) + ","; res = root.Nodes.Values.Where( n => n.Data is InventoryFolder && !n.Data.Name.StartsWith(".")).Aggregate( res, (current, n) => current + (n.Data.Name + "|" + GetWornIndicator(n) + ",")); } Respond(chan, res.TrimEnd(',')); } break; case "findfolder": case "findfolders": if (int.TryParse(rule.Param, out chan) && chan > 0) { StringBuilder response = new StringBuilder(); string[] keywordsArray = rule.Option.Split(new string[] { "&&" }, StringSplitOptions.None); if (keywordsArray.Any()) { List <InventoryNode> matching_nodes = FindFoldersKeyword(keywordsArray); if (matching_nodes.Any()) { if (rule.Behaviour == "findfolder") { InventoryNode bestCandidate = null; int bestCandidateSlashCount = -1; foreach (var match in matching_nodes) { string fullPath = FindFullInventoryPath(match, ""); int numSlashes = fullPath.Count(ch => ch == '/'); if (bestCandidate == null || numSlashes > bestCandidateSlashCount) { bestCandidateSlashCount = numSlashes; bestCandidate = match; } } string bestCandidatePath = bestCandidate.Data.Name; if (bestCandidatePath.Substring(0, 5).ToLower() == @"#rlv/") { bestCandidatePath = bestCandidatePath.Substring(5); } response.Append(bestCandidatePath); } else { StringBuilder sb = new StringBuilder(); foreach (var node in matching_nodes) { string fullPath = FindFullInventoryPath(node, ""); if (fullPath.Length > 4 && fullPath.Substring(0, 5).ToLower() == @"#rlv/") { fullPath = fullPath.Substring(5); } response.Append(fullPath + ","); } } } } Respond(chan, response.ToString().TrimEnd(',')); } break; #endregion #RLV folder and outfit manipulation } } return(true); }