Change font size
It is currently Fri May 24, 2019 2:24 pm

Forum rules


Post a new topicPost a reply Page 1 of 1   [ 1 post ]
Author Message
 Post subject: LSL, PHP, Ajax Meeting chat logger
PostPosted: Wed Sep 08, 2010 1:26 pm 
OSG Elite
User avatar

Joined: Thu Dec 11, 2008 7:51 am
Posts: 391
Location: England UK
The following scripts will create an in-world meeting chat logger that logs the meeting to a PHP webserver. People can view the meeting chat in realtime from a web page. You can also download the entire meeting log in text format with html so it could be pasted right into a wiki or CMS that supports html.

To use this you will need a webserver running PHP. There are two scripts that need to reside on the webserver and an LSL script for in-world. The chat is picked up by the LSL in-world script and posted to the PHP script, that writes the log to a text file. The html file runs an Ajax script to read the text file and print out via a browser the realtime chat without the need to refresh the page. The PHP and Ajax are highly modified scripts I found on the internet, the original credits are in the scripts.

- Spam keywords - this will drop an entire line if certain keywords are detected
- Entire lines of spam - this will drop an entire line if the enitre line is exactly the same
- Security key - the LSL and PHP have a key that has to be the same, if the key is not the same, no chat is logged. This is to stop people maliciously posting directly to the PHP script
- You can start/stop and clear the log from in-world
- The reader supports autoscroll and you can download the full meeting text (with html) from the reader page

- Create a folder on your webserver, something like 'meetinglog'
- Set permissions on that folder to allow your web server process/user to create, write and modify files in that folder only
- Drop the files meetinglogger.php and meetinglog.html into your folder
- Drop the LSL script into a prim in-world.
- Open both the LSL and PHP scripts and set the key to something else, or just leave it at default 1234 for testing
- Set both of the URLs in the LSL script to point at both the scripts on the webserver, such as: ... logger.php and
- Open the meetinglog.html in your web browser. At first it will say the text file can not be found, this is normal.
- Touch the prim with the LSL script and turn on the logging
- Say something and this should create the text file and start logging. You should see the output on the browser.

I have this setup on my webserver, so for a demo drop the LSL script into a prim (unchanged) and goto ... nglog.html to see the demo.

Enjoy! :)

LSL Script (drop into a prim in-world)
//LSL Meeting chat logger by Adelle Fitzgerald. In-world script posts chat to a PHP webserver. The PHP writes to a text document and an Ajax reader will display the chat log in realtime on a web browser.

//Licenced under Creative Commons Attribution-Share Alike 3.0 Unported -

//You are free:

//    * to Share — to copy, distribute and transmit the work
//    * to Remix — to adapt the work

//Under the following conditions:

//    * Attribution — You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).

//    * Share Alike — If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license.

//With the understanding that:

//    * Waiver — Any of the above conditions can be waived if you get permission from the copyright holder.
//    * Public Domain — Where the work or any of its elements is in the public domain under applicable law, that status is in no way affected by the license.
//    * Other Rights — In no way are any of the following rights affected by the license:
//          o Your fair dealing or fair use rights, or other applicable copyright exceptions and limitations;
//          o The author's moral rights;
//          o Rights other persons may have either in the work itself or in how the work is used, such as publicity or privacy rights.
//    * Notice — For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to this web page.


//The Commons Deed is not a license. It is simply a handy reference for understanding the Legal Code (the full license) — it is a human-readable expression of some of its key terms. Think of it as the user-friendly interface to the Legal Code beneath. This Deed itself has no legal value, and its contents do not appear in the actual license.

//Creative Commons is not a law firm and does not provide legal services. Distributing of, displaying of, or linking to this Commons Deed does not create an attorney-client relationship.

//For instructions please visit
//Please note this script will not work on it's own and requires a PHP webserver + PHP script to function.

string loggerurl = ""; //This is the URL to the php script on your webserver
string logurl = ""; //This is the URL to the chat log page for people to view online
integer gChannel = 0; //The channel for it to listen to chat on. Normally we will want this on channel 0 for its intended purpose
string fKey = "5678"; //This key needs to correspond with the key in chatlogger.php. This should stop (most) people from maliciously posting to the logger (providing they don't know it!).

key req_id2;
string time;
list lsTime;
integer isLogging = FALSE;
integer handle;
integer menuHandle;
integer menuChannel;
key gUser;
string loggingStatus;

