Jump to content

Sim Hopper Script (for groups of people)


Wulfie Reanimator
 Share

Recommended Posts

This is just something I worked on briefly after seeing an old full-perm sim hopper script that was over 1000 lines long and very hard to follow because of how fragmented it was. What the script does, is it requests random sim names from gridsurvey.com and checks the maturity rating before using llRegionSay to countdown and tell all hoppers to teleport to that location.

How to use:
- (Optional) Change your preferences in the script:

  • Acceptable sim ratings (general, moderate, adult)
  • Max retries (how many random sims to request before aborting)
  • Countdown before teleport
  • The private "script channel" to use (everybody on the same channel will be teleported)

- Put the script into any attachment (creating a new object is recommended)
- Say "hop" on the chat command channel (default: 1)
- Wait for the script to find a sim with an appropriate rating

string QUERY_URL = "http://api.gridsurvey.com/simquery.php?region=";
string RANDOM = "FETCH_RANDOM_ONLINE_REGION_FROM_DATABASE";

key SND_BEEP = "11a3f4d6-75ea-acf3-29a7-41bcba51a9d6";

// Chat commands go here.
integer chat_channel = 1;
// Commands intended for/by scripts only.
integer script_channel = -92403;

// used in TeleportCheck
integer allow_adult = 1;
integer allow_moderate = 0;
integer allow_general = 0;

// init in listen, used in dataserver
// How many tries to find a random server?
integer max_retries = 10;
integer retries_left;

// init in dataserver, used in timer
// Countdown before actually teleporting
integer max_timer = 5;
integer time_left;

key query_sim_name;     // for llHTTPRequest
key query_sim_rating;   // for llRequestSimulatorData
key query_sim_pos;      // for llRequestSimulatorData

// sim info
integer data_received;  // used in dataserver
string target_name;     // from http_response
string target_rating;   // from dataserver
vector target_pos;      // from dataserver

GetSimData(string sim_name)
{
    target_pos = <0,0,0>;
    target_rating = "";
    data_received = 0;
    query_sim_rating = llRequestSimulatorData(sim_name, DATA_SIM_RATING);
    query_sim_pos = llRequestSimulatorData(sim_name, DATA_SIM_POS);
}

integer TeleportCheck(string rating, vector pos)
{
    if(pos == ZERO_VECTOR)
    {
        llOwnerSay("TP failed, invalid coordinates!");
        return 0;
    }
    if( (rating == "ADULT"  && !allow_adult) ||
        (rating == "MATURE" && !allow_moderate) ||
        (rating == "PG"     && !allow_general) ||
        (rating == "UNKNOWN"))
    {
        llOwnerSay("TP failed, invalid maturity rating");
        return 0;
    }
    else return 1;
}

default
{
    listen(integer c, string n, key id, string m)
    {
        if(c == chat_channel)
        {
            if(m == "hop")
            {
                llOwnerSay("Looking for a sim...");
                retries_left = max_retries;
                query_sim_name = llHTTPRequest(QUERY_URL + RANDOM, [], "");
            }
        }
        else if(c == script_channel)
        {
            string cmd = llGetSubString(m, 0, 3);   // first 4 chars
            string data = llGetSubString(m, 4, -1); // the rest
            
            if(cmd == "TICK")
            {
                // llOwnerSay((string)data + "s to TP!");
                llPlaySound(SND_BEEP, 1);
            }
            if(cmd == "TELE")
            {
                target_pos = (vector)data;
                llTeleportAgentGlobalCoords(llGetOwner(), target_pos, <128, 128, 64>, <0,0,0>);
            }
        }
    }
    
    http_response(key request, integer status, list metadata, string body)
    {
        if(request == query_sim_name)
        {
            GetSimData(target_name = body);
        }
    }
    
    dataserver(key request, string data)
    {
        if(request == query_sim_rating)
        {
            target_rating = data;
            query_sim_rating = NULL_KEY;
            ++data_received;
        }
        else if(request == query_sim_pos)
        {
            target_pos = (vector)data;
            query_sim_pos = NULL_KEY;
            ++data_received;
        }
        
        // Dataserver requests may not be answered in order..
        // so we keep count of how many responses we've got.
        if(data_received == 2)
        {
            // Let's check whether the target sim meets our criteria.
            if(!TeleportCheck(target_rating, target_pos))
            {
                // If not, and we still have retries left, try again.
                if(retries_left--)
                     query_sim_name = llHTTPRequest(QUERY_URL + RANDOM, [], "");
                else llOwnerSay("Giving up on retries!");
            }
            else
            {
                // If the sim passes our criteria, start the countdown timer.
                llOwnerSay("Found a sim!");
                time_left = max_timer;
                llSetTimerEvent(1);
                query_sim_name = NULL_KEY;
            }
        }
    }
    
    timer() // Just beep beep like a sheep until teleport.
    {
        if(--time_left)
        {
            llPlaySound(SND_BEEP, 1);
            llRegionSay(script_channel, "TICK" + (string)time_left);
            // llOwnerSay((string)time_left + "s to TP!");
        }
        else
        {
            llSetTimerEvent(0);
            llRegionSay(script_channel, "TELE" + (string)target_pos);
            llTeleportAgentGlobalCoords(llGetOwner(), target_pos, <128, 128, 64>, <0,0,0>);
        }
    }
    
    state_entry()
    {
        llListen(chat_channel, "", llGetOwner(), "");   // for chat commands
        llListen(script_channel, "", "", "");           // for scripts
        
        llRequestPermissions(llGetOwner(),              // cheat no-script areas
            PERMISSION_TELEPORT|PERMISSION_TAKE_CONTROLS);
    }
    
    attach(key id)
    {
        if(id) llRequestPermissions(llGetOwner(),
            PERMISSION_TELEPORT|PERMISSION_TAKE_CONTROLS);
    }
    
    changed(integer change)
    {
        if(change & CHANGED_OWNER) llResetScript();
    }
}

