corrade-lsl-templates – Blame information for rev 25

Subversion Repositories:
Rev:
Rev Author Line No. Line
2 office 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
3 ///////////////////////////////////////////////////////////////////////////
4 //
5 // A template HUD script for Corrade that reads a configuration notecard
6 // and then feeds that configuration to various other components of the HUD
7 // that request the configuration. Additionally, this HUD is programmed to
8 // "fold" and "unfold" depending on whether Corrade is online or not. For
9 // more information on the Corrade scripted agent please see the URL:
25 office 10 // http://grimore.org/secondlife/scripted_agents/corrade
2 office 11 //
12 ///////////////////////////////////////////////////////////////////////////
13  
14 ///////////////////////////////////////////////////////////////////////////
15 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
16 ///////////////////////////////////////////////////////////////////////////
17 string wasKeyValueGet(string k, string data) {
18 if(llStringLength(data) == 0) return "";
19 if(llStringLength(k) == 0) return "";
20 list a = llParseString2List(data, ["&", "="], []);
21 integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
22 if(i != -1) return llList2String(a, 2*i+1);
23 return "";
24 }
25  
26 ///////////////////////////////////////////////////////////////////////////
27 // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 //
28 ///////////////////////////////////////////////////////////////////////////
29 string wasKeyValueEncode(list data) {
30 list k = llList2ListStrided(data, 0, -1, 2);
31 list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
32 data = [];
33 do {
34 data += llList2String(k, 0) + "=" + llList2String(v, 0);
35 k = llDeleteSubList(k, 0, 0);
36 v = llDeleteSubList(v, 0, 0);
37 } while(llGetListLength(k) != 0);
38 return llDumpList2String(data, "&");
39 }
40  
41 ///////////////////////////////////////////////////////////////////////////
42 // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 //
43 ///////////////////////////////////////////////////////////////////////////
44 // escapes a string in conformance with RFC1738
45 string wasURLEscape(string i) {
46 string o = "";
47 do {
48 string c = llGetSubString(i, 0, 0);
49 i = llDeleteSubString(i, 0, 0);
50 if(c == "") jump continue;
51 if(c == " ") {
52 o += "+";
53 jump continue;
54 }
55 if(c == "\n") {
56 o += "%0D" + llEscapeURL(c);
57 jump continue;
58 }
59 o += llEscapeURL(c);
60 @continue;
61 } while(i != "");
62 return o;
63 }
64  
65 // for notecard reading
66 integer line = 0;
67  
68 // key-value data will be read into this list
69 list tuples = [];
70 // Corrade's online status.
71 integer online = FALSE;
72 integer open = FALSE;
73 string URL = "";
74  
75 default {
76 state_entry() {
77 if(llGetInventoryType("configuration") != INVENTORY_NOTECARD) {
78 llOwnerSay("Sorry, could not find a configuration inventory notecard.");
79 return;
80 }
81 // DEBUG
82 llOwnerSay("Reading configuration file...");
83 llGetNotecardLine("configuration", line);
84 }
85 dataserver(key id, string data) {
86 if(data == EOF) {
87 // invariant, length(tuples) % 2 == 0
88 if(llGetListLength(tuples) % 2 != 0) {
89 llOwnerSay("Error in configuration notecard.");
90 return;
91 }
92 key CORRADE = llList2Key(
93 tuples,
94 llListFindList(
95 tuples,
96 [
97 "corrade"
98 ]
99 )
100 +1);
101 if(CORRADE == NULL_KEY) {
102 llOwnerSay("Error in configuration notecard: corrade");
103 return;
104 }
105 string GROUP = llList2String(
106 tuples,
107 llListFindList(
108 tuples,
109 [
110 "group"
111 ]
112 )
113 +1);
114 if(GROUP == "") {
115 llOwnerSay("Error in configuration notecard: group");
116 return;
117 }
118 string PASSWORD = llList2String(
119 tuples,
120 llListFindList(
121 tuples,
122 [
123 "password"
124 ]
125 )
126 +1);
127 if(PASSWORD == "") {
128 llOwnerSay("Error in configuration notecard: password");
129 return;
130 }
131 string VERSION = llList2String(
132 tuples,
133 llListFindList(
134 tuples,
135 [
136 "version"
137 ]
138 )
139 +1);
140 if(VERSION == "") {
141 llOwnerSay("Error in configuration notecard: version");
142 return;
143 }
144 // DEBUG
145 llOwnerSay("Read configuration notecard...");
146 state configuration;
147 }
148 if(data == "") jump continue;
149 integer i = llSubStringIndex(data, "#");
150 if(i != -1) data = llDeleteSubString(data, i, -1);
151 list o = llParseString2List(data, ["="], []);
152 // get rid of starting and ending quotes
153 string k = llDumpList2String(
154 llParseString2List(
155 llStringTrim(
156 llList2String(
157 o,
158  
159 ),
160 STRING_TRIM),
161 ["\""], []
162 ), "\"");
163 string v = llDumpList2String(
164 llParseString2List(
165 llStringTrim(
166 llList2String(
167 o,
168 1
169 ),
170 STRING_TRIM),
171 ["\""], []
172 ), "\"");
173 if(k == "" || v == "") jump continue;
174 tuples += k;
175 tuples += v;
176 @continue;
177 llGetNotecardLine("configuration", ++line);
178 }
179 attach(key id) {
180 llResetScript();
181 }
182 on_rez(integer num) {
183 llResetScript();
184 }
185 changed(integer change) {
186 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
187 llResetScript();
188 }
189 }
190 }
191  
192 state configuration {
193 state_entry() {
194 // DEBUG
195 llOwnerSay("Configuration ready...");
196 llMessageLinked(LINK_SET, 0, "retract", NULL_KEY);
197 llSetTimerEvent(1);
198 }
199 timer() {
200 llRequestAgentData(
201 (key)wasKeyValueGet(
202 "corrade",
203 wasKeyValueEncode(tuples)
204 ),
205 DATA_ONLINE
206 );
207 llSetTimerEvent(5);
208 }
209 dataserver(key id, string data) {
210 if(data != "1") {
211 if(online == TRUE) {
212 // DEBUG
213 llOwnerSay("Corrade is not online, shutting down...");
214 llMessageLinked(LINK_SET, 0, "retract", NULL_KEY);
215 online = FALSE;
216 }
217 return;
218 }
219 online = TRUE;
220 }
221 touch_start(integer total_number) {
222 if(!open && online) {
223 // DEBUG
224 llOwnerSay("Getting URL...");
225 llRequestURL();
226 return;
227 }
228 llMessageLinked(LINK_SET, 0, "retract", NULL_KEY);
229 open = FALSE;
230 }
231 http_request(key id, string method, string body) {
232 llHTTPResponse(id, 200, "OK");
233 llReleaseURL(URL);
234 string configuration = wasKeyValueEncode(tuples);
235 if(method == URL_REQUEST_GRANTED) {
236 llOwnerSay("Checking version...");
237  
238 URL = body;
239 llInstantMessage(
240 wasKeyValueGet(
241 "corrade",
242 configuration
243 ),
244 wasKeyValueEncode(
245 [
246 "command", "version",
247 "group", wasURLEscape(
248 wasKeyValueGet(
249 "group",
250 configuration
251 )
252 ),
253 "password", wasURLEscape(
254 wasKeyValueGet(
255 "password",
256 configuration
257 )
258 ),
259 "callback", wasURLEscape(URL)
260 ]
261 )
262 );
263 return;
264 }
265 if(wasKeyValueGet("command", body) != "version" ||
266 wasKeyValueGet("success", body) != "True") {
267 llOwnerSay("Version check failed...");
268 return;
269 }
270 list v = llParseString2List(
271 wasKeyValueGet(
272 "data",
273 body
274 ),
275 ["."],
276 []
277 );
278 integer receivedVersion = (integer)(llList2String(v, 0) + llList2String(v, 1));
279 v = llParseString2List(
280 wasKeyValueGet(
281 "version",
282 configuration
283 ),
284 ["."],
285 []
286 );
287 integer notecardVersion = (integer)(llList2String(v, 0) + llList2String(v, 1));
288 if(receivedVersion < notecardVersion) {
289 llOwnerSay("HUD version is incompatible! You need a Corrade of at least version: " +
290 wasKeyValueGet(
291 "version",
292 configuration
293 ) +
294 " for this HUD."
295 );
296 llMessageLinked(LINK_SET, 0, "retract", NULL_KEY);
297 open = FALSE;
298 return;
299 }
300 llOwnerSay("Version is compatible. Deploying HUD...");
301 llMessageLinked(LINK_SET, 0, "deploy", NULL_KEY);
302 open = TRUE;
303 return;
304 }
305 link_message(integer sender, integer num, string message, key id) {
306 if(message != "configuration") return;
307 llMessageLinked(sender, 0, wasKeyValueEncode(tuples), "configuration");
308 }
309 attach(key id) {
310 llResetScript();
311 }
312 on_rez(integer num) {
313 llResetScript();
314 }
315 changed(integer change) {
316 if((change & CHANGED_INVENTORY) || (change & CHANGED_REGION_START)) {
317 llResetScript();
318 }
319 }
320 }