postMessage(string msg)
    req_id2 = llHTTPRequest( loggerurl, [HTTP_METHOD,"POST",HTTP_MIMETYPE,"application/x-www-form-urlencoded"], msg);

    llListenControl(menuHandle, TRUE);
    llDialog(gUser, "\n\nPlease Choose:", ["On", "Off", "Cancel", "Clear Log"], menuChannel);

    llDialog(gUser, "\n\nAre you sure? Clearing the log will wipe it from the website", ["Yes", "No"], menuChannel);

    llListenControl(menuHandle, FALSE);
    llSay(0,"Meeting chat logging has been enabled. You can view the log at: " + logurl);
    isLogging = TRUE;
    llListenControl(handle, isLogging);
    llSetColor(<1,0,0>, ALL_SIDES);
    llSetText("Meeting chat Logging On\n" + logurl,<1,1,1>,1);
    llSetObjectDesc("Logging On");

    llListenControl(menuHandle, FALSE);
    isLogging = FALSE;
    llListenControl(handle, isLogging);
    llSetColor(<0,1,0>, ALL_SIDES);
    llSetText("Meeting chat Logging Off",<1,1,1>,1);
    llSay(0,"Meeting chat logging has been disabled. You can view the full log at: " + logurl);
    llSetObjectDesc("Logging Off");

        menuChannel = (integer)llFrand(2147423647) + 10000;
        handle = llListen(gChannel, "", "", "");
        menuHandle = llListen(menuChannel, "", "", "");
        llListenControl(handle, FALSE);
        llListenControl(menuHandle, FALSE);
        llSetText("Meeting chat Logging Off",<1,1,1>,1);
        llSetColor(<0,1,0>, ALL_SIDES);
        loggingStatus = llGetObjectDesc();
        if (loggingStatus == "Logging On")
    touch_start(integer num)
        gUser = llDetectedKey(0);
        if (gUser == llGetOwner())
    listen(integer channel,string name,key id,string message)
        if (channel == gChannel)
            //Get the current UTC time and prune it to just hh:mm
            time = llGetTimestamp();
            lsTime = [];
            lsTime = lsTime + llParseString2List(time,["T","."],[]);
            time = llList2String(lsTime,1);
            time = llDeleteSubString(time, 5, 7);
            //If emoting (/me) strip out the /me and change the message posted to reflect that of the viewer
            if (llGetSubString(message, 0, 3) == "/me ")
                message = llDeleteSubString(message, 0, 3);
                postMessage("fkey=" + fKey + "&ftime=[" + time + " UTC] " + "&fname=" + name + "&fmessage=<i>" + message + "</i>");
                //Otherwise post the message in as a normal chat
                postMessage("fkey=" + fKey + "&ftime=[" + time + " UTC] " + "&fname=" + name + ":" + "&fmessage=" + message);
        else if (channel == menuChannel)
            if (message == "On") //Turn on logging
                time = llGetTimestamp();
                lsTime = [];
                lsTime = lsTime + llParseString2List(time,["T","."],[]);
                time = llList2String(lsTime,1);
                time = llDeleteSubString(time, 5, 7);
                postMessage("fkey=" + fKey + "&ftime=[" + time + " UTC] " + "&fmessage=<b>*** Logging started. ***</b>");
            else if (message == "Off") //Turn off logging
                time = llGetTimestamp();
                lsTime = [];
                lsTime = lsTime + llParseString2List(time,["T","."],[]);
                time = llList2String(lsTime,1);
                time = llDeleteSubString(time, 5, 7);
                postMessage("fkey=" + fKey + "&ftime=[" + time + " UTC] " + "&fmessage=<b>*** Logging stopped. ***</b>");
            else if (message == "Yes") //Clear the log
                llListenControl(menuHandle, FALSE);
                postMessage("fkey=" + fKey + "&fcmd=clear");
            else if (message == "Clear Log") //Do the 'Are you sure?' thing
            else if (message == "Cancel") //Close menu listen handler
                llListenControl(menuHandle, FALSE);
            else if (message == "No") //Close menu listen handler
                llListenControl(menuHandle, FALSE);
        //Close menu listen handler
        llListenControl(menuHandle, FALSE);

