OSDN Git Service

RAD-493: Added context menu to group chat
[radegast/radegast.git] / Radegast / Automation / AutoSit.cs
1 // 
2 // Radegast Metaverse Client
3 //Copyright (c) 2009-2014, Radegast Development Team
4 // All rights reserved.
5 // 
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // 
9 //     * Redistributions of source code must retain the above copyright notice,
10 //       this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above copyright
12 //       notice, this list of conditions and the following disclaimer in the
13 //       documentation and/or other materials provided with the distribution.
14 //     * Neither the name of the application "Radegast", nor the names of its
15 //       contributors may be used to endorse or promote products derived from
16 //       this software without specific prior written permission.
17 // 
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 using System;
30 using System.Collections.Generic;
31 using System.Linq;
32 using System.Text;
33 using System.Timers;
34
35 using OpenMetaverse;
36 using OpenMetaverse.StructuredData;
37
38 namespace Radegast.Automation
39 {
40     public class AutoSitPreferences
41     {
42         public UUID Primitive { get; set; }
43         public string PrimitiveName { get; set; }
44         public bool Enabled { get; set; }
45
46         public static explicit operator AutoSitPreferences(OSD osd){
47             AutoSitPreferences prefs = new AutoSitPreferences
48             {
49                 Primitive = UUID.Zero,
50                 PrimitiveName = ""
51             };
52
53             if (osd != null && osd.Type == OSDType.Map)
54             {
55                 OSDMap map = (OSDMap)osd;
56                 prefs.Primitive = map.ContainsKey("Primitive") ? map["Primitive"].AsUUID() : UUID.Zero;
57                 prefs.PrimitiveName = prefs.Primitive != UUID.Zero && map.ContainsKey("PrimitiveName") ? map["PrimitiveName"].AsString() : "";
58                 prefs.Enabled = map.ContainsKey("Enabled") ? map["Enabled"].AsBoolean() : false;
59             }
60
61             return prefs;
62         }
63
64         public static implicit operator OSD(AutoSitPreferences prefs){
65             return (OSDMap)prefs;
66         }
67
68         public static explicit operator OSDMap(AutoSitPreferences prefs)
69         {
70             OSDMap map = new OSDMap(3);
71
72             map["Primitive"] = prefs.Primitive;
73             map["PrimitiveName"] = prefs.PrimitiveName;
74             map["Enabled"] = prefs.Enabled;
75
76             return map;
77         }
78
79         public static explicit operator AutoSitPreferences(Settings s){
80             return (s != null && s.ContainsKey("AutoSit")) ? (AutoSitPreferences)s["AutoSit"] : new AutoSitPreferences();
81         }
82     }
83
84     public class AutoSit : IDisposable
85     {
86         private const string c_label = "Use as Auto-Sit target";
87
88         private RadegastInstance m_instance;
89         private Timer m_Timer;
90
91         public AutoSit(RadegastInstance instance)
92         {
93             m_instance = instance;
94             m_Timer = new Timer(10 * 1000);
95             m_Timer.Elapsed += new ElapsedEventHandler((sender, args) => {
96                 TrySit();
97             });
98             m_Timer.Enabled = false;
99         }
100
101         public void Dispose()
102         {
103             if (m_Timer != null)
104             {
105                 m_Timer.Enabled = false;
106                 m_Timer.Dispose();
107                 m_Timer = null;
108             }
109         }
110
111         public AutoSitPreferences Preferences
112         {
113             get { return !m_instance.Client.Network.Connected ? null : (AutoSitPreferences)m_instance.ClientSettings; }
114
115             set {
116                 m_instance.ClientSettings["AutoSit"] = value;
117                 if (Preferences.Enabled)
118                 {
119                     m_instance.ContextActionManager.RegisterContextAction(typeof(Primitive), c_label, PrimitiveContextAction);
120                 }
121                 else
122                 {
123                     m_instance.ContextActionManager.DeregisterContextAction(typeof(Primitive), c_label);
124                 }
125             }
126         }
127
128         public void PrimitiveContextAction(object sender, EventArgs e)
129         {
130             Primitive prim = (Primitive)sender;
131             Preferences = new AutoSitPreferences
132             {
133                 Primitive = prim.ID,
134                 PrimitiveName = prim.Properties != null ? prim.Properties.Name : "",
135                 Enabled = Preferences.Enabled
136             };
137             if (prim.Properties == null)
138             {
139                 m_instance.Client.Objects.ObjectProperties += Objects_ObjectProperties;
140                 m_instance.Client.Objects.ObjectPropertiesUpdated += Objects_ObjectProperties;
141             }
142         }
143
144         public void Objects_ObjectProperties(object sender, ObjectPropertiesEventArgs e)
145         {
146             if (e.Properties.ObjectID == Preferences.Primitive)
147             {
148                 Preferences = new AutoSitPreferences
149                 {
150                     Primitive = Preferences.Primitive,
151                     PrimitiveName = e.Properties.Name,
152                     Enabled = Preferences.Enabled
153                 };
154
155                 m_instance.Client.Objects.ObjectProperties -= Objects_ObjectProperties;
156             }
157         }
158
159         public void TrySit()
160         {
161             if (Preferences != null && m_instance.Client.Network.Connected)
162             {
163                 if (Preferences.Enabled && Preferences.Primitive != UUID.Zero)
164                 {
165                     if (!m_instance.State.IsSitting)
166                     {
167                         m_instance.State.SetSitting(true, Preferences.Primitive);
168                         m_Timer.Enabled = true;
169                     }
170                     else
171                     {
172                         if (!m_instance.Client.Network.CurrentSim.ObjectsPrimitives.ContainsKey(m_instance.Client.Self.SittingOn))
173                         {
174                             m_instance.State.SetSitting(false, UUID.Zero);
175                         }
176                     }
177                 }
178                 else
179                 {
180                     m_Timer.Enabled = false;
181                 }
182             }
183             else
184             {
185                 m_Timer.Enabled = false; // being lazy here, just letting timer elapse rather than disabling on client disconnect
186             }
187         }
188     }
189 }