// SPDX-License-Identifier: MIT // Copyright (c) 2026 Incoprea // Audit sprite-sheet specifications // Not compiled or tested in-world // Setup: Add a saved plain-text notecard named Config. Place referenced textures in the same prim. Use positive integer grid sizes. Touch as owner; reset to scan again. // Stop / restore: Remove or disable. This auditor never changes object settings or inventory. // Notes: Reads at most 40 short lines, skips blanks and # comments, and times out each asynchronous request after 20 seconds. Frames cannot exceed grid cells. Does not inspect pixels to verify the claimed sprite sheet dimensions or start animation. // License: see LICENSE in this distribution. // Original Incoprea example. MIT. integer numberOK(string value) { integer i; if(value=="" || llStringLength(value)>6)return FALSE; for(i=0;i64 || rows>64 || frames<1 || frames>cols*rows)issue("Invalid grid or frame count."); if(llGetInventoryType(llList2String(p,0))!=INVENTORY_TEXTURE)issue("Referenced texture missing."); } default { touch_start(integer touches) { if(llDetectedKey(0)!=llGetOwner())return; if(pending!=NULL_KEY || finished) { llOwnerSay("Reset before starting another audit."); return; } if(llGetInventoryType("Config")!=INVENTORY_NOTECARD) { llOwnerSay("Add a saved Config notecard."); return; } requestLine(); } dataserver(key query,string data) { if(query!=pending || pending==NULL_KEY)return; if(data==EOF) { finish(); return; } data=llStringTrim(data,STRING_TRIM); if(data!="" && llGetSubString(data,0,0)!="#") { ++scannedRows; check(data); } ++lineNumber; if(lineNumber>=40) { llOwnerSay("40-line cap reached; report may be partial."); finish(); return; } requestLine(); } timer() { pending=NULL_KEY; finished=TRUE; llSetTimerEvent(0); llOwnerSay("Audit timed out; partial checks only. Reset to retry."); } changed(integer flags) { if(flags & (CHANGED_OWNER|CHANGED_INVENTORY))llResetScript(); } }