/* * Subsystem Status Notifications Program * * Duplicates a fair amount of _power, not for redistribution. */ #define DEBUG #include #define CLIENT_VERSION "0.0.1" #define CLIENT_VERSION_TAGS "alpha 1" integer power_on = 1; integer sys_state = 0xFFFFFFFF; integer forbidden_state = 0; integer masked_state = 0; string power_systems = "{}"; string power_system_names = "{}"; integer C_LIGHTS = NOWHERE; update_state() { string s_status = llLinksetDataRead("status"); sys_state = (integer)getjs(s_status, ["state"]); power_on = (integer)getjs(s_status, ["on"]); forbidden_state = (integer)getjs(s_status, ["forbidden"]); masked_state = 0; if (!power_on) { // Power off - all subsystems will be off, and light bus will be messaged. // No need to continue update. #ifdef DEBUG echo("Powered off, no subsystems to check"); #endif return; } integer psi = 0; string ps; while ((ps = getjs(power_systems, [(string)psi])) != JSON_INVALID) { integer system_forbidden = (forbidden_state & (1 << psi)) != 0; integer system_enabled = (sys_state & (1 << psi)) != 0; if (system_forbidden) { // System forbidden if (system_enabled) { // System forbidden, but status reports enabled. // Shouldn't happen, sanity check just in case. sys_state = sys_state & ~(1 << psi); } } else if (system_enabled) { // System enabled list psreqs = js2list(getjs(ps, ["req"])); integer psri = count(psreqs); while (psri--) { integer psreq = geti(psreqs, psri); if (!(sys_state & (1 << psreq)) || ((forbidden_state & (1 << psreq)) != 0)) { // Requirement disabled or forbidden, system masked. sys_state = sys_state & ~(1 << psi); masked_state = masked_state | (1 << psi); jump psribrk; } } @psribrk; } // else | System disabled ++psi; } if (C_LIGHTS == NOWHERE) { echo("[" + PROGRAM_NAME + "] light bus channel not set"); return; } list light_msg = ["subsys", sys_state, masked_state, forbidden_state]; io_tell(NULL_KEY, C_LIGHTS, concat(light_msg, " ")); } main(integer src, integer n, string m, key outs, key ins, key user) { #ifdef DEBUG echo("[" + PROGRAM_NAME + "] signal " + (string)n + ": " + m); #endif if (n == SIGNAL_INVOKE) { list argv = split(m, " "); integer argc = count(argv); string cmd = gets(argv, 1); string output_msg = ""; if (argc == 1 || cmd == "help") { output_msg = "Syntax: " + PROGRAM_NAME + " "; } else if (cmd == "query") { // send current status without updating list light_msg = ["subsys", sys_state, masked_state, forbidden_state]; io_tell(NULL_KEY, C_LIGHTS, concat(light_msg, " ")); } else { output_msg = "Unknown command \"" + cmd + "\"."; } if(output_msg != "") print(outs, user, output_msg); } else if (n == SIGNAL_NOTIFY) { list argv = splitnulls(m, " "); string cmd = gets(argv, 1); if (cmd == "update") { update_state(); } #ifdef DEBUG else { echo("[" + PROGRAM_NAME + "] unrecognised notify " + m); } #endif } else if (n == SIGNAL_INIT) { #ifdef DEBUG echo("[" + PROGRAM_NAME + "] init event"); #endif if (llGetAttached()) { C_LIGHTS = 105 - (integer)("0x" + substr(avatar, 29, 35)); } else { C_LIGHTS = 105 - (integer)("0x" + substr(KERNEL, 29, 35)); } string s_power = llLinksetDataRead("power"); power_systems = getjs(s_power, ["system"]); integer psi = 0; string ps = ""; while ((ps = getjs(power_systems, [(string)psi])) != JSON_INVALID) { string psname = getjs(ps, ["name"]); power_system_names = setjs(power_system_names, [psname], (string)psi); ++psi; } #ifdef DEBUG echo("[" + PROGRAM_NAME + "] (DEBUG) available subsystems: " + (string)psi); #endif update_state(); } else if (n == SIGNAL_UNKNOWN_SCRIPT) { echo("[" + PROGRAM_NAME + "] failed to run '" + m + "' (kernel could not find the program specified)"); } else { echo("[" + PROGRAM_NAME + "] unimplemented signal " + (string)n + ": " + m); } } #include