Difference between revisions of "Snoopers Doc"

From Elite Wiki
m (note about NPCTraffic)
m (Retagged!)
 
(14 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
== Overview ==
 
== Overview ==
snoopers.js is the script for the galactic news network. OXPs (worldScripts) can insert own messages by passing a object to [[Snoopers]].
+
[[Snoopers]] introduces the Galactic News Network with 4 news agencies. It can be used by other OXPs to implement own newsflashes easily and the passed news can be shown directly or by the time based mechanism in Snoopers and a callback after displaying can be used.
{{CodeEx|codeex=worldScripts.snoopers.insertNews(obj);}}
 
  
After displaying this message Snoopers tries to callback and passes the first 20 chars of the message.
+
 
;Callback:{{CodeEx|codeex=worldScripts[obj.ID].newsDisplayed(obj.Message.substr(0,20));}}
+
Missionscreens in <tt>snoopers.js</tt> are using the screenID {{AV|2.5}}
 +
{{CodeEx|codeex="snoopers"}}
 +
 
 +
*See [[#insertNews()|insertNews()]], [[#Callback|Callback]]
  
  
 
== Properties ==
 
== Properties ==
 +
<sup>OXPC</sup> - Marked properties can be configured via [[OXPConfig]].
 +
 
=== logging ===
 
=== logging ===
:Boolean. Switches extended logging on/off and can be configured via OXPConfig2. Default is false.
+
:Boolean. Switches extended logging on/off. Default is false. <sup>OXPC</sup>
  
 
=== audio ===
 
=== audio ===
:Boolean. Switches audio for internal news on/off and can be configured via OXPConfig2. Default is true.
+
:Boolean. Switches audio for internal news on/off. Default is true. <sup>OXPC</sup>
  
 
=== extraA ===
 
=== extraA ===
:Boolean. Switches full mode for internal news on/off and can be configured via OXPConfig2. Default is true.
+
:Boolean. Switches full mode for internal news on/off. Default is true. <sup>OXPC</sup>
  
 
=== sliderA ===
 
=== sliderA ===
:Integer. Chance for newsflashes and can be configured via OXPConfig2. Default is 0x3 (#3).
+
:Integer. Chance for newsflashes. Default is 0x3 (#3). <sup>OXPC</sup>
  
 
=== sliderB ===
 
=== sliderB ===
:Integer. Max days between newsflashes and can be configured via OXPConfig2. Default is 0x19 (#25).
+
:Integer. Max days between newsflashes. Default is 0x19 (#25). <sup>OXPC</sup>
  
 
=== sliderC ===
 
=== sliderC ===
:Integer. Brightness for displayed model and can be configured via OXPConfig2. Default is 0x4 (#4). This will only affect shadered models which support it. Uses the fuel property.
+
:Integer. Brightness for displayed model. Default is 0x4 (#4). This will only affect shadered models which support it. Uses the fuel property. <sup>OXPC</sup>
  
  
 
== Functions ==
 
== Functions ==
 
=== insertNews() ===
 
=== insertNews() ===
{{CodeEx|codeex=this.insertNews = function(obj)}}
+
{{CodeEx|codeex=worldScripts.snoopers.insertNews( obj )}}
Handles incoming message from other OXPs and stores it if all checks are passed. Snoopers stores up to 10 messages and 20 CRCs.
+
{{CodeExTime|native=0.000081|extension=0.000017|js=0.000337}}
 +
Handles incoming messages from other OXPs worldScripts. If <tt>.Direct</tt> is not used Snoopers stores up to 10 messages and 20 CRCs and all checks are passed (e.g. only 1 news per worldScript is allowed). <tt>.Direct</tt> news are displayed immediately and won't be stored. Make sure that the object is extensible and not sealed or frozen.
  
 
'''Parameters'''
 
'''Parameters'''
Line 36: Line 41:
  
 
'''Returns'''
 
'''Returns'''
:;n:Number. Errorcode.
+
:;n:Number. [[#Errorcodes|Errorcode]].
  
  
 
The passed object can hold a couple of properties:
 
The passed object can hold a couple of properties:
:;ID:String. Required. Name of the calling worldScript. Snoopers stores a checksum (CRC) to scatter the messages on every start and inbetween.
+
:;ID:String. Required. Name of the calling worldScript. Snoopers stores a checksum (CRC) to scatter the messages on every start and inbetween if <tt>.Direct</tt> is not used.
 
 
 
:;Message:String/Key. Required. Message can be a string or keynames (descriptions.plist or missiontext.plist), mixtures allowed, max 700 chars, min 10 chars.
 
:;Message:String/Key. Required. Message can be a string or keynames (descriptions.plist or missiontext.plist), mixtures allowed, max 700 chars, min 10 chars.
:;Agency:Number. Defines 1-GNN, 2-Rooters, 3-Snoopers. If used Snoopers disables custom pics and models.
+
:;Agency:Number. Defines 1-GNN, 2-Rooters, 3-Snoopers. If used Snoopers disables custom pics and models and uses internal ones.
:;Priority:Number. 1 highest (and bypasses CRC check and storing), used to sort the inserted news on next docking. Default 3.
+
:;Priority:Number. 1 highest (and bypasses CRC check), used to sort the inserted news on next docking. Default 3.
:;Pic:String. Overlay image, use tranparent areas if model should be used. Fileextension is required. If Agency and Pic not declared default setting choosen.
+
:;Pic:String. Overlay image, use tranparent areas if model should be used. Fileextension is required. If <tt>.Agency</tt> and <tt>.Pic</tt> not declared default setting choosen.
 
:;Music:String. Music for Newsflash. Fileextension is required. If not declared, default setting choosen.
 
:;Music:String. Music for Newsflash. Fileextension is required. If not declared, default setting choosen.
:;Model:String. Role for Model, if used Pos must be passed to, else disabled. shipdata.plist must use the same name and roles must contain snoopers_model(0).
+
:;Model:String. Role for Model. Starting with v2.3 it can be any NPC role.
:;Pos:Array. 3 valid numbers, ignored if Model not declared.
+
:;Pos:Array. 3 valid numbers. Adjusted on screen aspect ratios. If not defined Snoopers bases it on <tt>entity.position.z</tt>.
:;Ori:Number. Defines the orientation of Model. 1-[1,0,0,0], 2-[1,0,0,1], 4-[0,0,1,0], 8-[1,1,0,0]. Default 8. (New in 2.1.1)
+
:;Ori:Number/Array. Orientation of Model. If number: 1=<tt>[1,0,0,0]</tt>, 2=<tt>[1,0,0,1]</tt>, 4=<tt>[0,0,1,0]</tt>, 8=<tt>[1,1,0,0]</tt>. Default 8. Otherwise Array with 4 valid numbers.
 +
:;Recall:Boolean. Resend callback in case other OXPs have overridden Snoopers screen and Replay gets activated.
 +
:;Direct:Boolean. Display message directly without storing, CRC or other buffer checks. Requires the player to be docked.
 +
:;Anim:Array. Uses [[Cabal_Common_Library_Doc_Briefing#startBriefing()|Cabal_Common_Briefing]] capture option. The array must contain only the <tt>.briefing</tt> part. Ignored if <tt>.Direct</tt> is not used.
  
  
'''Errorcodes:'''<br>
+
A simple example
Snoopers will check all incoming requests and returns a value to the calling function (always) and logs errors (if necessary or logging enabled)... Usually (with this.logging = false) it will only log real errors, by enabling this switch all returned values are logged.
+
  worldScripts.snoopers.insertNews({ ID: this.name , Message: "Hello world!" });
:;negative:Snoopers buffers are full, OXP already placed a newsflash or CRC is still stored.
 
:;zero:Success.
 
:;positive:Error occured, details logged to Latest.log.
 
  
  
A simple example
+
==== Callback ====
{{CodeEx|codeex=worldScripts.snoopers.insertNews({ ID: this.name , Message: "Hello world!" });}}
+
After displaying this message Snoopers tries to callback and passes the first 20 chars of the message.
 +
{{CodeEx|codeex=worldScripts[obj.ID].newsDisplayed( obj.Message.substr(0,20) );}}
  
  
 
== shipdata.plist ==
 
== shipdata.plist ==
Snoopers usually doesn't do anything on other stations than the main station and stations with NPC traffic. A script_info key can change this behaviour.
+
Snoopers usually doesn't do anything on other stations than the main station and stations with NPC traffic (except with <tt>.Direct</tt> messages). A script_info key can change this behaviour.
  
 
'''Key:'''
 
'''Key:'''
:;snoopersNews:Boolean. Enables Snoopers for this station. (New in 2.1.1)
+
:;snoopersNews:Boolean. Enables Snoopers for this station.
{{CodeEx|codeex=script_info = { "snoopersNews" = true; };}}
+
{{CodeEx|codeex=script_info = { snoopersNews = true; };}}
 +
 
 +
 
 +
== Errorcodes ==
 +
Snoopers returns a errorcode to inserting scripts.
 +
{| class="wikitable"
 +
|-
 +
! Code
 +
! Meaning
 +
|-
 +
| -5
 +
| Snoopers buffer is full (max 10 news)
 +
|-
 +
| -4
 +
| No free storing slot available
 +
|-
 +
| -3
 +
| CRC buffer is full
 +
|-
 +
| -2
 +
| CRC is still active
 +
|-
 +
| -1
 +
| Caller already sent a message (1 news per worldScript)
 +
|-
 +
| 0
 +
| Success
 +
|-
 +
| 1
 +
| Required properties not found (ID and Message)
 +
|-
 +
| 2
 +
| Unknown properties passed
 +
|-
 +
| 3
 +
| To few or too much passed properties (at least 2)
 +
|-
 +
| 4
 +
| Request from invalid caller (no worldScript)
 +
|-
 +
| 5
 +
| Property 'Message' not a string (wrong type)
 +
|-
 +
| 6
 +
| Property 'Message' too short or too long (expected >10 and <700 chars)
 +
|-
 +
| 7
 +
| Property 'Message' starts with whitespace (\\f \\t \\r \\n or space). Removed in v2.4. Snoopers will trim the string.
 +
|-
 +
| 8
 +
| Property 'Message' - Sent message not expandable.
 +
|-
 +
| 9
 +
| Property 'Message' - Number of opening brackets doesn't match number of closing brackets. Removed in v2.4.
 +
|-
 +
| 10
 +
| Property 'Message' - Expanded key (descriptions.plist) too long (limit 700 chars). Removed in v2.4.
 +
|-
 +
| 11
 +
| Property 'Message' - Expanded key (missiontext.plist) too long (limit 700 chars). Removed in v2.4.
 +
|-
 +
| 12
 +
| Property 'Message' - Expanded Message too long
 +
|-
 +
| 13
 +
| Property 'Message' - Word with overlength detected (limit 79 chars)
 +
|-
 +
| 14
 +
| Property 'Message' - To many linebreaks (limit 10)
 +
|-
 +
| 15
 +
| Property 'Agency' - not valid (expected number in range 1 - 3)
 +
|-
 +
| 16
 +
| Property 'Priority' - not valid (expected number in range 1 - 3)
 +
|-
 +
| 17
 +
| Property 'Pic' - wrong type (expected string)
 +
|-
 +
| 18
 +
| Property 'Pic' - not a valid fileextension
 +
|-
 +
| 19
 +
| Property 'Music' - wrong type (expected string)
 +
|-
 +
| 20
 +
| Property 'Music' not a valid fileextension
 +
|-
 +
| 21
 +
| Property 'Model' - wrong type (expected string)
 +
|-
 +
| 22
 +
| Property 'Pos' - wrong type (expected array)
 +
|-
 +
| 23
 +
| Property 'Pos' - wrong number of arguments (expected 3 numbers)
 +
|-
 +
| 24
 +
| Property 'Pos' - contains NaN
 +
|-
 +
| 25
 +
| Property 'Ori' - wrong type (expected number or array)
 +
|-
 +
| 26
 +
| Property 'Ori' - not valid (expected 1, 2, 4 or 8)
 +
|-
 +
| 27
 +
| Snoopers was shutdown. Requirements not fullfilled
 +
|-
 +
| 28
 +
| Player not valid anymore
 +
|-
 +
| 29
 +
| Player not docked while trying to display a direct mission screen
 +
|-
 +
| 30
 +
| Attempt to override a missionscreen blocked
 +
|}
 +
 
 +
== Upgrading Snoopers to [[GNN]] ==
 +
 
 +
Here is the Snoopers section for the [[Jaguar Company]]'s  jaguar_company.js file (lines 2847 - 2923 at the end of the file)
 +
    /* NAME
 +
    *  $sendNewsToSnoopers
 +
    *
 +
    * FUNCTION
 +
    *  Send news to Snoopers (if available).
 +
    *
 +
    * INPUTS
 +
    *  message - news to show
 +
    *  agency - agency to use (optional)
 +
    */
 +
    this.$sendNewsToSnoopers = function (message, agency) {
 +
        var news = {},
 +
        result,
 +
        index;
 +
 +
        if (!worldScripts.snoopers) {
 +
            /* Snoopers not installed. */
 +
            return;
 +
        }
 +
 +
        if (!agency || typeof agency !== "number") {
 +
            /* Random agency. [1, 2 or 3] */
 +
            agency = Math.floor(Math.random() * 3.0) + 1;
 +
        }
 +
 +
        news.ID = this.name;
 +
        news.Message = message;
 +
        news.Agency = agency;
 +
        result = worldScripts.snoopers.insertNews(news);
 +
        index = result + 5;
 +
 +
        if (result < 0) {
 +
            /* Save for later. Snoopers only allows one news item at a time. */
 +
            this.$playerVar.newsForSnoopers.push(news);
 +
 +
            if (this.$logging && this.$logExtra) {
 +
                log(this.name, "$sendNewsToSnoopers::Saving news for later.\n" +
 +
                    "* ID: '" + this.name + "'\n" +
 +
                    "* Message: '" + message + "'\n" +
 +
                    "* Agency: " + agency + "\n" +
 +
                    "* result: " + result + (result >= -5 ? ") " + p_const.snoopersErrorCodes[index] : ""));
 +
            }
 +
        } else if (result > 0) {
 +
            /* Problem. */
 +
            log(this.name, "$sendNewsToSnoopers::Problem with news.\n" +
 +
                "* ID: '" + this.name + "'\n" +
 +
                "* Message: '" + message + "'\n" +
 +
                "* Agency: " + agency + "\n" +
 +
                "* result: " + result + (result <= 30 ? ") " + p_const.snoopersErrorCodes[index] : ""));
 +
        } else {
 +
            /* News inserted. */
 +
            if (this.$logging && this.$logExtra) {
 +
                log(this.name, "$sendNewsToSnoopers::News inserted.\n" +
 +
                    "* ID: '" + this.name + "'\n" +
 +
                    "* Message: '" + message + "'\n" +
 +
                    "* Agency: " + agency + "\n" +
 +
                    "* result: " + result + ") " + p_const.snoopersErrorCodes[index]);
 +
            }
 +
        }
 +
    };
 +
 +
    /* NAME
 +
    *  newsDisplayed
 +
    *
 +
    * FUNCTION
 +
    *  Called by Snoopers when the news item has been displayed.
 +
    *  Check for any more news available and send it.
 +
    */
 +
    this.newsDisplayed = function () {
 +
        var news = this.$playerVar.newsForSnoopers.shift();
 +
 +
        if (news) {
 +
            /* More news available. Send it to Snoopers. */
 +
            this.$sendNewsToSnoopers(news.Message, news.Agency);
 +
        }
 +
    };
 +
}.bind(this)());
 +
 +
Phkb upgraded is as follows:
 +
 
 +
    /* NAME
 +
    *  $sendNewsToSnoopers
 +
    *
 +
    * FUNCTION
 +
    *  Send news to Snoopers (if available).
 +
    *
 +
    * INPUTS
 +
    *  message - news to show
 +
    *  agency - agency to use (optional)
 +
    */
 +
    this.$sendNewsToSnoopers = function (message, agency) {
 +
        var news = {},
 +
        result,
 +
        index;
 +
 +
        if (!worldScripts.snoopers <font color="Red">&& !worldScripts.GNN</font>) {
 +
            /* Snoopers not installed. */
 +
            return;
 +
        }
 +
 +
        if (!agency || typeof agency !== "number") {
 +
            /* Random agency. [1, 2 or 3] */
 +
            agency = Math.floor(Math.random() * 3.0) + 1;
 +
        }
 +
 +
        news.ID = this.name;
 +
        news.Message = message;
 +
        news.Agency = agency;
 +
        <font color="Red">if (worldScripts.GNN) {
 +
        result = worldScripts.GNN.insertNews(news);
 +
        } else {</font>
 +
        result = worldScripts.snoopers.insertNews(news);
 +
        <font color="Red"> } </font>
 +
        index = result + 5;
 +
 +
        if (result < 0) {
 +
            /* Save for later. Snoopers only allows one news item at a time. */
 +
            this.$playerVar.newsForSnoopers.push(news);
 +
 +
            if (this.$logging && this.$logExtra) {
 +
                log(this.name, "$sendNewsToSnoopers::Saving news for later.\n" +
 +
                    "* ID: '" + this.name + "'\n" +
 +
                    "* Message: '" + message + "'\n" +
 +
                    "* Agency: " + agency + "\n" +
 +
                    "* result: " + result + (result >= -5 ? ") " + p_const.snoopersErrorCodes[index] : ""));
 +
            }
 +
        } else if (result > 0) {
 +
            /* Problem. */
 +
            log(this.name, "$sendNewsToSnoopers::Problem with news.\n" +
 +
                "* ID: '" + this.name + "'\n" +
 +
                "* Message: '" + message + "'\n" +
 +
                "* Agency: " + agency + "\n" +
 +
                "* result: " + result + (result <= 30 ? ") " + p_const.snoopersErrorCodes[index] : ""));
 +
        } else {
 +
            /* News inserted. */
 +
            if (this.$logging && this.$logExtra) {
 +
                log(this.name, "$sendNewsToSnoopers::News inserted.\n" +
 +
                    "* ID: '" + this.name + "'\n" +
 +
                    "* Message: '" + message + "'\n" +
 +
                    "* Agency: " + agency + "\n" +
 +
                    "* result: " + result + ") " + p_const.snoopersErrorCodes[index]);
 +
            }
 +
        }
 +
    };
 +
 +
    /* NAME
 +
    *  newsDisplayed
 +
    *
 +
    * FUNCTION
 +
    *  Called by Snoopers when the news item has been displayed.
 +
    *  Check for any more news available and send it.
 +
    */
 +
    this.newsDisplayed = function () {
 +
        var news = this.$playerVar.newsForSnoopers.shift();
 +
 +
        if (news) {
 +
            /* More news available. Send it to Snoopers. */
 +
            this.$sendNewsToSnoopers(news.Message, news.Agency);
 +
        }
 +
    };
 +
}.bind(this)());
 +
 
 +
''The text for the news flashes is in descriptions.plist: keys are "jaguar_company_help_news", "jaguar_company_help_news_quote", "jaguar_company_rescue_news", "jaguar_company_rescue_multiple_news", and "jaguar_company_rescue_news_quote".''
  
[[Category:OXPDoc]]
+
[[Category:OXP API's]]

Latest revision as of 13:45, 20 September 2023

Overview

Snoopers introduces the Galactic News Network with 4 news agencies. It can be used by other OXPs to implement own newsflashes easily and the passed news can be shown directly or by the time based mechanism in Snoopers and a callback after displaying can be used.


Missionscreens in snoopers.js are using the screenID Added in v2.5

"snoopers"


Properties

OXPC - Marked properties can be configured via OXPConfig.

logging

Boolean. Switches extended logging on/off. Default is false. OXPC

audio

Boolean. Switches audio for internal news on/off. Default is true. OXPC

extraA

Boolean. Switches full mode for internal news on/off. Default is true. OXPC

sliderA

Integer. Chance for newsflashes. Default is 0x3 (#3). OXPC

sliderB

Integer. Max days between newsflashes. Default is 0x19 (#25). OXPC

sliderC

Integer. Brightness for displayed model. Default is 0x4 (#4). This will only affect shadered models which support it. Uses the fuel property. OXPC


Functions

insertNews()

worldScripts.snoopers.insertNews( obj )
Profiler
Native 0.000081s
Extension 0.000017s
JS 0.000337s

Handles incoming messages from other OXPs worldScripts. If .Direct is not used Snoopers stores up to 10 messages and 20 CRCs and all checks are passed (e.g. only 1 news per worldScript is allowed). .Direct news are displayed immediately and won't be stored. Make sure that the object is extensible and not sealed or frozen.

Parameters

obj
Object.

Returns

n
Number. Errorcode.


The passed object can hold a couple of properties:

ID
String. Required. Name of the calling worldScript. Snoopers stores a checksum (CRC) to scatter the messages on every start and inbetween if .Direct is not used.
Message
String/Key. Required. Message can be a string or keynames (descriptions.plist or missiontext.plist), mixtures allowed, max 700 chars, min 10 chars.
Agency
Number. Defines 1-GNN, 2-Rooters, 3-Snoopers. If used Snoopers disables custom pics and models and uses internal ones.
Priority
Number. 1 highest (and bypasses CRC check), used to sort the inserted news on next docking. Default 3.
Pic
String. Overlay image, use tranparent areas if model should be used. Fileextension is required. If .Agency and .Pic not declared default setting choosen.
Music
String. Music for Newsflash. Fileextension is required. If not declared, default setting choosen.
Model
String. Role for Model. Starting with v2.3 it can be any NPC role.
Pos
Array. 3 valid numbers. Adjusted on screen aspect ratios. If not defined Snoopers bases it on entity.position.z.
Ori
Number/Array. Orientation of Model. If number: 1=[1,0,0,0], 2=[1,0,0,1], 4=[0,0,1,0], 8=[1,1,0,0]. Default 8. Otherwise Array with 4 valid numbers.
Recall
Boolean. Resend callback in case other OXPs have overridden Snoopers screen and Replay gets activated.
Direct
Boolean. Display message directly without storing, CRC or other buffer checks. Requires the player to be docked.
Anim
Array. Uses Cabal_Common_Briefing capture option. The array must contain only the .briefing part. Ignored if .Direct is not used.


A simple example

 worldScripts.snoopers.insertNews({ ID: this.name , Message: "Hello world!" });


Callback

After displaying this message Snoopers tries to callback and passes the first 20 chars of the message.

worldScripts[obj.ID].newsDisplayed( obj.Message.substr(0,20) );


shipdata.plist

Snoopers usually doesn't do anything on other stations than the main station and stations with NPC traffic (except with .Direct messages). A script_info key can change this behaviour.

Key:

snoopersNews
Boolean. Enables Snoopers for this station.
script_info = { snoopersNews = true; };


Errorcodes

Snoopers returns a errorcode to inserting scripts.

Code Meaning
-5 Snoopers buffer is full (max 10 news)
-4 No free storing slot available
-3 CRC buffer is full
-2 CRC is still active
-1 Caller already sent a message (1 news per worldScript)
0 Success
1 Required properties not found (ID and Message)
2 Unknown properties passed
3 To few or too much passed properties (at least 2)
4 Request from invalid caller (no worldScript)
5 Property 'Message' not a string (wrong type)
6 Property 'Message' too short or too long (expected >10 and <700 chars)
7 Property 'Message' starts with whitespace (\\f \\t \\r \\n or space). Removed in v2.4. Snoopers will trim the string.
8 Property 'Message' - Sent message not expandable.
9 Property 'Message' - Number of opening brackets doesn't match number of closing brackets. Removed in v2.4.
10 Property 'Message' - Expanded key (descriptions.plist) too long (limit 700 chars). Removed in v2.4.
11 Property 'Message' - Expanded key (missiontext.plist) too long (limit 700 chars). Removed in v2.4.
12 Property 'Message' - Expanded Message too long
13 Property 'Message' - Word with overlength detected (limit 79 chars)
14 Property 'Message' - To many linebreaks (limit 10)
15 Property 'Agency' - not valid (expected number in range 1 - 3)
16 Property 'Priority' - not valid (expected number in range 1 - 3)
17 Property 'Pic' - wrong type (expected string)
18 Property 'Pic' - not a valid fileextension
19 Property 'Music' - wrong type (expected string)
20 Property 'Music' not a valid fileextension
21 Property 'Model' - wrong type (expected string)
22 Property 'Pos' - wrong type (expected array)
23 Property 'Pos' - wrong number of arguments (expected 3 numbers)
24 Property 'Pos' - contains NaN
25 Property 'Ori' - wrong type (expected number or array)
26 Property 'Ori' - not valid (expected 1, 2, 4 or 8)
27 Snoopers was shutdown. Requirements not fullfilled
28 Player not valid anymore
29 Player not docked while trying to display a direct mission screen
30 Attempt to override a missionscreen blocked

Upgrading Snoopers to GNN

Here is the Snoopers section for the Jaguar Company's jaguar_company.js file (lines 2847 - 2923 at the end of the file)

   /* NAME
    *   $sendNewsToSnoopers
    *
    * FUNCTION
    *   Send news to Snoopers (if available).
    *
    * INPUTS
    *   message - news to show
    *   agency - agency to use (optional)
    */
   this.$sendNewsToSnoopers = function (message, agency) {
       var news = {},
       result,
       index;

       if (!worldScripts.snoopers) {
           /* Snoopers not installed. */
           return;
       }

       if (!agency || typeof agency !== "number") {
           /* Random agency. [1, 2 or 3] */
           agency = Math.floor(Math.random() * 3.0) + 1;
       }

       news.ID = this.name;
       news.Message = message;
       news.Agency = agency;
       result = worldScripts.snoopers.insertNews(news);
       index = result + 5;

       if (result < 0) {
           /* Save for later. Snoopers only allows one news item at a time. */
           this.$playerVar.newsForSnoopers.push(news);

           if (this.$logging && this.$logExtra) {
               log(this.name, "$sendNewsToSnoopers::Saving news for later.\n" +
                   "* ID: '" + this.name + "'\n" +
                   "* Message: '" + message + "'\n" +
                   "* Agency: " + agency + "\n" +
                   "* result: " + result + (result >= -5 ? ") " + p_const.snoopersErrorCodes[index] : ""));
           }
       } else if (result > 0) {
           /* Problem. */
           log(this.name, "$sendNewsToSnoopers::Problem with news.\n" +
               "* ID: '" + this.name + "'\n" +
               "* Message: '" + message + "'\n" +
               "* Agency: " + agency + "\n" +
               "* result: " + result + (result <= 30 ? ") " + p_const.snoopersErrorCodes[index] : ""));
       } else {
           /* News inserted. */
           if (this.$logging && this.$logExtra) {
               log(this.name, "$sendNewsToSnoopers::News inserted.\n" +
                   "* ID: '" + this.name + "'\n" +
                   "* Message: '" + message + "'\n" +
                   "* Agency: " + agency + "\n" +
                   "* result: " + result + ") " + p_const.snoopersErrorCodes[index]);
           }
       }
   };

   /* NAME
    *   newsDisplayed
    *
    * FUNCTION
    *   Called by Snoopers when the news item has been displayed.
    *   Check for any more news available and send it.
    */
   this.newsDisplayed = function () {
       var news = this.$playerVar.newsForSnoopers.shift();

       if (news) {
           /* More news available. Send it to Snoopers. */
           this.$sendNewsToSnoopers(news.Message, news.Agency);
       }
   };
}.bind(this)());

Phkb upgraded is as follows:

   /* NAME
    *   $sendNewsToSnoopers
    *
    * FUNCTION
    *   Send news to Snoopers (if available).
    *
    * INPUTS
    *   message - news to show
    *   agency - agency to use (optional)
    */
   this.$sendNewsToSnoopers = function (message, agency) {
       var news = {},
       result,
       index;

       if (!worldScripts.snoopers && !worldScripts.GNN) {
           /* Snoopers not installed. */
           return;
       }

       if (!agency || typeof agency !== "number") {
           /* Random agency. [1, 2 or 3] */
           agency = Math.floor(Math.random() * 3.0) + 1;
       }

       news.ID = this.name;
       news.Message = message;
       news.Agency = agency;
       if (worldScripts.GNN) {
       	result = worldScripts.GNN.insertNews(news);
       } else {
       	result = worldScripts.snoopers.insertNews(news);
        } 
       index = result + 5;

       if (result < 0) {
           /* Save for later. Snoopers only allows one news item at a time. */
           this.$playerVar.newsForSnoopers.push(news);

           if (this.$logging && this.$logExtra) {
               log(this.name, "$sendNewsToSnoopers::Saving news for later.\n" +
                   "* ID: '" + this.name + "'\n" +
                   "* Message: '" + message + "'\n" +
                   "* Agency: " + agency + "\n" +
                   "* result: " + result + (result >= -5 ? ") " + p_const.snoopersErrorCodes[index] : ""));
           }
       } else if (result > 0) {
           /* Problem. */
           log(this.name, "$sendNewsToSnoopers::Problem with news.\n" +
               "* ID: '" + this.name + "'\n" +
               "* Message: '" + message + "'\n" +
               "* Agency: " + agency + "\n" +
               "* result: " + result + (result <= 30 ? ") " + p_const.snoopersErrorCodes[index] : ""));
       } else {
           /* News inserted. */
           if (this.$logging && this.$logExtra) {
               log(this.name, "$sendNewsToSnoopers::News inserted.\n" +
                   "* ID: '" + this.name + "'\n" +
                   "* Message: '" + message + "'\n" +
                   "* Agency: " + agency + "\n" +
                   "* result: " + result + ") " + p_const.snoopersErrorCodes[index]);
           }
       }
   };

   /* NAME
    *   newsDisplayed
    *
    * FUNCTION
    *   Called by Snoopers when the news item has been displayed.
    *   Check for any more news available and send it.
    */
   this.newsDisplayed = function () {
       var news = this.$playerVar.newsForSnoopers.shift();

       if (news) {
           /* More news available. Send it to Snoopers. */
           this.$sendNewsToSnoopers(news.Message, news.Agency);
       }
   };
}.bind(this)());

The text for the news flashes is in descriptions.plist: keys are "jaguar_company_help_news", "jaguar_company_help_news_quote", "jaguar_company_rescue_news", "jaguar_company_rescue_multiple_news", and "jaguar_company_rescue_news_quote".