Skip to content

Instantly share code, notes, and snippets.

@ZeroPivot
Created October 12, 2018 16:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ZeroPivot/a34c6a504ecd2d0b5829cfd812248317 to your computer and use it in GitHub Desktop.
Save ZeroPivot/a34c6a504ecd2d0b5829cfd812248317 to your computer and use it in GitHub Desktop.
//By: grrendel resident - kejento@gmail.com - start: 8/14/2014 - "fin": ??/??/????
//Log: * 8/16/2014 - Changed default PARTITION_BUFFER_BY to 4; certain functions required a change as well and ends with 2().
//Modified functions:
// * send_buffer2();
// * get_relative_buffer_location2();
// * add_to_buffer2();
//HAVE: A quick and dirty way to send a 'buffer' of data from "SL_server() -> router() -> home_computer()". 8/15/2014 - 5:36AM
//WANT: AN ALGORITHM which does all the partitioning work on its own without anything hardcoded in--SO, have an n-partition, it sends it partiioned up n times to your home server. 8/16/2014 - 5:37AM
//TODO: * remove_from_buffer(integer location) -- removes a triplet value from BUFFER -- added: 8/15/2014 - 10:13AM
// * instanteneuous rate_of_change (calculus/continuous maths)/"average" rate of change... (Implement a Simplified Turing Machine.] => [STM]
// * BUFFER_MUTEX for use timer() and listen(). if timer() is processing the buffer,
// * BUFFER_MUTEX=TRUE and any messages while BUFFER_MUTEX==TRUE will be rerouted to the BACK_BUFFER. When processing, process the BUFFER first, then the BACK_BUFFER due to the time
// * NOTE: With all this being said, I just realized that I forgot to include a 4th string for BUFFER, the timestamp, which will be used to rates of change processing on the server.
// *This may not be much of a problem fixing though, since everything seems to be in the correct place.
//TESTED: creating a buffer with many specifications; the data structure to be sent to the server after processing here. 4:42PM - 8/15/2014
//UNTESTED: buffer string replacement for sending to server. 4:42PM - 8/15/2014
//UNIMPLEMENTED: buffer_mutex(integer true || false), BACK_BUFFER for when BUFFER_MUTEX==TRUE.
// timer() used to process data after some interval over time t. With other data as well, mostly rates of change,
// create an algorithm which maximizes the BUFFER/BACK_BUFFER processing alongside the limits of some time t -- 4:42PM - 8/15/2014
//WORKING ON:
// * HIGH PRIORITY 'to-do': *create an algorithm which will do all this in terms of 'n-buffer/n-partition', without the need to hardcode variables and data structures into this script. -- 8/16/2014 --
// * LATER_MAYBE: a generalized algorithm which sends data to home computer after a certain amount of time has passed, or if the buffer is full--YOU HAVE ALREADY TRIED TO EXPLAIN THIS ALGORITHM TO YOUR SELF. call this algorithm auto_send() -> calls lsl timer functions, etc
//Algorithms:
// auto_send(integer start_time) -> uses timer to automatically send data to server, etc
// n_partitioned_buffer(integer partition_by)...
// *for n_partitioned_buffer() algorithm... NEED a generalized data structure which works with string concatenation, and lsl parses this string and places it into an appropriately sized list, etc.
string SERVER_URL = "http://173.16.179.31:8080";
string QUESTION_MARK = "%0Q"; //zero
string LEFT_CURLY = "%LC";
string RIGHT_CURLY = "%RC";
string DOUBLE_QUOTE = "%DC";
string SINGLE_QUOTE = "%SQ";
string COMMA="%CO";
string ESC_DQUOTE="\"";
list escape = [QUESTION_MARK, LEFT_CURLY, RIGHT_CURLY, DOUBLE_QUOTE, SINGLE_QUOTE, COMMA, ESC_DQUOTE];
float SCAN_RANGE = 96.0;
float SCAN_INTERVAL = 5.0;
integer FIRST_NAME=0;
integer LAST_NAME=1;
integer COMMENT=2;
integer AGENT_KEY=3;
integer DEBUG=TRUE;
float TIMER_SWEEP_INTERVAL=5.0; //seconds
//for boolean
//integer TRUE=1;
//integer FALSE=0;
list BUFFER=[];//There is a limit to the number of httprequests per n length of time, gotta add everything into a queue and then send to your server accordingly
list BACK_BUFFER=[]; //while BUFFER is full, add to BACK_BUFFER.
integer BUFFER_MUTEX=FALSE;
integer MAX_RELATIVE_BUFFER_SIZE=60; //changable variable
integer PARTITION_BUFFER_BY=4; // ["fname","lname","sl_id", "fname_1", "lname_1", "sl_id_1", ...
// ----------loc_0--------- -----------loc_1---------------- ... ----loc_n----
integer BUFFER_LOCATION=0; //initialize the buffer location to 0
integer MAX_BUFFER_LENGTH;
//Buffer Mutexi -- getters & setters.
set_buffer_mutex(integer true_or_false)
{
BUFFER_MUTEX=true_or_false;
}
integer get_buffer_mutex()
{
return BUFFER_MUTEX;
}
//list/string manipulation
string str_replace(string str, string search, string replace){
return llDumpList2String(llParseStringKeepNulls((str="")+str, [search], []), replace);
}
string rem_quest(string text){
return str_replace(text, "?", QUESTION_MARK);
}
//--------------------------
//void functions (debug() & reset_buffer(); tests()) / functions which are NOT generally called in production
debug(string say_to_self)
{
if (DEBUG == TRUE)
{
llOwnerSay(say_to_self);
}
}
test_buffer_maxima()
{
integer size_left=MAX_BUFFER_LENGTH-llGetListLength(BUFFER);
llOwnerSay((string)get_buffer_remaining_size());
while(!is_buffer_full())
{
add_to_buffer("value1", "value2", "value3");
llOwnerSay((string)get_buffer_remaining_size());
}
}
reset_buffer()
{
BUFFER=[];
}
traverse_buffer_pretty_print()
{
integer start;
while(MAX_RELATIVE_BUFFER_SIZE)
{debug("traverse_buffer_pretty_print(): incomplete");}
}
list remove_sublist(list data, integer start, integer finish) //it's not that bad, is it?
{
return []; //for now
}
integer get_buffer_remaining_size() //used for while/for loop logic
{
return (MAX_BUFFER_LENGTH - llGetListLength(BUFFER));
}
integer remove_from_buffer(integer location) //TO implement later... includes recreating the list in question without that value.
{
debug("remove_from_buffer(integer location) is a wip.");
return 0; //for now
}
string get_from_buffer(integer location) //for function logic--not used otherwise
{
return llList2String(BUFFER, location);
//llGetListLength(list)
}
//------------------------------------
//Public related functions that deal with BUFFER list manipulation
integer is_buffer_empty()//?
{
return llGetListLength(BUFFER) == 0;
}
integer is_buffer_full()//?
{
if ((llGetListLength(BUFFER) < MAX_BUFFER_LENGTH) && ((llGetListLength(BUFFER)+PARTITION_BUFFER_BY) <= MAX_BUFFER_LENGTH ) )
{
debug("is_buffer_full() returns FALSE");
return FALSE;
}
else
{
debug("is_buffer_full() returns TRUE");
return TRUE;
}
}
integer get_buffer_max_relative_size() {
return MAX_RELATIVE_BUFFER_SIZE;
}
integer get_buffer_current_relative_size()
{
return llGetListLength(BUFFER)/PARTITION_BUFFER_BY;
}
integer add_to_buffer2(string first_name, string last_name, string comment, string agent_id) //for partitions of 4. 4:50am, 8/16/2014
{
//You have to parse the comment and remove all annoying characters, possibly using llEscapeURL()
//llEscapeURL(url)
integer added=FALSE;
if (!is_buffer_full()){
string escaped_comment=comment;
//escaped_comment = rem_quest(escaped_comment); //do we need this? 8/15/2014 6:51AM
escaped_comment = str_replace(escaped_comment, "{", LEFT_CURLY); //since we'll most likely convert all this junk to a ruby hash
escaped_comment = str_replace(escaped_comment, "}", RIGHT_CURLY);
escaped_comment = str_replace(escaped_comment, "\"", DOUBLE_QUOTE);
escaped_comment = str_replace(escaped_comment, "'", SINGLE_QUOTE);
BUFFER=BUFFER+[first_name, last_name, escaped_comment, (string)agent_id]; //THE DATA STRUCT
added=TRUE;
}
else { debug("BUFFER is full."); }
return added;
//BUFFER_LOC=BUFFER_LOC+3;
//0+1+2+3
//(buffer,i) starts at 0. add one, increment i. add one again, increment i. add one yet again, increment i yet again
// i=0. i=1. i=2 i=3
}
integer add_to_buffer(string first_name, string last_name, string comment) //for partitions of 3.
{
//You have to parse the comment and remove all annoying characters, possibly using llEscapeURL()
//llEscapeURL(url)
integer added=FALSE;
if (!is_buffer_full()){
string escaped_comment=comment;
//escaped_comment = rem_quest(escaped_comment); //do we need this? 8/15/2014 6:51AM
escaped_comment = str_replace(escaped_comment, "{", LEFT_CURLY); //since we'll most likely convert all this junk to a ruby hash
escaped_comment = str_replace(escaped_comment, "}", RIGHT_CURLY);
escaped_comment = str_replace(escaped_comment, "\"", DOUBLE_QUOTE);
escaped_comment = str_replace(escaped_comment, "'", SINGLE_QUOTE);
BUFFER=BUFFER+[first_name, last_name, escaped_comment]; //THE DATA STRUCT
added=TRUE;
}
else { debug("BUFFER is full."); }
return added;
//BUFFER_LOC=BUFFER_LOC+3;
//0+1+2+3
//(buffer,i) starts at 0. add one, increment i. add one again, increment i. add one yet again, increment i yet again
// i=0. i=1. i=2 i=3
}
list get_relative_buffer_loc(integer loc) //This is what you'll be using the most
{
integer location_offset=loc*PARTITION_BUFFER_BY;
if (location_offset < MAX_BUFFER_LENGTH)
{
string first_name = get_from_buffer(location_offset);
string last_name = get_from_buffer(location_offset+1);
string comment = get_from_buffer(location_offset+2);
debug("[start] loc: " + (string)loc + "; " + "location_offset: " + (string)location_offset);
debug("-[first_name]: " + first_name + " location_offset: " + (string)location_offset);
debug("- [last_name]: " + last_name + " location_offset+1: " + (string)(location_offset+1));
debug("- [comment]: " + (string)comment+ " location_offset+2: " + (string)(location_offset+2));
return [first_name, last_name, comment];
}
else
{
return []; //we return the empty list if... the offset is off
}
}
list get_relative_buffer_loc2(integer loc) //This is what you'll be using the most
{
integer location_offset=loc*PARTITION_BUFFER_BY;
if (location_offset < MAX_BUFFER_LENGTH)
{
string first_name = get_from_buffer(location_offset);
string last_name = get_from_buffer(location_offset+1);
string comment = get_from_buffer(location_offset+2);
string agent_id = get_from_buffer(location_offset+3); //added code 8/14/2014
debug("[start] loc: " + (string)loc + "; " + "location_offset: " + (string)location_offset);
debug("-[first_name]: " + first_name + " location_offset: " + (string)location_offset);
debug("- [last_name]: " + last_name + " location_offset+1: " + (string)(location_offset+1));
debug("- [comment]: " + (string)comment+ " location_offset+2: " + (string)(location_offset+2));
debug("- [agent_id]: " + (string)agent_id+ " location_offset+3: " + (string)(location_offset+3));
return [first_name, last_name, comment, agent_id]; //8/14/2014
}
else
{
return []; //we return the empty list if... the offset is off
}
}
send_buffer2()
{
integer counter=0;
list temp=[];
string first_name="";
string last_name="";
string comment="";
key agent_id=NULL_KEY;
string flat_buffer="["; //start the buffer2arrayhash data struct
string buffer_subset;
key reqid;
while (counter < get_buffer_current_relative_size())
{
temp=get_relative_buffer_loc2(counter);
first_name = llList2String(temp, FIRST_NAME);
last_name = llList2String(temp, LAST_NAME);
comment = llList2String(temp, COMMENT);
//what has to be added for a 4-partition: 8/16/2014
agent_id = llList2String(temp, AGENT_KEY);
buffer_subset=":first_name => "+ ESC_DQUOTE + first_name + ESC_DQUOTE + ", :last_name => " + ESC_DQUOTE + last_name + ESC_DQUOTE + ", :comment => " + ESC_DQUOTE + comment + ESC_DQUOTE + ", :sl_id => " + ESC_DQUOTE + (string)agent_id + ESC_DQUOTE;
//buffer_subset=":first_name => "+ ESC_DQUOTE + first_name + ESC_DQUOTE + ", :last_name => " + ESC_DQUOTE + last_name + ESC_DQUOTE + ", :comment => " + ESC_DQUOTE + comment + ESC_DQUOTE;
flat_buffer += "{" + buffer_subset + "}, ";
counter+=1;
}
flat_buffer+="]"; //end data struct
reqid=llHTTPRequest(SERVER_URL+"/read_body", [HTTP_METHOD, "POST"], flat_buffer); //there isn't much to change here except for /read_body, which is a test route that outputs whatever the input was.
BUFFER=[]; //reset the BUFFER;
//return reqid;
}
///
send_buffer() //what should this return, anyways? The reqid?
{
integer counter=0;
list temp=[];
string first_name="";
string last_name="";
string comment="";
key agent_id=NULL_KEY;
string flat_buffer="["; //start the buffer2arrayhash data struct
string buffer_subset;
key reqid;
while (counter < get_buffer_current_relative_size())
{
temp=get_relative_buffer_loc(counter);
first_name = llList2String(temp, FIRST_NAME);
last_name = llList2String(temp, LAST_NAME);
comment = llList2String(temp, COMMENT);
//what has to be added for a 4-partition: 8/16/2014
//agent_id = llList2String(temp, AGENT_KEY)
//buffer_subset=":first_name => "+ ESC_DQUOTE + first_name + ESC_DQUOTE + ", :last_name => " + ESC_DQUOTE + last_name + ESC_DQUOTE + ", :comment => " + ESC_DQUOTE + comment + ESC_DQUOTE + ", :sl_id => " + ESC_DQUOTE + (string)agent_id + ESC_DQUOTE;
buffer_subset=":first_name => "+ ESC_DQUOTE + first_name + ESC_DQUOTE + ", :last_name => " + ESC_DQUOTE + last_name + ESC_DQUOTE + ", :comment => " + ESC_DQUOTE + comment + ESC_DQUOTE;
flat_buffer += "{" + buffer_subset + "}, ";
counter+=1;
}
flat_buffer+="]"; //end data struct
reqid=llHTTPRequest(SERVER_URL+"/read_body", [HTTP_METHOD, "POST"], flat_buffer); //there isn't much to change here except for /read_body, which is a test route that outputs whatever the input was.
BUFFER=[]; //reset the BUFFER;
//return reqid;
}
///
n_buffer_partition_setup(list hash_args)
{
}
default
{
timer()
{
}
listen(integer channel, string name, key id, string message)
{
//llOwnerSay(name + " " + message);
list full_name = llParseString2List(name, [" "], []);
string first_name = llList2String(full_name, FIRST_NAME);
string last_name = llList2String(full_name, LAST_NAME);
string comment = message;
string agent_id = (string)id;
//integer added_success = add_to_buffer(first_name, last_name, comment);
integer added_success = add_to_buffer2(first_name, last_name, comment, agent_id);
if (added_success == TRUE)
debug("An entry was successfully added to BUFFER...");
else
debug("An entry has FAILED to be added to BUFFER...");
}
http_response(key id, integer status, list meta, string body)
{
llOwnerSay(body);
}
state_entry()
{
llOwnerSay("agent_parser() v1.1 online...");
MAX_BUFFER_LENGTH=MAX_RELATIVE_BUFFER_SIZE * PARTITION_BUFFER_BY;//n*3 //multiples of 3, since that is the data struct... need to play around with this value more. DO NOT CHANGE THIS UNLESS YOU CHANGE THE DATA STRUCTURE,
//llSetTimerEvent(TIMER_SWEEP_INTERVAL);
integer handle = llListen(0, "", NULL_KEY, "");
// llSetTimerEvent(
}
touch_start(integer total_number)
{
//llSay(0, "Touched.");
//llWhisper(0, (string)llGetUnixTime());
//integer size = llGetListLength(BUFFER);
//integer relative_size = size/3;
//integer location = size-1;
debug((string)is_buffer_empty());
//test_buffer_maxima();
//loc - size
add_to_buffer2((string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime()); //0 - 1
llSleep(1.0);
add_to_buffer2((string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime()); //1 - 2
llSleep(1.0);
add_to_buffer2((string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime()); //2 - 3
llSleep(1.0);
add_to_buffer2((string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime()); //3 - 4
llSleep(1.0);
add_to_buffer2((string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime()); //4 - 5
llSleep(1.0);
add_to_buffer2((string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime(), (string)llGetUnixTime()); //5 - 6; total size 6 @ loc 5
llSleep(1.0);
//get_relative_buffer_loc(0);
//get_relative_buffer_loc(1);
//get_relative_buffer_loc(2);
send_buffer2();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment