MXP Implementation and general update

160 views
Skip to first unread message

Michael Elford

unread,
Oct 13, 2012, 6:14:15 AM10/13/12
to phudbase-...@googlegroups.com
Thought I'd share the very beginnings of my MXP implementation...all in the client.  

Essentially it will search all mud input for <HELP>XYZ</HELP> and replaces it with a link to sendDirect the HELP XYZ command to the mud server.
in index.php line 36ish:
        <script type="text/javascript" src="js/mxp.js"></script>

The call to the function goes just under the call to handle_ATCP in client.js
in client.js line 217ish
        if (data.message)
                data.message = handle_MXP(data.message);

in mxp.js (new file)
function handle_MXP(data)
{

//Test against HELP
        var str=data.toString();
        var helpRegExp = new RegExp("\&lt;HELP\&gt;(.*?)\&lt;/HELP\&gt;", "g");
        var helpRegReplace = "<a href=# onclick='sendDirect(&quot;help $1&quot;)'>$1</a>";
        var str=data;
        data = str.replace(helpRegExp, helpRegReplace);
        return(data);

}

Unrelated to the above, there's a change to be made in WebMudServer.class.inc on or around line 272:
              if (!$cObj->isNoNegotiate())
the if statement should either be commented out or removed.  You should be able to negotiate out-of-band at anytime during the session.  (I.e. I can turn MXP on or off)

I've also seriously modified the layout which has messed up the autosizing function, however, my intention is to replace autosize with various layouts that the user can select (and save their selection into a DB against their mud account).  The current layout includes space for a map (7x7 square), expanded movement buttons (up/down, in/out) which now also autofocus back to the textfield and space for room contents to be listed (mobs/items) my intention is to include an image and a short desc in this space.

Plan on getting the MAP to work tomorrow, although, that wont be very useful for anyone else unless you either implement similar output from your mud server or use coffeemud and make a couple changes to the source.

Michael Elford

unread,
Oct 14, 2012, 5:33:02 AM10/14/12
to phudbase-...@googlegroups.com
Updated mxp.js file, now changes the movement buttons based on whether there is a visible exit or not.  Mini-Map works fine, just needs more/better graphics for it.  Pretty much all the MXP tags it's using are now being parsed or ignored which has cleaned up the mud output.  I'm sure there are better ways to do some of the things, would appreciate any feedback/thoughts.  I've got some more client changes to make and then I'm going to dig a bit deeper into the server code as the phudbase server uses significant CPU when it's supposed to be idling.

updated index.php (movement Div)
                                <div id="movement">
                                        <table>
                                        <tr>
                                                <td id="moveUP" style='text-align: center; vertical-align: middle;' onclick="sendDirect('UP');">UP</td>
                                                <td style='text-align: center; vertical-align: middle; background: transparent; cursor: default;'></td>
                                                <td id="moveNW" style='text-align: center; vertical-align: middle;' onclick="sendDirect('NW');">NW</td>
                                                <td id="moveN" style='text-align: center; vertical-align: middle;' onclick="sendDirect('N');">N</td>
                                                <td id="moveNE" style='text-align: center; vertical-align: middle;' onclick="sendDirect('NE');">NE</td>
                                                <td style='text-align: center; vertical-align: middle; background: transparent; cursor: default;'></td>
                                                <td id="moveIN" style='text-align: center; vertical-align: middle;' onclick="sendDirect('IN');">IN</td>
                                        </tr>
                                        <tr>
                                                <td style='text-align: center; vertical-align: middle; background: transparent; cursor: default;'></td>
                                                <td style='text-align: center; vertical-align: middle; background: transparent; cursor: default;'></td>
                                                <td id="moveW" style='text-align: center; vertical-align: middle;' onclick="sendDirect('W');">W</td>
                                                <td style='text-align: center; vertical-align: middle; background: transparent; cursor: default;'></td>
                                                <td id="moveE" style='text-align: center; vertical-align: middle;' onclick="sendDirect('E');">E</td>
                                                <td style='text-align: center; vertical-align: middle; background: transparent; cursor: default;'></td>
                                                <td style='text-align: center; vertical-align: middle; background: transparent; cursor: default;'></td>
                                        </tr>
                                        <tr>
                                                <td id="moveD" style='text-align: center; vertical-align: middle;' onclick="sendDirect('DOWN');">D</td>
                                                <td style='text-align: center; vertical-align: middle; background: transparent; cursor: default;'></td>
                                                <td id="moveSW" style='text-align: center; vertical-align: middle;' onclick="sendDirect('SW');">SW</td>
                                                <td id="moveS" style='text-align: center; vertical-align: middle;' onclick="sendDirect('S');">S</td>
                                                <td id="moveSE" style='text-align: center; vertical-align: middle;' onclick="sendDirect('SE');">SE</td>
                                                <td style='text-align: center; vertical-align: middle; background: transparent; cursor: default;'></td>
                                                <td id="moveOUT" style='text-align: center; vertical-align: middle;' onclick="sendDirect('OUT');">OUT</td>
                                        </tr>
                                        </table>
                                </div>