meetinglogger.php (Place on your webserver)
   /* original author: chris at
      licence: GPLv2
      highly modified by Adelle Fitzgerald for use as a vw meeting logger
/* Function to strip leading slashes from quotes */
function smartstripslashes($str) {
  $cd1 = substr_count($str, "\"");
  $cd2 = substr_count($str, "\\\"");
  $cs1 = substr_count($str, "'");
  $cs2 = substr_count($str, "\\'");
  $tmp = strtr($str, array("\\\"" => "", "\\'" => ""));
  $cb1 = substr_count($tmp, "\\");
  $cb2 = substr_count($tmp, "\\\\");
  if ($cd1 == $cd2 && $cs1 == $cs2 && $cb1 == 2 * $cb2) {
    return strtr($str, array("\\\"" => "\"", "\\'" => "'", "\\\\" => "\\"));
  return $str;

   $fn = "chat.txt";
   /* spam keywords  - if keyword is detected it will drop entire line*/
   $spam[] = "nigger";
   $spam[] = "wanker";

   /* spam, if message IS exactly that string - will drop entire line*/   
   $espam[] = "ajax";
   $msg = $_POST['fmessage'];
   $n = $_POST['fname'];
   $tme = $_POST['ftime'];
   $key = $_POST['fkey'];
   $cmd = $_POST['fcmd'];
   if ($key != "5678") { die(); } /* Set this to the same key as the in-world LSL script */
   if ($cmd == "clear")  {
   $handle = fopen ($fn, 'w'); fwrite ($handle, ""); fclose($handle);
   if ($msg != "")  {
      /* Check for spam keywords */
      $mystring = strtoupper($msg);
      foreach ($spam as $a) {   
          if (strpos($mystring, strtoupper($a)) === false) {
          } else { die(); }
      /* Check for spam message */
      foreach ($espam as $a) {
         if (strtoupper($msg) == strtoupper($a)) { die(); }      
      /* Write the message to the text file */
      $out = $tme . "<b><i>" . $n . "</i></b> " . $msg . "<br>\n";
      $out = smartstripslashes($out);
      $handle = fopen ($fn, 'a'); fwrite ($handle, $out); fclose($handle);            

meetinglog.html (Place on your webserver)
   <title>LSL/PHP/Ajax Meeting chat logger</title>
   <style type="text/css">
   body          { padding-left:40px; background:#57767F; font-family:arial;}
   #content       { width:800px; text-align:left; margin-left:60px; }
   #chatwindow       { border:1px solid #aaaaaa; padding:4px; background:#232D2F; color:white; width:800px; height:500px; overflow: auto; font-family:Arial, Helvetica, sans-serif; font-size: 12px;}
   .text {font-family: Arial, Helvetica, sans-serif; font-weight: bold; font-size: 14px; color: #FFFFFF;}
   <div id="content">
         <p id="chatwindow"> </p>
            <p><span class="text">Autoscroll?</span>
              <input name="autoscroll" type="radio" value="true" onClick="submit_as(value)">
                <span class="text">Yes</span>
              <input name="autoscroll" type="radio" value="false" checked onClick="submit_as(value)">
                <span class="text">No</span>
              <input id="chatmsg" type="hidden" onKeyUp="keyup(event.keyCode);">
            <p>                      <a href="chat.txt" target="_self" class="text">Click for log in txt format</a>

<script type="text/javascript">
* Most Simple Ajax Chat Script (      *
* Version: 3.1                     *
*                         *
* Author: Chris (chris[at]         *
* Contributors: Derek, BlueScreenJunky (
*                        *
* Licence: GPLv2                  *
* Modified by Adelle Fitsgerald            *

/* Settings you might want to define */
   var waittime=800;   
   var autoscroll=false;   

/* Internal Variables & Stuff */
   document.getElementById("chatwindow").innerHTML = "loading...";

   var xmlhttp = false;
   var xmlhttp2 = false;

/* Request for Reading the Chat Content */
function ajax_read(url) {
      xmlhttp=new XMLHttpRequest();
   } else if(window.ActiveXObject){
         xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");
      } catch(e) {
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
         } catch(e){

   if(!xmlhttp) {
      alert('Giving up :( Cannot create an XMLHTTP instance');
      return false;

   xmlhttp.onreadystatechange = function() {
   if (xmlhttp.readyState==4) {
      document.getElementById("chatwindow").innerHTML = xmlhttp.responseText;

      zeit = new Date();
      ms = (zeit.getHours() * 24 * 60 * 1000) + (zeit.getMinutes() * 60 * 1000) + (zeit.getSeconds() * 1000) + zeit.getMilliseconds();
      intUpdate = setTimeout("ajax_read('chat.txt?x=" + ms + "')", waittime)

   /* Auto scroll */
   if(autoscroll == "true") {
   var objDiv = document.getElementById("chatwindow");
   objDiv.scrollTop = objDiv.scrollHeight;
   else if(autoscroll == "false") {
   var objDiv = document.getElementById("chatwindow");
   objDiv.scrollTop = objDiv.scrollTop;


function submit_as(value){
   autoscroll = value;

/* Start the Requests! ;) */
var intUpdate = setTimeout("ajax_read('chat.txt')", waittime);


"Nothing lasts forever; It's scientific"
~David Byrne (Talking Heads)

Display posts from previous:  Sort by  
Post a new topicPost a reply Page 1 of 1   [ 1 post ]

Who is online

Users browsing this forum: No registered users and 1 guest

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
610nm Style by Daniel St. Jules of