corrade-lsl-templates – Diff between revs 15 and 24

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 15 Rev 24
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 // 2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
3 /////////////////////////////////////////////////////////////////////////// 3 ///////////////////////////////////////////////////////////////////////////
4 // 4 //
5 // A module using AI-SIML that allows group members to talk to Corrade. 5 // A module using AI-SIML that allows group members to talk to Corrade.
6 // 6 //
7 /////////////////////////////////////////////////////////////////////////// 7 ///////////////////////////////////////////////////////////////////////////
8   8  
9 /////////////////////////////////////////////////////////////////////////// 9 ///////////////////////////////////////////////////////////////////////////
10 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // 10 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 //
11 /////////////////////////////////////////////////////////////////////////// 11 ///////////////////////////////////////////////////////////////////////////
12 string wasKeyValueGet(string k, string data) { 12 string wasKeyValueGet(string k, string data) {
13 if(llStringLength(data) == 0) return ""; 13 if(llStringLength(data) == 0) return "";
14 if(llStringLength(k) == 0) return ""; 14 if(llStringLength(k) == 0) return "";
15 list a = llParseString2List(data, ["&", "="], []); 15 list a = llParseString2List(data, ["&", "="], []);
16 integer i = llListFindList(a, [ k ]); 16 integer i = llListFindList(a, [ k ]);
17 if(i != -1) return llList2String(a, i+1); 17 if(i != -1) return llList2String(a, i+1);
18 return ""; 18 return "";
19 } 19 }
20 20
21 /////////////////////////////////////////////////////////////////////////// 21 ///////////////////////////////////////////////////////////////////////////
22 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // 22 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
23 /////////////////////////////////////////////////////////////////////////// 23 ///////////////////////////////////////////////////////////////////////////
24 string wasKeyValueEncode(list data) { 24 string wasKeyValueEncode(list data) {
25 list k = llList2ListStrided(data, 0, -1, 2); 25 list k = llList2ListStrided(data, 0, -1, 2);
26 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); 26 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
27 data = []; 27 data = [];
28 do { 28 do {
29 data += llList2String(k, 0) + "=" + llList2String(v, 0); 29 data += llList2String(k, 0) + "=" + llList2String(v, 0);
30 k = llDeleteSubList(k, 0, 0); 30 k = llDeleteSubList(k, 0, 0);
31 v = llDeleteSubList(v, 0, 0); 31 v = llDeleteSubList(v, 0, 0);
32 } while(llGetListLength(k) != 0); 32 } while(llGetListLength(k) != 0);
33 return llDumpList2String(data, "&"); 33 return llDumpList2String(data, "&");
34 } 34 }
35   35  
36 /////////////////////////////////////////////////////////////////////////// 36 ///////////////////////////////////////////////////////////////////////////
37 // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // 37 // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 //
38 /////////////////////////////////////////////////////////////////////////// 38 ///////////////////////////////////////////////////////////////////////////
39 // http://was.fm/secondlife/wanderer 39 // http://was.fm/secondlife/wanderer
40 vector wasCirclePoint(float radius) { 40 vector wasCirclePoint(float radius) {
41 float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); 41 float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
42 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); 42 float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
43 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) 43 if(llPow(x,2) + llPow(y,2) <= llPow(radius,2))
44 return <x, y, 0>; 44 return <x, y, 0>;
45 return wasCirclePoint(radius); 45 return wasCirclePoint(radius);
46 } 46 }
47   47  
48 /////////////////////////////////////////////////////////////////////////// 48 ///////////////////////////////////////////////////////////////////////////
49 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 49 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
50 /////////////////////////////////////////////////////////////////////////// 50 ///////////////////////////////////////////////////////////////////////////
51 // escapes a string in conformance with RFC1738 51 // escapes a string in conformance with RFC1738
52 string wasURLEscape(string i) { 52 string wasURLEscape(string i) {
53 string o = ""; 53 string o = "";
54 do { 54 do {
55 string c = llGetSubString(i, 0, 0); 55 string c = llGetSubString(i, 0, 0);
56 i = llDeleteSubString(i, 0, 0); 56 i = llDeleteSubString(i, 0, 0);
57 if(c == "") jump continue; 57 if(c == "") jump continue;
58 if(c == " ") { 58 if(c == " ") {
59 o += "+"; 59 o += "+";
60 jump continue; 60 jump continue;
61 } 61 }
62 if(c == "\n") { 62 if(c == "\n") {
63 o += "%0D" + llEscapeURL(c); 63 o += "%0D" + llEscapeURL(c);
64 jump continue; 64 jump continue;
65 } 65 }
66 o += llEscapeURL(c); 66 o += llEscapeURL(c);
67 @continue; 67 @continue;
68 } while(i != ""); 68 } while(i != "");
69 return o; 69 return o;
70 } 70 }
71   71  
72 /////////////////////////////////////////////////////////////////////////// 72 ///////////////////////////////////////////////////////////////////////////
73 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 73 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
74 /////////////////////////////////////////////////////////////////////////// 74 ///////////////////////////////////////////////////////////////////////////
75 list wasCSVToList(string csv) { 75 list wasCSVToList(string csv) {
76 list l = []; 76 list l = [];
77 list s = []; 77 list s = [];
78 string m = ""; 78 string m = "";
79 do { 79 do {
80 string a = llGetSubString(csv, 0, 0); 80 string a = llGetSubString(csv, 0, 0);
81 csv = llDeleteSubString(csv, 0, 0); 81 csv = llDeleteSubString(csv, 0, 0);
82 if(a == ",") { 82 if(a == ",") {
83 if(llList2String(s, -1) != "\"") { 83 if(llList2String(s, -1) != "\"") {
84 l += m; 84 l += m;
85 m = ""; 85 m = "";
86 jump continue; 86 jump continue;
87 } 87 }
88 m += a; 88 m += a;
89 jump continue; 89 jump continue;
90 } 90 }
91 if(a == "\"" && llGetSubString(csv, 0, 0) == a) { 91 if(a == "\"" && llGetSubString(csv, 0, 0) == a) {
92 m += a; 92 m += a;
93 csv = llDeleteSubString(csv, 0, 0); 93 csv = llDeleteSubString(csv, 0, 0);
94 jump continue; 94 jump continue;
95 } 95 }
96 if(a == "\"") { 96 if(a == "\"") {
97 if(llList2String(s, -1) != a) { 97 if(llList2String(s, -1) != a) {
98 s += a; 98 s += a;
99 jump continue; 99 jump continue;
100 } 100 }
101 s = llDeleteSubList(s, -1, -1); 101 s = llDeleteSubList(s, -1, -1);
102 jump continue; 102 jump continue;
103 } 103 }
104 m += a; 104 m += a;
105 @continue; 105 @continue;
106 } while(csv != ""); 106 } while(csv != "");
107 // postcondition: length(s) = 0 107 // postcondition: length(s) = 0
108 return l + m; 108 return l + m;
109 } 109 }
110   110  
111 /////////////////////////////////////////////////////////////////////////// 111 ///////////////////////////////////////////////////////////////////////////
112 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 112 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
113 /////////////////////////////////////////////////////////////////////////// 113 ///////////////////////////////////////////////////////////////////////////
114 string wasListToCSV(list l) { 114 string wasListToCSV(list l) {
115 list v = []; 115 list v = [];
116 do { 116 do {
117 string a = llDumpList2String( 117 string a = llDumpList2String(
118 llParseStringKeepNulls( 118 llParseStringKeepNulls(
119 llList2String( 119 llList2String(
120 l, 120 l,
121 0 121 0
122 ), 122 ),
123 ["\""], 123 ["\""],
124 [] 124 []
125 ), 125 ),
126 "\"\"" 126 "\"\""
127 ); 127 );
128 if(llParseStringKeepNulls( 128 if(llParseStringKeepNulls(
129 a, 129 a,
130 [" ", ",", "\n", "\""], [] 130 [" ", ",", "\n", "\""], []
131 ) != 131 ) !=
132 (list) a 132 (list) a
133 ) a = "\"" + a + "\""; 133 ) a = "\"" + a + "\"";
134 v += a; 134 v += a;
135 l = llDeleteSubList(l, 0, 0); 135 l = llDeleteSubList(l, 0, 0);
136 } while(l != []); 136 } while(l != []);
137 return llDumpList2String(v, ","); 137 return llDumpList2String(v, ",");
138 } 138 }
139   139  
140 /////////////////////////////////////////////////////////////////////////// 140 ///////////////////////////////////////////////////////////////////////////
141 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // 141 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
142 /////////////////////////////////////////////////////////////////////////// 142 ///////////////////////////////////////////////////////////////////////////
143 // unescapes a string in conformance with RFC1738 143 // unescapes a string in conformance with RFC1738
144 string wasURLUnescape(string i) { 144 string wasURLUnescape(string i) {
145 return llUnescapeURL( 145 return llUnescapeURL(
146 llDumpList2String( 146 llDumpList2String(
147 llParseString2List( 147 llParseString2List(
148 llDumpList2String( 148 llDumpList2String(
149 llParseString2List( 149 llParseString2List(
150 i, 150 i,
151 ["+"], 151 ["+"],
152 [] 152 []
153 ), 153 ),
154 " " 154 " "
155 ), 155 ),
156 ["%0D%0A"], 156 ["%0D%0A"],
157 [] 157 []
158 ), 158 ),
159 "\n" 159 "\n"
160 ) 160 )
161 ); 161 );
162 } 162 }
163   163  
164 /////////////////////////////////////////////////////////////////////////// 164 ///////////////////////////////////////////////////////////////////////////
165 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 // 165 // Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 //
166 /////////////////////////////////////////////////////////////////////////// 166 ///////////////////////////////////////////////////////////////////////////
167 list wasSetIntersect(list a, list b) { 167 list wasSetIntersect(list a, list b) {
168 if(llGetListLength(a) == 0) return []; 168 if(llGetListLength(a) == 0) return [];
169 string i = llList2String(a, 0); 169 string i = llList2String(a, 0);
170 a = llDeleteSubList(a, 0, 0); 170 a = llDeleteSubList(a, 0, 0);
171 if(llListFindList(b, (list)i) == -1) 171 if(llListFindList(b, (list)i) == -1)
172 return wasSetIntersect(a, b); 172 return wasSetIntersect(a, b);
173 return i + wasSetIntersect(a, b); 173 return i + wasSetIntersect(a, b);
174 } 174 }
175   175  
176 // configuration data 176 // configuration data
177 string configuration = ""; 177 string configuration = "";
178 // callback URL 178 // callback URL
179 string URL = ""; 179 string URL = "";
180 // store message over state. 180 // store message over state.
181 string data = ""; 181 string data = "";
-   182 string jump_table = "";
-   183 string messageHash = "";
182   184  
183 default { 185 default {
184 state_entry() { 186 state_entry() {
185 llOwnerSay("[AI] Starting..."); 187 llOwnerSay("[AI] Starting...");
186 llSetTimerEvent(10); 188 llSetTimerEvent(10);
187 } 189 }
188 link_message(integer sender, integer num, string message, key id) { 190 link_message(integer sender, integer num, string message, key id) {
189 if(id != "configuration") return; 191 if(id != "configuration") return;
190 llOwnerSay("[AI] Got configuration..."); 192 llOwnerSay("[AI] Got configuration...");
191 configuration = message; 193 configuration = message;
-   194
-   195 // Subscribe to MQTT messages.
-   196 jump_table = "subscribe";
192 state listen_group; 197 state url;
193 } 198 }
194 timer() { 199 timer() {
195 llOwnerSay("[AI] Requesting configuration..."); 200 llOwnerSay("[AI] Requesting configuration...");
196 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY); 201 llMessageLinked(LINK_THIS, 0, "configuration", NULL_KEY);
197 } 202 }
198 on_rez(integer num) { 203 on_rez(integer num) {
199 llResetScript(); 204 llResetScript();
200 } 205 }
201 changed(integer change) { 206 changed(integer change) {
202 if((change & CHANGED_INVENTORY) || 207 if((change & CHANGED_INVENTORY) ||
203 (change & CHANGED_REGION_START) || 208 (change & CHANGED_REGION_START) ||
204 (change & CHANGED_OWNER)) { 209 (change & CHANGED_OWNER)) {
205 llResetScript(); 210 llResetScript();
206 } 211 }
207 } 212 }
208 state_exit() { 213 state_exit() {
209 llSetTimerEvent(0); 214 llSetTimerEvent(0);
210 } 215 }
211 } 216 }
-   217  
-   218 state url {
-   219 state_entry() {
-   220 // DEBUG
-   221 llOwnerSay("[AI] Requesting URL...");
-   222 llRequestURL();
-   223 }
-   224 http_request(key id, string method, string body) {
-   225 if(method != URL_REQUEST_GRANTED) return;
-   226 URL = body;
-   227
-   228 // DEBUG
-   229 llOwnerSay("[AI] Got URL...");
-   230
-   231 if(jump_table == "subscribe")
-   232 state subscribe;
-   233 if(jump_table == "publish")
-   234 state publish;
-   235 }
-   236 on_rez(integer num) {
-   237 llResetScript();
-   238 }
-   239 changed(integer change) {
-   240 if((change & CHANGED_INVENTORY) ||
-   241 (change & CHANGED_REGION_START) ||
-   242 (change & CHANGED_OWNER)) {
-   243 llResetScript();
-   244 }
-   245 }
-   246 }
-   247  
-   248 state subscribe {
-   249 state_entry() {
-   250 // DEBUG
-   251 llOwnerSay("[AI] Subscribing to Corrade AI...");
-   252 llInstantMessage(
-   253 wasKeyValueGet(
-   254 "corrade",
-   255 configuration
-   256 ),
-   257 wasKeyValueEncode(
-   258 [
-   259 "command", "MQTT",
-   260 "group", wasURLEscape(
-   261 wasKeyValueGet(
-   262 "group",
-   263 configuration
-   264 )
-   265 ),
-   266 "password", wasURLEscape(
-   267 wasKeyValueGet(
-   268 "password",
-   269 configuration
-   270 )
-   271 ),
-   272 // Subscribe to Corrade AI
-   273 "action", "subscribe",
-   274 "id", wasURLEscape(
-   275 wasKeyValueGet(
-   276 "ai subscription",
-   277 configuration
-   278 )
-   279 ),
-   280 // Corrade AI listening host.
-   281 "host", wasURLEscape(
-   282 wasKeyValueGet(
-   283 "ai host",
-   284 configuration
-   285 )
-   286 ),
-   287 // Corrade AI listening port.
-   288 "port", wasURLEscape(
-   289 wasKeyValueGet(
-   290 "ai port",
-   291 configuration
-   292 )
-   293 ),
-   294 // Corrade AI credentials.
-   295 "username", wasURLEscape(
-   296 wasKeyValueGet(
-   297 "ai username",
-   298 configuration
-   299 )
-   300 ),
-   301 "secret", wasURLEscape(
-   302 wasKeyValueGet(
-   303 "ai secret",
-   304 configuration
-   305 )
-   306 ),
-   307 // Use the SIML module of Corrade AI.
-   308 "topic", "SIML",
-   309 // Send the result of the MQTT command to this URL.
-   310 "callback", wasURLEscape(URL)
-   311 ]
-   312 )
-   313 );
-   314 }
-   315
-   316 http_request(key id, string method, string body) {
-   317 llHTTPResponse(id, 200, "OK");
-   318 llReleaseURL(URL);
-   319 if(wasKeyValueGet("command", body) != "MQTT" ||
-   320 wasKeyValueGet("success", body) != "True") {
-   321 // DEBUG
-   322 llOwnerSay("[AI] Unable to subscribe to MQTT topic: " +
-   323 wasURLUnescape(
-   324 wasKeyValueGet("error", body)
-   325 )
-   326 );
-   327 llResetScript();
-   328 }
-   329
-   330 state listen_group;
-   331 }
-   332 on_rez(integer num) {
-   333 llResetScript();
-   334 }
-   335 changed(integer change) {
-   336 if((change & CHANGED_INVENTORY) ||
-   337 (change & CHANGED_REGION_START) ||
-   338 (change & CHANGED_OWNER)) {
-   339 llResetScript();
-   340 }
-   341 }
-   342 state_exit() {
-   343 llSetTimerEvent(0);
-   344 }
-   345 }
212   346  
213 state listen_group { 347 state listen_group {
214 state_entry() { 348 state_entry() {
215 // DEBUG 349 // DEBUG
216 llOwnerSay("[AI] Waiting for group messages..."); 350 llOwnerSay("[AI] Waiting for group messages...");
217 } 351 }
218 link_message(integer sender, integer num, string message, key id) { 352 link_message(integer sender, integer num, string message, key id) {
219 // We only care about notifications now. 353 // We only care about notifications now.
220 if(id != "notification") 354 if(id != "notification")
221 return; 355 return;
222 356
223 // This script only processes group notifications. 357 // Listen to group message notifications.
224 if(wasKeyValueGet("type", message) != "group") 358 if(wasKeyValueGet("type", message) != "group")
225 return; 359 return;
226 360
227 // Get the sent message. 361 // Get the sent message.
228 data = wasURLUnescape( 362 data = wasURLUnescape(
229 wasKeyValueGet( 363 wasKeyValueGet(
230 "message", 364 "message",
231 message 365 message
232 ) 366 )
233 ); 367 );
234 368
235 // Check if this is an eggdrop command. 369 // Check if this is an eggdrop command.
236 if(llGetSubString(data, 0, 0) != 370 if(llGetSubString(data, 0, 0) !=
237 wasKeyValueGet("command", configuration)) 371 wasKeyValueGet("command", configuration))
238 return; 372 return;
239 373
240 // Check if the command matches the current module. 374 // Check if the command matches the current module.
241 list command = llParseString2List(data, [" "], []); 375 list command = llParseString2List(data, [" "], []);
242 if(llList2String(command, 0) != 376 if(llList2String(command, 0) !=
243 wasKeyValueGet("command", configuration) + 377 wasKeyValueGet("command", configuration) +
244 wasKeyValueGet("nickname", configuration)) 378 wasKeyValueGet("nickname", configuration))
245 return; 379 return;
246 380
247 // Remove command. 381 // Remove command.
248 command = llDeleteSubList(command, 0, 0); 382 command = llDeleteSubList(command, 0, 0);
249 383
250 // Dump the rest of the message. 384 // Dump the rest of the message.
251 data = llDumpList2String(command, " "); 385 data = llDumpList2String(command, " ");
252   386  
253 // Get an URL. 387 // Get an URL.
-   388 jump_table = "publish";
254 state url; 389 state url;
255 } 390 }
256 on_rez(integer num) { 391 on_rez(integer num) {
257 llResetScript(); 392 llResetScript();
258 } 393 }
259 changed(integer change) { 394 changed(integer change) {
260 if((change & CHANGED_INVENTORY) || 395 if((change & CHANGED_INVENTORY) ||
261 (change & CHANGED_REGION_START) || 396 (change & CHANGED_REGION_START) ||
262 (change & CHANGED_OWNER)) { 397 (change & CHANGED_OWNER)) {
263 llResetScript(); 398 llResetScript();
264 } 399 }
265 } 400 }
266 } 401 }
267   402  
268 state url { -  
269 state_entry() { -  
270 // DEBUG -  
271 llOwnerSay("[AI] Requesting URL..."); -  
272 llRequestURL(); -  
273 } -  
274 http_request(key id, string method, string body) { -  
275 if(method != URL_REQUEST_GRANTED) return; -  
276 URL = body; -  
277 // DEBUG -  
278 llOwnerSay("[AI] Got URL..."); -  
279 state version; -  
280 } -  
281 on_rez(integer num) { -  
282 llResetScript(); -  
283 } -  
284 changed(integer change) { -  
285 if((change & CHANGED_INVENTORY) || -  
286 (change & CHANGED_REGION_START) || -  
287 (change & CHANGED_OWNER)) { -  
288 llResetScript(); -  
289 } -  
290 } -  
291 } -  
292   -  
293 state version { 403 state publish {
294 state_entry() { 404 state_entry() {
295 // DEBUG 405 // DEBUG
296 llOwnerSay("[AI] Sending to AI for processing..."); 406 llOwnerSay("[AI] Sending to AI for processing...");
-   407
-   408 messageHash = llSHA1String(data);
-   409
297 llInstantMessage( 410 llInstantMessage(
298 wasKeyValueGet( 411 wasKeyValueGet(
299 "corrade", 412 "corrade",
300 configuration 413 configuration
301 ), 414 ),
302 wasKeyValueEncode( 415 wasKeyValueEncode(
303 [ 416 [
304 "command", "ai", 417 "command", "MQTT",
305 "group", wasURLEscape( 418 "group", wasURLEscape(
306 wasKeyValueGet( 419 wasKeyValueGet(
307 "group", 420 "group",
308 configuration 421 configuration
309 ) 422 )
310 ), 423 ),
311 "password", wasURLEscape( 424 "password", wasURLEscape(
312 wasKeyValueGet( 425 wasKeyValueGet(
313 "password", 426 "password",
314 configuration 427 configuration
315 ) 428 )
316 ), 429 ),
317 "action", "process", 430 "action", "publish",
-   431 // Corrade AI listening host.
-   432 "host", wasURLEscape(
-   433 wasKeyValueGet(
-   434 "ai host",
-   435 configuration
-   436 )
-   437 ),
-   438 // Corrade AI listening port.
-   439 "port", wasURLEscape(
-   440 wasKeyValueGet(
-   441 "ai port",
-   442 configuration
-   443 )
-   444 ),
-   445 // Corrade AI credentials.
318 "message", wasURLEscape(data), 446 "username", wasURLEscape(
-   447 wasKeyValueGet(
-   448 "ai username",
-   449 configuration
-   450 )
-   451 ),
-   452 "secret", wasURLEscape(
-   453 wasKeyValueGet(
-   454 "ai secret",
-   455 configuration
-   456 )
-   457 ),
-   458 // Use the SIML module of Corrade AI.
-   459 "topic", "SIML",
-   460 "payload", wasURLEscape(
-   461 wasKeyValueEncode(
-   462 [
-   463 // The hash is an identifier that will allow responses from Corrade AI
-   464 // for various messages to be distinguished. It can be any identifier
-   465 // but a handy way of generating an identifier is to hash the message.
-   466 "Hash", messageHash,
-   467 // Note the double escaping!
-   468 "Message", wasURLEscape(data)
-   469 ]
-   470 )
-   471 ),
319 "callback", wasURLEscape(URL) 472 "callback", wasURLEscape(URL)
320 ] 473 ]
321 ) 474 )
322 ); 475 );
323 llSetTimerEvent(60); 476 llSetTimerEvent(60);
324 } 477 }
325 http_request(key id, string method, string body) { 478 http_request(key id, string method, string body) {
326 llHTTPResponse(id, 200, "OK"); 479 llHTTPResponse(id, 200, "OK");
327 llReleaseURL(URL); 480 llReleaseURL(URL);
328 if(wasKeyValueGet("command", body) != "ai" || 481 if(wasKeyValueGet("command", body) != "MQTT" ||
329 wasKeyValueGet("success", body) != "True") { 482 wasKeyValueGet("success", body) != "True") {
330 // DEBUG 483 // DEBUG
331 llOwnerSay("[AI] Unable to get processed message: " + 484 llOwnerSay("[AI] Unable to publish message: " +
332 wasURLUnescape( 485 wasURLUnescape(
333 wasKeyValueGet("error", body) 486 wasKeyValueGet("data", body)
334 ) 487 )
335 ); 488 );
336 state listen_group; 489 state listen_group;
337 } 490 }
-   491
-   492 // DEBUG
-   493 llOwnerSay("[AI] Message published successfully...");
-   494 }
-   495 link_message(integer sender, integer num, string message, key id) {
-   496 // We only care about notifications now.
-   497 if(id != "notification")
-   498 return;
-   499
-   500 // Listen to MQTT messages.
-   501 if(wasKeyValueGet("type", message) != "MQTT")
-   502 return;
338 503
-   504 // Get the sent message.
-   505 data = wasURLUnescape(
-   506 wasKeyValueGet(
-   507 "payload",
-   508 message
-   509 )
-   510 );
-   511
-   512 string hash = wasURLUnescape(
-   513 wasKeyValueGet(
-   514 "Hash",
-   515 data
-   516 )
-   517 );
-   518
-   519 string serverMessage = wasURLUnescape(
-   520 wasKeyValueGet(
-   521 "ServerMessage",
-   522 data
-   523 )
-   524 );
-   525
-   526 // Skip generated messages that are not for the published message.
-   527 if(hash != messageHash ||
-   528 serverMessage != "True")
-   529 return;
-   530
339 // Get the processed message. 531 data = wasURLUnescape(
-   532 wasKeyValueGet(
-   533 "Message",
-   534 data
-   535 )
340 data = wasKeyValueGet("data", body); 536 );
341 537
342 state tell; 538 state tell;
343 } 539 }
344 timer() { 540 timer() {
345 llReleaseURL(URL); 541 llReleaseURL(URL);
346 state listen_group; 542 state listen_group;
347 } 543 }
348 on_rez(integer num) { 544 on_rez(integer num) {
349 llResetScript(); 545 llResetScript();
350 } 546 }
351 changed(integer change) { 547 changed(integer change) {
352 if((change & CHANGED_INVENTORY) || 548 if((change & CHANGED_INVENTORY) ||
353 (change & CHANGED_REGION_START) || 549 (change & CHANGED_REGION_START) ||
354 (change & CHANGED_OWNER)) { 550 (change & CHANGED_OWNER)) {
355 llResetScript(); 551 llResetScript();
356 } 552 }
357 } 553 }
358 state_exit() { 554 state_exit() {
359 llSetTimerEvent(0); 555 llSetTimerEvent(0);
360 } 556 }
361 } 557 }
362   558  
363 state tell { 559 state tell {
364 state_entry() { 560 state_entry() {
365 // DEBUG 561 // DEBUG
366 llOwnerSay("[AI] Sending to group."); 562 llOwnerSay("[AI] Sending to group.");
367 llInstantMessage( 563 llInstantMessage(
368 wasKeyValueGet( 564 wasKeyValueGet(
369 "corrade", 565 "corrade",
370 configuration 566 configuration
371 ), 567 ),
372 wasKeyValueEncode( 568 wasKeyValueEncode(
373 [ 569 [
374 "command", "tell", 570 "command", "tell",
375 "group", wasURLEscape( 571 "group", wasURLEscape(
376 wasKeyValueGet( 572 wasKeyValueGet(
377 "group", 573 "group",
378 configuration 574 configuration
379 ) 575 )
380 ), 576 ),
381 "password", wasURLEscape( 577 "password", wasURLEscape(
382 wasKeyValueGet( 578 wasKeyValueGet(
383 "password", 579 "password",
384 configuration 580 configuration
385 ) 581 )
386 ), 582 ),
387 "entity", "group", 583 "entity", "group",
388 "message", data // message is already encoded 584 "message", wasURLEscape(data)
389 ] 585 ]
390 ) 586 )
391 ); 587 );
392 state listen_group; 588 state listen_group;
393 } 589 }
394 } 590 }
395   591