mxp.js

// Process any MXP messages //


function process_Prompt(str)
{
        console.log("PROMPT: "+str);
}

function check_PROMPT(str)
{
        var promptRegExp = new RegExp("&lt;Prompt&gt;(.*?)&lt;\/Prompt&gt;", "g");
        var promptRegReplace = "&lt;.*?&gt;|<.*?>";
        if (str.search(promptRegExp) != -1)
        {
                var promptData = str.match(promptRegExp); //Extract the data..returns an array
                promptData = promptData[0];  //just get the first element of the array
                process_Prompt(promptData);  // WORK WITH PROMPT
                str = str.replace(promptRegExp,""); //remove all prompt data from display
        }
        return(str);
}

function process_Exits(str)
{
//      console.log("EXIT: "+str);
        if (str.search("&lt;EX&gt;Up")!=-1)
        {
                document.getElementById("moveUP").style.background="green";
                return;
        }
        if (str.search("&lt;EX&gt;North&lt;")!=-1)
        {
                document.getElementById("moveN").style.background="green";
                return;
        }
        if (str.search("&lt;EX&gt;South&lt;")!=-1)
        {
                document.getElementById("moveS").style.background="green";
                return;
        }
        if (str.search("&lt;EX&gt;East &lt;")!=-1)
        {
                document.getElementById("moveE").style.background="green";
                return;
        }
        if (str.search("&lt;EX&gt;West &lt;")!=-1)
        {
                document.getElementById("moveW").style.background="green";
                return;
        }
        if (str.search("&lt;EX&gt;Down&lt;")!=-1)
        {
                document.getElementById("moveD").style.background="green";
                return;
        }
        if (str.search("&lt;EX&gt;Northeast")!=-1)
        {
                document.getElementById("moveNE").style.background="green";
                return;
        }
        if (str.search("&lt;EX&gt;Southwest")!=-1)
        {
                document.getElementById("moveSW").style.background="green";
                return;
        }
        if (str.search("&lt;EX&gt;Southeast")!=-1)
        {
                document.getElementById("moveSE").style.background="green";
                return;
        }
        if (str.search("&lt;EX&gt;Northwest")!=-1)
        {
                document.getElementById("moveNW").style.background="green";
                return;
        }
        if (str.search("&lt;EX&gt;In")!=-1)
        {
                document.getElementById("moveIN").style.background="green";
                return;
        }
        if (str.search("&lt;EX&gt;Out")!=-1)
        {
                document.getElementById("moveOUT").style.background="green";
                return;
        }
}

function clear_EXITS()
{
                document.getElementById("moveUP").style.background="#242424";
                document.getElementById("moveN").style.background="#242424";
                document.getElementById("moveS").style.background="#242424";
                document.getElementById("moveE").style.background="#242424";
                document.getElementById("moveW").style.background="#242424";
                document.getElementById("moveD").style.background="#242424";
                document.getElementById("moveNE").style.background="#242424";
                document.getElementById("moveSW").style.background="#242424";
                document.getElementById("moveSE").style.background="#242424";
                document.getElementById("moveNW").style.background="#242424";
                document.getElementById("moveIN").style.background="#242424";
                document.getElementById("moveOUT").style.background="#242424";
}

