OSDN Git Service

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