PtokaX forum

Lua 5.3/5.2/5.1 Scripts (for PtokaX 0.4.0.0 and newer) => Finished Scripts => Topic started by: amenay on 01 April, 2008, 00:35:29

Title: Simple Interactive Mode
Post by: amenay on 01 April, 2008, 00:35:29
--[[

Simple Interactive Mode by amenay.

Usage notes:

Aside from the general security concerns involved with this sort of script (which any hub owner should be aware of), there are a couple usage
notes mostly in respect to some of the behavioural aspects of the script.

First, mind your endpipes, the behaviour here varies depending on what you're doing -- if you're defining something from a DC client use \124
opposed to the HTML escape method of | (which you'll want to use to send messages containing non-delimiting endpipes to your client from
the hub (See: ReadFile)
Second,  if you're not familiar with the behaviour of variadic functions and the vararg expression (and how it's used alongside loadstring)
then you might want to look it up a bit in the mailing list. In short, chunks compiled by loadstring (which are not function with traditional
paremeters) can receive arguments through the vararg expression. (Example: foo = loadstring( "local tUser, sData = ... <chunk>" ) foo( tUser, sData ) )

--]]

do
_PROMPT = "Interactive mode >|";
tInteractive = { };

tSettings = {
[1] = "^[" .. ( SetMan.GetString( 29 ):gsub( ( "%p" ), function ( p ) return "%" .. p end ) ) .. "]",
[2] = "#SIM" or SetMan.GetString( 21 ), --BotName
[3] = "", --BotDesc
[4] = "", --BotEmail
[5] = true, --BotbOp
[6] = { ["amenay"] = true, ["AnotherTrustedNick"] = true } --Allowed Users by nick.
}

print = function( ... )
local tBuff = { };
for _, v in ipairs( { ... } ) do
tBuff[ #tBuff + 1 ] = tostring( v );
end
local SendMethod = SendMethod or function( tUser, sData ) Core.SendToUser( tUser, "$To: " .. tUser.sNick .. " From: " .. tSettings[2] .. " $" .. sData ) end;
for i, v in pairs( tInteractive ) do
SendMethod( v, table.concat( tBuff, "\t\t" ) );
end
end

end

function OnStartup( )
Core.RegBot( tSettings[2], tSettings[3], tSettings[4], true );
end

OnError = print;

function OnExit( )
print( "Interactive mode interupted by script exit.|" );
end

function UserDisconnected( tUser, sData )
if tInteractive[ tUser.uptr ] then
tInteractive[ tUser.uptr ] = nil;
end
end

OpDisconnected = UserDisconnected;
RegDisconnected = UserDisconnected;

function ToArrival( tUser, sData )

local sToUser = sData:match( "^(%S+)", 6 );
if sToUser == tSettings[2] then
local nInitIndex = #sToUser + 18 + #tUser.sNick * 2;
if tInteractive[ tUser.uptr ] then
local sBody = sData:sub( nInitIndex, -2 );
Core.SendToUser( tUser, "$To: " .. tUser.sNick .. " From: " .. tSettings[2] .." $" .. sBody .. "" );
local foo = assert( loadstring( sBody ) );
local bStatus, ret =  pcall( foo, tUser, sData );
if tInteractive[ tUser.uptr ] then Core.SendToUser( tUser, "$To: " .. tUser.sNick .. " From: " .. tSettings[2] .." $" .. _PROMPT ) end;
if bStatus then
return ret or bStatus;
else
return error( ret ), bStatus;
end
end

if sData:match( tSettings[1], nInitIndex ) then
local sCmd = sData:match( "^(%w+)", nInitIndex + 1 );
if sCmd then
sCmd = sCmd:lower( );
if tCommandArrivals[ sCmd ] then
if tCommandArrivals[ sCmd ].Permissions[ tUser.iProfile ] then
local sMsg;
if ( nInitIndex + #sCmd ) <= #sData + 1 then sMsg = sData:sub( nInitIndex + #sCmd + 2 ) end;
return tCommandArrivals[ sCmd ]:Action( tUser, sMsg );
else
return Core.SendPmToUser( tUser, tSettings[2],  "*** Permission denied.|" ), true;
end
else
return false;
end
end
end
end

end

--Commands

tCommandArrivals = {

imode = {
Permissions = {
[0] = true, [1] = true;
}
}

};

function tCommandArrivals.imode:Action( tUser )
if tSettings[6][ tUser.sNick ] then
tInteractive[ tUser.uptr ] = tUser;
return Core.SendPmToUser( tUser, tSettings[2], "*** Entering interactive mode. Type tInteractive[ Core.GetUser( \"" .. tUser.sNick ..
"\" ).uptr ] = nil to end.|$To: " .. tUser.sNick .. " From: " .. tSettings[2] .. " $" .. _PROMPT ), true;
end
end

-- Useful Functions

function EndSIM( tUser )
tInteractive[ tUser.uptr ] = nil;
Core.SendPmToUser( tUser, tSettings[2], "*** Leaving interactive mode.|" );
end

function ReadFile( sName ) --Reads this script by default.
sName = sName or ScriptMan.GetScript( ).sName;
local fData, sError = io.open( sName );
if not sError then
local sContents = "\n" .. fData:read( "*a" ):gsub( "|", "&#124;" );
print( sContents );
else
error( sError );
end
fData:close( );
end


A script I've found infinitely useful in configuring hubs and testing other scripts -- works well as a drop-in debug solution as well. It's more for advanced users, and people that know some Lua than anything. Suggestions welcome.
Title: Simple Interactive Mod[ul]e
Post by: amenay on 04 February, 2009, 03:55:31
Alright, so I've made this into a module to make it a bit easier to drop into other scripts. There are some notes in the rar covering a few features and eccentricities. I highly recommend this script to anyone attempting to debug/optimize a script or for observing behavior and testing new ideas. I've not really added much over the last few months, and just decided it had enough beef to put out there. I'm hoping to post a few snippets in the near future showing some of the tasks which can be accomplished with it, since some of them aren't quite so plain.

Questions and suggestions are highly welcome per usual.

PS: Use at your own risk.