function check_EXITS(str)
{
        var exitRegExp = new RegExp("&lt;EX&gt;(.*?)&lt;\/EX&gt;\:.*?<br>", "g");
        var exitRegReplace = "&lt;.*?&gt;|<.*?>";
        if (str.search(exitRegExp) != -1)
        {
//              console.log("Exit before match: " + str);
                var exitData = str.match(exitRegExp); //Extract the data..returns an array
//              console.log("Exit Data: " + exitData);
                clear_EXITS();
                // Clear exit data!!
                for (var i=0;i<exitData.length;i++)
                        process_Exits(exitData[i]);  //Process each found exit.

                str = str.replace(exitRegExp,""); //remove all prompt data from display
        }
        return(str);

}

function check_HELP(str)
{
        var helpRegExp = new RegExp("&lt;HELP&gt;(.*?)&lt;\/HELP&gt;", "g");
        var helpRegReplace = "<a href=# onclick='sendDirect(&quot;help $1&quot;)'>$1</a>";
        str = str.replace(helpRegExp, helpRegReplace);
        return(str);
}

function check_IMAGE(str)
{
        var imageRegExp = new RegExp("&lt;IMAGE(.*?)&gt;", "g");
        var imageRegReplace = "";
        str = str.replace(imageRegExp, imageRegReplace);
        return(str);
}



function process_MAP(str)
{
        var html_MAP = "<table>";
        for (var i=0;i<5;i++)
        {
                html_MAP += "<tr>";
                for (var j=0;j<5;j++)
                {
                        if (str.charAt(i*5+j) == "=") //city
                        {
                                html_MAP += "<td style='background:url(";
                                html_MAP += '"'+mxpRoot+'locale_city2.png");';
                                html_MAP += "background-repeat: no-repeat; background-size: 80px 80px;'></td>";
                        }
                        else
                                html_MAP += "<td>" + str.charAt(i*5+j) + "</td>";
                }
                html_MAP += "</tr>";
        }
        html_MAP +="</table>";
//      console.log("HTMLMAP: " +html_MAP);
        document.getElementById("map").innerHTML=html_MAP;
}


Michael Elford

unread,
Oct 14, 2012, 5:34:48 AM10/14/12
to phudbase-...@googlegroups.com
mxp.js continued

function check_MAP(str)
{
        var fullmapRegExp = new RegExp("&lt;MAP&gt;(.*?)&lt;\\/MAP&gt;");
        var incmapRegExp = new RegExp("&lt;MAP&gt;");
        var mapRegExpReplace = new RegExp("&lt;.*?&gt;|<.*?>|((2))", "g");
        if (str.search(fullmapRegExp)!=-1)
        {
                var mapData = str.match(fullmapRegExp); //Extract the map data..returns an array
                mapData = mapData[0];  //just get the first element of the array
                mapData = mapData.replace(mapRegExpReplace, "");  //replace all the non map data with nothing
                process_MAP(mapData);  //proocess the map data, also updates the screen...
                //Remove all MAP data from the string and return
                str = str.replace(fullmapRegExp, "");
                return(str);
        } else {
        //      console.log("Haven't found a full MAP");
                if (str.search(incmapRegExp)!=-1)
                {
        //              console.log("Found incomplete Map");
                }
        }
        return(str);

}

function check_REMOVE(str)
{
        str = str.replace("Obvious exits:",""); //remove final exit data from display
        str = str.replace("<br><br><br><br>",""); //remove lots of line breaks...
        str = str.replace("<br><br>","");
        str = str.replace("&lt;RName&gt;","");
        str = str.replace("&lt;/RName&gt;","");
        str = str.replace("&lt;RDesc&gt;","");
        str = str.replace("&lt;/RDesc&gt;","");
        console.log("REMOVE: "+str);
        return(str);
}