For anyone who's interested in seeing the source that inspired this, see: http://puu.sh/yjTa7/79f2fd40bc.txt (But be wary)

Edited by Wulfie Reanimator
  • Like 2
  • Thanks 1
Link to comment
Share on other sites

This is a nice concept. It takes advantage of the fact that llTeleportAgentGlobalCoords will always transport the person who owns the scripted object, so if each user puts the script in a HUD, you can teleport several users to the same spot at once.  It might be worth considering three modifications:

1. Use if ( llToLower(m) == "hop") to accept alternate typed commands -- "HOP", "Hop", etc.

2. Add a touch_start event that is triggered by a button on the HUD to replace the triggering that's done with chat_channel in the listen event. That would save some potential chat lag and eliminate the need for a "hop" command at all.

3. Consider ways to avoid the chaos that would be likely if several users are spam clicking the teleport button at the same time. For example, you could designate one HUD as the master, or tell the HUDs to take turns letting different users be the master, or queue incoming commands and execute them sequentially after a delay of a few minutes, or simply block everyone's script_channel for a while after a successful TP.

EDIT:  OK, four modifications 9_9  ...  If several people all TP to the same spot, they'll pile up. You could offset each HUD's target coordinates by a small random amount to minimize the crowd jam.

Edited by Rolig Loon
  • Like 1
Link to comment
Share on other sites

9 minutes ago, Rolig Loon said:

This is a nice concept. It takes advantage of the fact that llTeleportAgentGlobalCoords will always transport the person who owns the scripted object, so if each user puts the script in a HUD, you can teleport several users to the same spot at once.  It might be worth considering three modifications:

1. Use if ( llToLower(m) == "hop") to accept alternate typed commands -- "HOP", "Hop", etc.

2. Add a touch_start event that is triggered by a button on the HUD to replace the triggering that's done with chat_channel in the listen event. That would save some potential chat lag and eliminate the need for a "hop" command at all.

3. Consider ways to avoid the chaos that would be likely if several users are spam clicking the teleport button at the same time. For example, you could designate one HUD as the master, or tell the HUDs to take turns letting different users be the master, or queue incoming commands and execute them sequentially after a delay of a few minutes, or simply block everyone's script_channel for a while after a successful TP.

All good suggestions. What I also wanted to do was add a way to toggle the acceptable ratings, but got distracted and lost interest soon after. The main goal was to simplify the original script though, not necessarily make a polished product. Anyone is free to take it from here and make it their own.

Also, generally if it's a group of friends sim hopping, the group tends to pick a specific person to do the teleporting. (Just speaking from personal experience, we never needed any turn taking or such because the sim was random regardless.) And adding an offset is mostly pointless as most sims have their own landing spot where avatars will pile up regardless of where the teleport command sends them.

Edited by Wulfie Reanimator
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...