OSDN Git Service

dc2840800e2364f18a391800ecbb622b6b552ef3
[radegast/radegast.git] / plugins / Radegast.Plugin.EVOVend / EVOvendPlugin.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Drawing;
5 using System.Data;
6 using System.Linq;
7 using System.Text;
8 using System.Windows.Forms;
9 using OpenMetaverse;
10 using OpenMetaverse.StructuredData;
11 using System.Threading;
12 using System.IO;
13 using System.Net;
14
15 namespace Radegast.Plugin.EVOVend
16 {
17     [Radegast.Plugin(Name = "EVOvend Plugin", Description = "EVO Vendor Delivery System", Version = "1.0")]
18     public partial class EVOvendPlugin : RadegastTabControl, IRadegastPlugin
19     {
20         public int DELIVERY_INTERVAL
21         {
22             get
23             {
24                 return (int)numDeliveryInterval.Value;
25             }
26             set
27             {
28                 numDeliveryInterval.Value = value;
29             }
30         }
31
32         public int STARTUP_DELAY
33         {
34             get
35             {
36                 return (int)numStartupDelay.Value;
37             }
38             set
39             {
40                 numStartupDelay.Value = value;
41             }
42         }
43
44         public OSDMap config;
45
46         public static System.Threading.Timer timer;
47         private InventoryManager Manager;
48         private OpenMetaverse.Inventory Inventory;
49
50         private string vendURL = @"http://evosl.org/TREK/SL/index.php";
51         List<InventoryBase> searchRes = new List<InventoryBase>();
52
53         /*private GridClient Client { get { return instance.Client; } }*/
54
55         static string tabID = "evovend_tab";
56         static string tabLabel = "EVOvend";
57
58         private string pluginName = "EVOvend";
59         private string version = "1.0";
60         private ToolStripMenuItem EVOButton;
61
62         public EVOvendPlugin()
63         {
64             //this.InitializeComponent();
65         }
66
67         public EVOvendPlugin(RadegastInstance instance, bool unused) : base(instance)
68         {
69             //this.instance = instance;
70             Init();
71             Disposed += new EventHandler(EVOvendTab_Disposed);
72             RegisterClientEvents(client);
73         }
74
75         void RegisterClientEvents(GridClient client)
76         {
77             //instance.ClientChanged += new EventHandler<ClientChangedEventArgs>(instance_ClientChanged);
78             //client.Self.ChatFromSimulator += new EventHandler<ChatEventArgs>(Self_ChatFromSimulator);
79         }
80
81         void UnregisterClientEvents(GridClient client)
82         {
83             //if (client == null) return;
84         }
85
86         private UUID offeredObject;
87         private UUID offeredAgent;
88
89         void Inventory_InventoryObjectOffered(object sender, InventoryObjectOfferedEventArgs e)
90         {
91             offeredObject = e.ObjectID;
92             offeredAgent = e.Offer.FromAgentID;
93         }
94
95         void Inventory_ItemReceived(object sender, ItemReceivedEventArgs e)
96         {
97             if (offeredObject != e.Item.UUID) return;
98             if (offeredAgent == UUID.Zero)
99             {
100                 instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": Failed to insert. Agent UUID not found", ChatBufferTextStyle.Error);
101                 return;
102             }
103             
104             Dictionary<string, string> param = new Dictionary<string, string>();
105             param.Add("invUUID", e.Item.UUID.ToString());
106             param.Add("userUUID", offeredAgent.ToString());
107             param.Add("name", e.Item.Name);
108
109             if(e.Item.SaleType != SaleType.Not)
110                 param.Add("price", e.Item.SalePrice.ToString());
111             else
112                 param.Add("price", "0");
113             param.Add("texture", "");
114
115             string str = this.RequestVendor("ADDPRODUCT", param);
116             int result = Int32.Parse(str);
117
118             if(result > 0)
119                 instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": Product " + e.Item.Name + " from Agent " + offeredAgent.ToString() + " accepted and inserted", ChatBufferTextStyle.StatusBlue);
120             else
121                 instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": Failed to insert " + e.Item.Name + " from Agent " + offeredAgent.ToString(), ChatBufferTextStyle.Error);
122
123             offeredAgent = UUID.Zero;
124         }
125         
126
127         void EVOvendTab_Disposed(object sender, EventArgs e)
128         {
129             this.writeConfig();
130             UnregisterClientEvents(client);
131             //instance.ClientChanged -= new EventHandler<ClientChangedEventArgs>(instance_ClientChanged);
132         }
133
134         public void StartPlugin(RadegastInstance inst)
135         {
136             instance = inst;
137             instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + " version " + version + " loaded");
138
139             Init();
140
141             EVOButton = new ToolStripMenuItem(tabLabel, null, OnEVOButtonClicked);
142             instance.MainForm.PluginsMenu.DropDownItems.Add(EVOButton);
143
144             // setup timer
145             timer = new System.Threading.Timer(new TimerCallback(productCallback));
146             this.SetupTimer();
147             // invenotry receiving
148             client.Inventory.ItemReceived += Inventory_ItemReceived;
149             client.Inventory.InventoryObjectOffered +=Inventory_InventoryObjectOffered;
150         }
151
152         public void SetupTimer(){
153             if (timer == null) return;
154             timer.Change((STARTUP_DELAY * 1000), (DELIVERY_INTERVAL * 1000));
155             instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ":  Waiting " + STARTUP_DELAY + " seconds before start...");
156         }
157
158         private void Init()
159         {
160             this.InitializeComponent();
161             this.RegisterClientEvents(client);
162             if (instance != null)
163             {
164                 this.readConfig();
165             }
166         }
167
168         private void readConfig()
169         {
170             config = instance.GlobalSettings["plugin." + pluginName] as OSDMap;
171
172             if (config == null)
173             {
174                 config = new OSDMap();
175                 config["startup_delay"] = new OSDInteger(60);
176                 config["delivery_interval"] = new OSDInteger(60);
177                 instance.GlobalSettings["plugin." + pluginName] = config;
178             }
179
180             if (!config.ContainsKey("startup_delay"))
181                 config["startup_delay"] = 60;
182             if (!config.ContainsKey("delivery_interval"))
183                 config["delivery_interval"] = 60;
184
185             STARTUP_DELAY = config["startup_delay"].AsInteger();
186             DELIVERY_INTERVAL = config["delivery_interval"].AsInteger();
187         }
188
189         private void writeConfig()
190         {
191             config = instance.GlobalSettings["plugin." + pluginName] as OSDMap;
192
193             if (config != null)
194             {
195                 config["startup_delay"] = STARTUP_DELAY;
196                 config["delivery_interval"] = DELIVERY_INTERVAL;
197                 //instance.GlobalSettings["plugin." + pluginName] = config;
198             }
199
200             instance.GlobalSettings.Save();
201         }
202
203         void OnEVOButtonClicked(object sender, EventArgs e)
204         {
205             if (instance.TabConsole.TabExists(tabID))
206             {
207                 instance.TabConsole.Tabs[tabID].Select();
208             }
209             else
210             {
211                 instance.TabConsole.AddTab(tabID, tabLabel, new EVOvendPlugin(instance, true));
212                 instance.TabConsole.Tabs[tabID].Select();
213             }
214         }
215
216         public void StopPlugin(RadegastInstance instance)
217         {
218             // kill timer
219             timer.Dispose();
220             EVOButton.Dispose();
221             // unregister inventory receiver events
222             client.Inventory.ItemReceived -= Inventory_ItemReceived;
223             client.Inventory.InventoryObjectOffered -= Inventory_InventoryObjectOffered;
224         }
225
226         private string m_searchString;
227         public string searchString
228         {
229             get
230             {
231                 return m_searchString;
232             }
233             set
234             {
235                 m_searchString = value;
236                 if (!String.IsNullOrEmpty(value))
237                     PerformRecursiveSearch(0, Inventory.RootFolder.UUID);
238             }
239         }
240
241         void PerformRecursiveSearch(int level, UUID folderID)
242         {
243             var me = Inventory.Items[folderID].Data;
244             var sorted = Inventory.GetContents(folderID);
245
246             sorted.Sort((InventoryBase b1, InventoryBase b2) =>
247             {
248                 if (b1 is InventoryFolder && !(b2 is InventoryFolder))
249                 {
250                     return -1;
251                 }
252                 else if (!(b1 is InventoryFolder) && b2 is InventoryFolder)
253                 {
254                     return 1;
255                 }
256                 else
257                 {
258                     return string.Compare(b1.Name, b2.Name);
259                 }
260             });
261
262             foreach (var item in sorted)
263             {
264                 if (item is InventoryFolder)
265                 {
266                     PerformRecursiveSearch(level + 1, item.UUID);
267                 }
268                 else
269                 {
270                     var it = item as InventoryItem;
271
272                     if (it.UUID.ToString().Contains(searchString))
273                         searchRes.Add(it);
274                 }
275             }
276         }
277
278         class DeliveryQueue
279         {
280             public string ClassName { get; set; }
281             public string id { get; set; }
282             public string userUUID { get; set; }
283             public string objectUUID { get; set; }
284             public int price { get; set; }
285             public string created { get; set; }
286             public string delivered { get; set; }
287         }
288
289         private string RequestVendor(string action, Dictionary<string, string> param = null)
290         {
291             try
292             {
293                 var webRequest = WebRequest.Create(this.vendURL);
294
295                 string postData = "action=" + action;
296                 if (param != null && param.Count > 0)
297                 {
298                     var kv = param.Select(p => "&" + p.Key + "=" + p.Value);
299                     postData += String.Join("", kv.ToArray());
300                 }
301                 byte[] byteArray = Encoding.UTF8.GetBytes(postData);
302
303                 webRequest.Method = "POST";
304                 webRequest.ContentType = "application/x-www-form-urlencoded";
305                 webRequest.ContentLength = byteArray.Length;
306
307                 // add post data to request
308                 Stream postStream = webRequest.GetRequestStream();
309                 postStream.Write(byteArray, 0, byteArray.Length);
310                 postStream.Flush();
311                 postStream.Close();
312
313                 using (var response = webRequest.GetResponse())
314                 using (var content = response.GetResponseStream())
315                 using (var reader = new System.IO.StreamReader(content))
316                 {
317                     return reader.ReadToEnd();
318                 }
319             }
320             catch { }
321             return null;
322         }
323
324         private List<DeliveryQueue> parseResponse(string content)
325         {
326             List<DeliveryQueue> queue = new List<DeliveryQueue>();
327
328             if (String.IsNullOrEmpty(content)) return queue;
329
330             try
331             {
332                 System.Reflection.PropertyInfo[] propertyInfos = typeof(DeliveryQueue).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
333
334                 string field_separator = "|";
335
336                 var lines = content.Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
337                 foreach (string l in lines)
338                 {
339                     int lastPos = 0;
340
341                     var deliveryQ = new DeliveryQueue();
342                     foreach (System.Reflection.PropertyInfo pInfo in propertyInfos)
343                     {
344                         var nextPos = l.IndexOf(field_separator, lastPos);
345                         if (nextPos > -1)
346                         {
347                             object o = Convert.ChangeType(l.Substring(lastPos, nextPos - lastPos), pInfo.PropertyType);
348                             pInfo.SetValue(deliveryQ, o, null);
349                         }
350                         lastPos = nextPos + 1;
351                     }
352
353                     queue.Add(deliveryQ);
354                 }
355             }
356             catch (Exception ex)
357             {
358                 instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": Failed to read DeliveryQ -  " + ex.Message, ChatBufferTextStyle.Error);
359             }
360             return queue;
361         }
362
363         private bool SendObject(DeliveryQueue p)
364         {
365             searchRes.Clear();
366             searchString = p.objectUUID;
367             if (searchRes.Count <= 0)
368             {
369                 instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": Product not found '" + searchString + "' for user '" + p.userUUID + "'", ChatBufferTextStyle.Error);
370                 return false;
371             }
372             if (searchRes.Count > 1)
373             {
374                 instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": More then one product found for '" + searchString + "'", ChatBufferTextStyle.Error);
375                 return false;
376             }
377
378             var inv = searchRes[0] as InventoryItem;
379             if (inv == null)
380             {
381                 instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": Product found, but not an inventory item", ChatBufferTextStyle.Error);
382                 return false;
383             }
384
385
386             Dictionary<string, string> param = new Dictionary<string, string>();
387             param.Add("id", p.id);
388             var str = this.RequestVendor("SETDELIVERED", param);
389             if (str != "1")
390             {
391                 instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": Product found, but user " + p.userUUID + " might not have enough funds", ChatBufferTextStyle.Normal);
392                 // a message to the user would be helpful later
393                 return false;
394             }
395             instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": SETDELIVERED: " + str, ChatBufferTextStyle.StatusBlue);
396
397             Manager.GiveItem(inv.UUID, inv.Name, inv.AssetType, OpenMetaverse.UUID.Parse(p.userUUID), false);
398             instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": PRODUCT '" + searchRes[0].Name + "' SENT TO " + p.userUUID, ChatBufferTextStyle.StatusBlue);
399
400             return true;
401         }
402
403         private bool isSending = false;
404         private void productCallback(object obj)
405         {
406             Manager = client.Inventory;
407             Inventory = Manager.Store;
408             if (Inventory == null)
409             {
410                 instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": Waiting for Inventory...");
411                 return;
412             }
413
414             if (isSending == true)
415             {
416                 instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": Waiting...");
417                 return;
418             }
419             isSending = true;
420             
421             Inventory.RootFolder.OwnerID = client.Self.AgentID;
422
423             var strContent = this.RequestVendor("GETOUTSTANDING");
424             List<DeliveryQueue> queue = this.parseResponse(strContent);
425             instance.MainForm.TabConsole.DisplayNotificationInChat(pluginName + ": " + queue.Count + " Items in Queue List");
426
427             // check if something neddc to be done
428             if (queue.Count > 0)
429             {
430                 foreach (DeliveryQueue p in queue)
431                     this.SendObject(p);
432             }
433
434             isSending = false;
435         }
436
437         private void numStartupDelay_ValueChanged(object sender, EventArgs e)
438         {
439             this.SetupTimer();
440         }
441
442         private void numDeliveryInterval_ValueChanged(object sender, EventArgs e)
443         {
444             this.SetupTimer();
445         }
446     }
447 }
448