function handle_MXP(data)
{
        str = data.toString();
//Test against PROMPT
        str = check_PROMPT(str);
//Test against EXITS
        str = check_EXITS(str);
//Test against HELP
        str = check_HELP(str);
//Test against IMAGE
        str = check_IMAGE(str);
//Test against MAP
        str = check_MAP(str);
//      console.log(str);
//Test against strings to be removed (includes extra <br> & unused tags)
        str = check_REMOVE(str);
        return(str);
}

Ragnar

unread,
Oct 18, 2012, 9:21:03 PM10/18/12
to phudbase-...@googlegroups.com
Yah the CPU usage seems to stem from the only pausing I've seen the server do is an arbitrary sleep that isn't clock synced.  Merc/Diku/Rom muds deal with this using this function:

void sync_to_clock(void)
{
    long secDelta;
    long usecDelta;

    gettimeofday( &now_time, NULL );
    usecDelta   = last_time.tv_usec - now_time.tv_usec
                + (1000000 / PULSE_PER_SECOND);
    secDelta    = last_time.tv_sec - now_time.tv_sec;
    while ( usecDelta < 0 )
    {
        usecDelta += 1000000;
        secDelta  -= 1;
    }
    while ( usecDelta >= 1000000 )
    {
        usecDelta -= 1000000;
        secDelta  += 1;
    }
    if (secDelta > 0)
        sleep(secDelta);
    if ( usecDelta > 0)
        usleep((useconds_t) usecDelta);
    gettimeofday( &last_time, NULL );
    current_time = (time_t) last_time.tv_sec;
    return;
}

I imagine building a similar one into the server.php's main loop would resolve this issue entirely, from what I'd read the early instances of it wouldn't sleep at all.

Douglas James

unread,
Aug 24, 2014, 5:59:30 AM8/24/14
to phudbase-...@googlegroups.com
i found /phudbase-wm/wm_server/includes/classes/Server/MXP/handle_mxp.inc was handling mxp for send/color in the SERVER, by that i mean it was just stripping out everything. i'm guessing the code moved over to your mxp.js.  well anyway, hope that helps people save some pain

Douglas James

unread,
Aug 26, 2014, 5:10:31 AM8/26/14
to phudbase-...@googlegroups.com
i had some luck just updating the above mentioned MXP file location.  you dont want to modify it in the client because youre inviting your players to send stuff at peoples screens. i'm using kavirs mud protocol snippet for those who care.  this is the code i used to change my mxp

this is from my game code

#ifdef MXP_ENABLED
        if(!IS_NPC(ch) && ch->pcdata->mxp)
        {
          strcat(buf, "\t<send>\t<font color=White>");
          strcat( buf, dir_name[door] );
          strcat(buf, "\t</font>\t</send>");
        }
        else
#endif



/this is what that comes out like on the phudbase client
//some of the escape characters are not displayed but basically every [\dz has one in front.

//[1z<send>[7z[1z<font color=White>[7znorth[1z</font>[7z[1z</send>[7z
$pattern = "/"
  . "(" . chr(27) . "\[1z)"
  . "<send>"
  . "(" . chr(27) . "\[7z)"
  . "(" . chr(27) . "\[1z)"
  . "<font color=White>"
  . "(" . chr(27) . "\[7z)"
  . "([A-Za-z0-9-\s]+)"
  . "(" . chr(27) . "\[1z)"
  . "<\/font>"
  . "(" . chr(27) . "\[7z)"
  . "(" . chr(27) . "\[1z)"
  . "<\/send>"
  . "(" . chr(27) . "\[7z)"
  . "/is";
//its easier to match difficult long regex by working one line at a time if youre wondering why i did it like this


$data = preg_replace($pattern,
  "MXP_OPENa style=\"color: Yellow;\" href=\"javascript:void(0);\" onclick=\"sendDirect('$5');\"MXP_CLOSE$5MXP_OPEN/aMXP_CLOSE",
  $data,-1,$count);

obviously, the regex you find in that mxp snippet should be commented out  first before you start messsing with mxp. all of them.

Reply all
Reply to author
Forward
0 new messages