Sign in to follow this  
Followers 0
Guest Toast

startup.lua

9 posts in this topic

Since there isn't any script forum yet for script i had to put this in here

Here is a awsome startup script made by ATAG that makes lua scripts easier to manage

a additional script is needed to run this startup script and that script is called libsimplepickle.lua

please replace the current startup script with this one its really so much better then the old startup script

	--[[ startup.lua: version 2.1.2d 2009/01/22

		 modded by ATAG - atagster [at] gmail [dot] com


	   2.1.2d:

		  fixed: error on missing libsimplepickle.lua - reported by [NH]Nando


	   2.1.2c:

		  first public release


	NMDC Listeners (events):

		  chat	  = normal chat message (you won't get your own messages)

				  function chat( hub, user, "message" )

				  DISCARDABLE:

					* return non-nil to hide the msg from BCDC++

		  unknownchat   = incoming messages displayed without any nick

				  function unknownchat( hub, "message" )

				  DISCARDABLE

		  ownChat	  = normal chat message from yourself (incoming from the hub)

				  function ownChat( hub, "message" )

				  DISCARDABLE

		  pm	  = normal pm message

				  function pm( hub, user, "message" )

				  DISCARDABLE

		  hubPm	  = pm message with a different prefix than the nick in the From field

				  function hubPm( hub, user, "message which may include a <nickname>" )

				  DISCARDABLE

		  userConnected	= a user connected (or rather.. the first getUser call was made)

				  function userConnected( hub, user )

		  userMyInfo   = a myinfo message from a user, use this as "userConnected"

				  function userMyInfo( hub, user, "$MyINFO $ALL ... 1234$|" )

				  DISCARDABLE

		  userQuit   = a quit message from a user

				  function userQuit( hub, nick )

				  DISCARDABLE

		  raw	  = a full message

				  function raw( hub, "line" )

				  DISCARDABLE (message won't get parsed.. no other listeners will be called)

	ADC Listeners:

		  adcChat	  = normal chat message (you won't get your own messages).

				  function adcChat( hub, user, "message", me_msg )

				  DISCARDABLE:

					* return non-nil to hide the msg from BCDC++,

					* me_msg is true if a /me-style message is sent

		  adcOwnChat   = normal chat message from yourself (incoming from the hub)

				  function adcOwnChat( hub, "message", me_msg )

				  DISCARDABLE

		  adcPm	  = normal pm message

				  function adcPm( hub, user, "message", me_msg )

				  DISCARDABLE

		  groupPm	  = pm message with a different reply-sid than the one who talks (probably chatroom or bot)

				  function groupPm( hub, user, "message", reply_sid, me_msg )

				  DISCARDABLE

		  userInf	  = an INF message from a user

				  function userInf( hub, user, flags )

			   flags is a table where all named flags are stored (ie: flags["NI"], flags["I4"], ...)

				  DISCARDABLE

		  adcUserCon	= a user connected (or rather.. the first getUser call was made)

				  function adcUserCon( hub, user )

		  adcUserQui   = a quit message from a user

				  function adcUserQui( hub, sid, flags )

			   flags is a table where all named flags are stored (ie: flags["ID"], flags["MS"], ...)

	Common Listeners:

		  ownChatOut   = normal chat message from yourself (outgoing to the hub)

				  function ownChatOut( hub, "message" )

				  DISCARDABLE

		  connected   = connecting to a hub (many functions may be unavailable (return nil))

				  function connected( hub )

		  disconnected	= disconnected from a hub

				  function disconnected( hub )

		  timer	  = called every second (if DC():RunTimer(1) is called), use

				  dcpp:getHubs()[k]:getAddress() or :getUrl() to select a hub

				  function timer()

		  clientIn   = peer to peer line oriented transfer control input, userp is a pointer

				  (lightuserdata)

				  function clientIn( userp, "line" )

				  DISCARDABLE (returning non-nil kills the connection)

		  clientOut   = peer to peer line oriented transfer control output, userp is a pointer

				  (lightuserdata)

				  function clientOut( userp, "line" )

				  DISCARDABLE (returning non-nil kills the connection)


	Example listener:

	   function chat( hub, user, text )

		  local s = string.lower( text )

		  if string.find( s, "[^a-z]bier+[^a-z]" ) or string.find( s, "[^a-z]biertje[^a-z]" ) then

			 hub:sendChat( "bier? ja lekker! :)" )

		  end

	   end


	Example Usercommand:

	   function connected( hub )

		  if ( hub:getProtocol() ~= "adc" ) then

			 hub:injectChat( '$UserCommand 1 2 Ignore$%[lua:scriptMan:Run("AddUser","!%!{userNI!}")]||' )

			 hub:injectChat( '$UserCommand 1 2 Unignore$%[lua:scriptMan:Run("RmUser","!%!{userNI!}")]||' )

		  end

	   end

	]]							  


	DC():PrintDebug( "  ** Started startup.lua **" )


	--/////////////////////////////////////

	--// Helper functions

	--/////////////////////////////////////


	if not dcu then

	   dcu = {}

	end


	dcu.NmdcEscape = function(this, msg )

	   msg = msg:gsub( "[%$|]", function(s) return "&#"..string.byte(s)..";" end )

	   return msg

	end


	dcu.AdcEscape = function(this, msg, inverse)

	   msg = string.gsub(msg, "\r", "")

	   local ret = ""

	   if inverse then

		  local replacetable = {

			 ["\\\\"] = [[\]],

			 ["\\s"] = [[ ]],

			 ["\\n"] = "\n"

		  }

		  local skip = false

		  for k = 1, #msg do

			 if skip then

				skip = false

			 else

				local c = msg:sub( k, k + 1)

				if replacetable[c] then

				   ret = ret .. replacetable[c]

				   skip = true

				else

				   ret = ret .. c:sub(1, 1)

				end

			 end

		  end

	   else

		  local replacetable = {

			 ["\\"] = [[\\]],

			 [" "] = [[\s]],

			 ["\n"] = [[\n]]

		  }

		  for k = 1, #msg do

			 local c = msg:sub( k, k)

			 if replacetable[c] then

				ret = ret .. replacetable[c]

			 else

				ret = ret .. c

			 end

		  end

	   end

	   return ret

	end


	--// Checks if the given decimal number has the 2^exp bit set

	dcu.BBit = function(this, num, exp)

	   if string.find( math.floor(num / 2^exp), "[13579]$") then

		  return true

	   end

	   return false

	end


	--/////////////////////////////////////

	--// Hub manager

	--/////////////////////////////////////


	if not dcpp or dcpp._init_me_anyway == true then

	   dcpp = {}

	   dcpp._hubs = {}

	   dcpp._listeners = { id = {} }

	end


	dcpp.addHub = function( this, hub, isitadc )

	   if not this._hubs[hub] then

		  -- DC():PrintDebug( "Hub added (id = "..tostring( hub )..")" )

		  if isitadc then

			 this._hubs[hub] = createAdcHub( hub )

			 DC():PrintDebug( "ADC hub added (id = " .. tostring( hub ) ..")" )

		  else

			 this._hubs[hub] = createNmdcHub( hub )

		  end

		  local h = dcpp:getHub( hub )

		  scriptMan:Run( "connected", h )


		  return this._hubs[hub]

	   else

		  --DC():PrintDebug( "Tried to add existing hub on: "..this._hubs[hub]:getHubName()..

		  --				  " (id = "..tostring( hub )..")" )

		  return nil

	   end

	end


	dcpp.getHub = function( this, hub )

	   if this._hubs[hub] then

		  return this._hubs[hub]

	   else

		  --DC():PrintDebug( "Tried to fetch an unknown hub (id = "..tostring( hub )..")" )

		  return this:addHub( hub ):setPartial() -- tell the object that we missed the logon

	   end

	end


	dcpp.getHubs = function( this )

	   return this._hubs

	end


	dcpp.hasHub = function( this, hub )

	   if this._hubs[hub] then

		  return 1

	   else

		  return nil

	   end

	end


	dcpp.findHub = function( this, url )

	   for k, h in pairs(this._hubs) do

		  if h:getUrl() == url then

			 return h

		  end

	   end

	   return false

	end



	dcpp.removeHub = function( this, hub )

	   if this._hubs[hub] then

		  --DC():PrintDebug( "Hub removed: "..this._hubs[hub]:getHubName().." (id = "..tostring( hub )..")" )

		  local h = dcpp:getHub( hub )

		  scriptMan:Run( "disconnected", h )


		  this._hubs[hub]:destroy()

		  this._hubs[hub] = nil

	   else

		  --DC():PrintDebug( "Tried to remove non-existent hub (id = "..tostring( hub )..")" )

	   end	  

	end


	dcpp.listHubs = function( this )

	   DC():PrintDebug( "** Listing hubs **" )

	   for k,v in pairs(this._hubs) do

		  DC():PrintDebug( tostring( k ).." ("..v:getHubName()..")" )

	   end

	end


	dcpp.setListener = function( this, ltype, id, func  )

	   -- load func into the caller's environment

	   getfenv(2)[ltype] = func

	end


	dcpp.getListeners = function( this, ltype )

	-- only for backward compatibility :)

	end


	--/////////////////////////////////////

	--// Hub object

	--/////////////////////////////////////


	function createAdcHub( hubid )

	   local hub = {}


	   hub._id = hubid

	   hub._mySID = nil

	   hub._myNick = nil

	   hub._myCID = nil

	   hub._nick = nil

	   hub._description = nil

	   hub._users = {}

	   hub._uptime = os.time()


	   hub.getId = function( this )

		  return this._id

	   end


	   hub.getUptime = function( this )

		  return ( os.time() - hub._uptime ) / 60

	   end


	   hub.getProtocol = function( this )

		  return "adc"

	   end


	   hub.getAddress = function( this )

		  return DC():GetHubIpPort( this._id )

	   end


	   hub.getHubName = function( this )

		  --// TODO: Shall we return with NI or DE? or both?

		  --//	   For now just returning the nick with the url

		  if this._nick then

			 return this._nick  .. " ("..this:getUrl()..")"

		  else

			 return this:getUrl()

		  end

	   end


	   hub.getUrl = function( this )

		  return DC():GetHubUrl( this._id )

	   end


	   hub.getOwnNick = function( this )

		  return this._myNick

	   end


	   hub.setOwnNick = function( this, newnick )

		  this._myNick = newnick

		  DC():PrintDebug( " [STATUS] Own nick set: " .. newnick )

	   end


	   hub.getOwnSid = function( this )

		  if this._mySID then

			 return this._mySID

		  end

		  DC():PrintDebug( " [" .. this:getUrl() .."] Own SID not set, your scripts are failing. Reconnect please." )

	   end


	   hub.getOwnCid = function( this )

		  if this._myCID then

			 return this._myCID

		  end

		  DC():PrintDebug( " [" .. this:getUrl() .."] Own CID not set, your scripts are failing. Reconnect please." )

	   end


	   hub.getUser = function( this, sid, inf )

		  local newuser = false

		  if sid == "HUB9" and inf then

			 -- INF is about the hub itself

			 local params = {}

			 string.gsub(inf, "([^ ]+)", function(s) table.insert(params, s) end )

			 for k in pairs(params) do

				local name = string.sub( params[k], 1, 2 )

				if name == "NI" then

				   local NI = dcu:AdcEscape(string.sub( params[k], 3), true)

				   this._nick = NI

				   DC():PrintDebug(" [STATUS] HUB nick set: " .. NI )

				elseif name == "DE" then

				   local DE = dcu:AdcEscape(string.sub( params[k], 3), true)

				   this._description = DE

				   DC():PrintDebug(" [STATUS] HUB description set: " .. DE )

				end

			 end

		  end


		  if not this._users[sid] then

			 this._users[sid] = createAdcUser( this, sid )

			 newuser = true

			 if this:getUptime() >= 2 then -- start sending messages AFTER logon

						 scriptMan:Run( "adcUserCon", this, this._users[sid] )

			 end

		  end

		  local r = this._users[sid]

		  if inf then

			 local params = {}

			 string.gsub(inf, "([^ ]+)", function(s) table.insert(params, s) end )

			 for k in pairs(params) do

				local name = string.sub( params[k], 1, 2 )

				if name == "ID" then

				   local ID = string.sub( params[k], 3)

				   r:setCid(ID)

				   if sid == this._mySID then

					  this._myCID = ID

					  DC():PrintDebug(" [STATUS] Own CID set: " .. ID )

				   end

				elseif name == "CT" then

				   local CT = string.sub( params[k], 3)

				   r:processCt(CT)

				elseif name == "I4" then

				   local I4 = string.sub( params[k], 3)

				   r:setIp(I4)

				elseif name == "NI" then

				   local NI = dcu:AdcEscape(string.sub( params[k], 3), true)

				   if not newuser then

					  local oldNI = r:getNick()

					  r:setNick(NI)				  

					  this:addLine( oldNI .. " is now known as " .. NI )

				   else

					  r:setNick(NI)

				   end

				   if sid == this._mySID then

					  this:setOwnNick(NI)

				   end

				end

			 end

		  end

		  return r

	   end


	   hub.removeUser = function( this, sid )

		  this._users[sid] = nil

	   end


	   hub.isOp = function( this, sid )

		  if this._users[sid] then

			 return this._users[sid]._op

		  end

		  return nil

	   end


	   hub.getSidbyNick = function( this, nick )

		  for k in pairs(this._users) do

			 if this._users[k]._nick == nick then

				return k

			 end

		  end

		  return nil

	   end


	   hub.getSidbyCid = function( this, cid )

		  for k in pairs(this._users) do

			 if this._users[k]._cid == cid then

				return k

			 end

		  end

		  return nil

	   end


	   hub.sendChat = function( this, msg )

		  local ownSid = this:getOwnSid()

		  msg = dcu:AdcEscape( msg )

		  DC():SendHubMessage( this:getId(), "BMSG " .. ownSid .. " " .. msg .. "\n" )

	   end


	   hub.injectChat = function( this, msg )

			 DC():PrintDebug(" [WARNING] Your scripts trying to use hub:injectChat on ADC hub. Please use hub:injectMessage() to inject an ADC message or hub:addLine() to inject a chat line." )

			 -- hub:injectMessage( msg )

	   end


	   hub.injectMessage = function( this, msg )

		  DC():InjectHubMessageADC( this:getId(), msg )

	   end


	   hub.addLine = function( this, msg, fmt )

		  --// TODO: need a function which adds a chat line without nick

		  msg = dcu:AdcEscape( msg )

		  DC():InjectHubMessageADC( this:getId(), "ISTA 000 " .. msg )

	   end


	   hub.sendPrivMsgTo = function( this, victimSid, msg_unescaped, hideFromSelf )

		  local ownSid = this:getOwnSid()

		  local msg = dcu:AdcEscape( msg_unescaped )

		  if ownSid then

			 if hideFromSelf then

				DC():SendHubMessage( this:getId(), "DMSG ".. ownSid .. " " .. victimSid .." " .. msg .. " PM" .. ownSid .."\n" )

			 else

				DC():SendHubMessage( this:getId(), "EMSG ".. ownSid .. " " .. victimSid .." " .. msg .. " PM" .. ownSid .."\n" )

			 end

		  end   

	   end


	   hub.injectPrivMsg = function( this, victimSid, fromSid, msg )

		  DC():InjectHubMessageADC( this:getId(), "DMSG " .. fromSid .." ".. victimSid .." ".. msg .. " PM" .. victimSid .. "\n" )

	   end


	   hub.findUsers = function( this, nick, notag )

		  -- you get a possibly empty table of users

		  if not notag then

			 return { this._users[this:getSidbyNick(nick)] }

		  else

			 local list = {}

			 for k in pairs(this._users) do

				local ret,c,n = string.find( this._users[k]._nick, "^%[.*%](.-)$" )

				if n == nick then

				   table.insert( list, this._users[k] )

				end

			 end

			 return list

		  end

	   end


	   hub.destroy = function( this )

	   end


	   --// events


	   hub.onChatMessage = function( this, user, text, me_msg )

		  return scriptMan:Run( "adcChat", this, user, text, me_msg )

	   end


	   hub.onChatFromSelf = function( this, text, me_msg )

		  return scriptMan:Run( "adcOwnChat", this, text, me_msg )

	   end   


	   hub.onINF = function( this, user, flags )

		  return scriptMan:Run( "userInf", this, user, flags )

	   end


	   hub.onQUI = function( this, sid, flags )

		  scriptMan:Run( "adcUserQui", this, sid, flags )

	   end


	   hub.onPrivateMessage = function( this, user, targetSid, replySid, text, me_msg )

		  if targetSid == this:getOwnSid() then

			 if user:getSid() == replySid then

				return scriptMan:Run( "adcPm", this, user, text, me_msg )

			 else

				return scriptMan:Run( "groupPm", this, user, replySid, text, me_msg )

			 end   

		  end

	   end


	   hub.attention = function( this )

		  DC():HubWindowAttention( this:getId() )

	   end


	   return hub

	end


	function createNmdcHub( hubid )

	   local hub = {}


	   hub._id = hubid

	   hub._users = {}

	   hub._name = nil

	   hub._myNick = nil

	   hub._partial = nil

	   hub._gotOpList = nil

	   hub._uptime = os.time()

	   hub._hubUC = {}

	   hub._customUC = {}


	   hub.getId = function( this )

		  return this._id

	   end


	   hub.getProtocol = function( this )

		  return "nmdc"

	   end


	   hub.getUptime = function( this )

		  return ( os.time() - hub._uptime ) / 60

	   end


	   hub.getUser = function( this, nick, op )

		  if not this._users[nick] then

			 this._users[nick] = createNmdcUser( this, nick )

			 if this:getUptime() >= 2 then -- start sending messages AFTER logon

						 scriptMan:Run( "userConnected", this, this._users[nick] )

			 end

		  end

		  local r = this._users[nick]

		  if op then

			 r:setOp( true )

			 r:setClass( "op" )

			 this._gotOpList = 1

		  end

		  return r

	   end


	   hub.findUsers = function( this, nick, notag )

		  -- you get a possibly empty table of users

		  if not notag then

			 return { this._users[nick] }

		  else

			 local list = {}

			 for k,v in pairs(this._users) do

				local ret,c,n = string.find( k, "^%[.*%](.-)$" )

				if n == nick then

				   table.insert( list, v )

				end

			 end

			 return list

		  end

	   end


	   hub.gotOpList = function( this )

		  return this._gotOpList

	   end


	   hub.isOp = function( this, nick )

		  if this._users[nick] and this._users[nick]:isOp() then

			 return 1

		  end

	   end


	   hub.removeUser = function( this, nick )

		  this._users[nick] = nil

	   end


	   hub.setPartial = function( this )

		  --// we're most likely missing logon info

		  this._partial = 1

	   end


	   hub.isPartial = function( this )

		  --// are we missing logon info?

		  return this._partial

	   end   


	   hub.setHubName = function( this, msg )

		  this._name = msg

	   end


	   hub.getAddress = function( this )

		  return DC():GetHubIpPort( this._id )

	   end


	   hub.getUrl = function( this )

		  return DC():GetHubUrl( this._id )

	   end


	   hub.getHubName = function( this )

		  if this._name then

			 return this._name.." ("..this:getUrl()..")"

		  else

			 return this:getUrl()

		  end

	   end


	   hub.setOwnNick = function( this, nick )

		  this._myNick = nick

	   end


	   hub.getOwnNick = function( this )

		  if not this:isPartial() then

			 return this._myNick

		  end

		  DC():PrintDebug( "[" .. this:getUrl() .."] Your scripts are failing. "..

				   "Own nick not set. Reconnect please." )

	   end


	   hub.destroy = function( this )

	   end


	   hub.sendChat = function( this, msg )

		  local ownNick = this:getOwnNick()

		  msg = dcu:NmdcEscape( msg )

		  if ownNick then

			 DC():SendHubMessage( this:getId(), "<"..ownNick.."> "..msg.."|" )

		  end

	   end


	   hub.injectChat = function( this, msg, skipusercommand )

			 DC():InjectHubMessage( this:getId(), msg )

			 -- test if it's usercommand

			 if ( string.sub(msg, 1, 13) == "$UserCommand " ) and (not skipusercommand) then

				this:customUC( msg )

			 end

	   end


	   hub.addLine = function( this, msg, fmt )

		  if not fmt then

			 msg = "*** " .. msg

		  end

		  DC():InjectHubMessage( this:getId(), msg )

	   end


	   hub.sendPrivMsgTo = function( this, victim, msg, hideFromSelf )

		  local ownNick = this._myNick

		  msg = dcu:NmdcEscape( msg )

		  if ownNick then

			 DC():SendHubMessage( this:getId(), "$To: "..victim.." From: "..ownNick.." $"..msg.."|" )

			 if not hideFromSelf then

				this:injectPrivMsg( victim, ownNick, msg )

			 end

		  end   

	   end


	   hub.injectPrivMsg = function( this, from, to, msg )

			 DC():InjectHubMessage( this:getId(), "$To: "..to.." From: "..from.." $"..msg )

	   end


	   hub.injectPrivMsgFmt = function( this, from, to, msg )

		  this:injectPrivMsg( from, to, "<"..from.."> "..msg )

	   end


	   hub.attention = function( this )

		  DC():HubWindowAttention( this:getId() )

	   end


	   --///////////////////////////

	   --// $UserCommand manager

	   --///////////////////////////

	   -- Todo: context sensitivitiy at UC 255


	   hub.hubUC = function( this, msg )

		  local uc_type = string.gsub( msg, "%$UserCommand (%d+) .+", "%1")

		  -- DC():PrintDebug( "UserCommand " .. uc_type .. " arrived from " .. this:getHubName() .. " : " .. msg)

		  if uc_type == "255" then

			 -- clear user command list and resend our own commands to prevent it from disappearing

			 -- DC():PrintDebug( "Clearing Hub UC list.." )

			 this:clearHubUCList()

			 -- DC():PrintDebug( "Resending Custom commands.." )

			 this:reSendCustomUC()

		  else

			 -- add usercommands to UClist

			 -- DC():PrintDebug( "Adding hubUC.." )

			 this:addHubUC( msg )

		  end


		  return true

	   end


	   hub.customUC = function ( this, msg )

		  local uc_type = string.gsub( msg, "%$UserCommand (%d+) .+", "%1")

		  -- DC():PrintDebug( "UserCommand " .. uc_type .. " arrived from a script: " .. msg)

		  if uc_type == "255" then

			 -- clear own user command list and resend hub usercommands to prevent it from disappearing

			 this:clearCustomUCList()

			 this:reSendHubUC()

		  else

			 -- add usercommands to UClist

			 this:addCustomUC( msg )

		  end

		  return true

	   end


	   hub.addHubUC = function( this, msg )

		  table.insert( this._hubUC, msg )

		  return true

	   end


	   hub.addCustomUC = function( this, msg)

		  table.insert( this._customUC, msg )

		  return true

	   end


	   hub.clearHubUCList = function( this )

		  this._hubUC = {}

		  return true

	   end


	   hub.clearCustomUCList = function( this )

		  this._customUC = {}

		  return true

	   end


	   hub.reSendCustomUC = function( this )

		  for k in pairs(this._customUC) do

			 hub:injectChat( this._customUC[k] , true )

			 -- DC():PrintDebug("Sending custom uc from stored table: " .. this._customUC[k] )

		  end

		  return true

	   end


	   hub.reSendHubUC = function( this )

		  for k in pairs(this._hubUC) do

			 hub:injectChat( this._hubUC[k] , true)

		  end

		  return true

	   end


	   --////////////////

	   --// Own functions

	   --////////////////


	   hub.onRaw = function( this, msg )

		  return scriptMan:Run( "raw", this, msg )

	   end


	   hub.onSearch = function( this, msg )

		  --DC():PrintDebug( this:getHubName().."> "..msg )

	   end


	   hub.onHello = function( this, user, msg )

	   end


	   hub.onMyInfo = function( this, user, msg )

		  return scriptMan:Run( "userMyInfo", this, user, msg )

	   end


	   hub.onQuit = function( this, nick, msg )

		  return scriptMan:Run( "userQuit", this, nick )

	   end


	   hub.onHubName = function( this, hubname, msg )

	   end


	   hub.onPrivateMessage = function( this, user, to, prefix, text, full )

		  if to == this:getOwnNick() then

			 if prefix == "<"..user:getNick().."> " then

				return scriptMan:Run( "pm", this, user, text )

			 else

				return scriptMan:Run( "hubPm", this, user, text )

			 end   

		  end

	   end


	   hub.onChatMessage = function( this, user, text )

		  return scriptMan:Run( "chat", this, user, text ) or scriptMan:Run( "ChatArrival", this, user, text )

	   end


	   hub.onUnknownChatMessage = function( this, text )

		  return scriptMan:Run( "unknownchat", this, text )

	   end


	   hub.onChatFromSelf = function( this, text )

		  return scriptMan:Run( "ownChat", this, text )

	   end   


	   return hub

	end




	--/////////////////////////////////////

	--// User object

	--/////////////////////////////////////


	function createNmdcUser( hub, nick )

	   local user = {}


	   user._hub = hub

	   user._nick = nick

	   user._op = false

	   user._ip = ""

	   user._class = "user"

	   user._handled_messages = {} -- flood protection

	   setmetatable( user, {__index = {

		  sNick = user._nick,

		  bOperator = function() return user._op end,

		  sIP = function() return user._ip end,

		  }

	   })

	   user.getProtocol = function( this )

		  return "nmdc"

	   end


	   user.setOp = function( this, op )

		  this._op = op

		  return this

	   end


	   user.isOp = function( this )

		  return this._op

	   end


	   user.setClass = function( this, param )

		  this._class = param

		  return this

	   end


	   user.getClass = function( this )

		  return this._class

	   end


	   user.setIp = function( this, ip )

		  this._ip = ip

	   end


	   user.getIp = function( this )

		  return this._ip

	   end


	   user.getNick = function( this )

		  return this._nick

	   end


	   user.sendPrivMsgFmt = function( this, msg, hideFromSelf )

		  local ownNick = this._hub:getOwnNick()

		  if ownNick then

			 this._hub:sendPrivMsgTo( this._nick, "<"..ownNick.."> "..msg, hideFromSelf )

		  end

		  return this

	   end


	   user.setMsgHandled = function( this, which )

		  this._handled_messages[which] = 1

		  return this

	   end


	   user.msgHandled = function( this, which )

		  return this._handled_messages[which]

	   end


	   return user

	end


	function createAdcUser( hub, sid )

	   local user = {}


	   user._sid = sid

	   user._cid = ""

	   user._hub = hub

	   user._nick = ""

	   user._op = false

	   user._bot = false

	   user._registered = false

	   user._hubitself = false

	   user._class = "user"

	   user._ip = ""

	   user._handled_messages = {} -- flood protection


	   user.getProtocol = function( this )

		  return "adc"

	   end


	   user.setOp = function( this, op )

		  this._op = op

		  return this

	   end


	   user.isOp = function( this )

		  return this._op

	   end


	   user.processCt = function( this, param )

		  local num = tonumber(param)

		  if num then


			 --// Init

			 this._class = "user"


			 --// 2^0: bot

			 if dcu:BBit(num, 0) then

				this:setBot(true)

				DC():PrintDebug("BOT set: " .. this:getSid())

			 else

				this:setBot(false)

			 end


			 --// 2^1: registered

			 if dcu:BBit(num, 1) then

				this:setReg(true)

			 else

				this:setReg(false)

			 end


			 --// 2^2, 2^3, 2^4: some type of operator

			 if dcu:BBit(num, 2) or dcu:BBit(num, 3) or dcu:BBit(num, 4) then

				this:setOp(true)

				if dcu:BBit(num, 2) then

				   this._class = "op"

				elseif dcu:BBit(num, 3) then

				   this._class = "su"

				else

				   this._class = "owner"

				end

			 else

				this:setOp(false)

			 end


			 if dcu:BBit(num, 5) then

				this:setHub(true)

				this._class = "hub"

			 else

				this:setHub(false)

			 end


		  else

			 --// Empty CT field should cause all properties gone

			 this:setBot(false)

			 this:setOp(false)

			 this:setReg(false)

			 this:setHub(false)

			 this._class = "user"

		  end


		  DC():PrintDebug("CLASS: " .. this._class .. " [" .. tostring(param) .. "]" )

		  return this

	   end


	   --// Possible values: "user", "op", "su", "owner", "hub"

	   user.getClass = function( this )

		  return this._class

	   end


	   user.setBot = function(this, bot)

		  this._bot = bot

		  return this

	   end


	   user.isBot = function(this)

		  return this._bot

	   end


	   user.setReg = function(this, registered)

		  this._registered = registered

		  return this

	   end


	   user.isReg = function(this)

		  return this._registered

	   end


	   user.setHub = function(this, hubitself)

		  this._hubitself = hubitself

		  return this

	   end


	   user.isHub = function(this)

		  return this._hubitself

	   end


	   user.setIp = function( this, ip )

		  this._ip = ip

	   end


	   user.getIp = function( this )

		  return this._ip

	   end


	   user.setCid = function( this, cid )

		  this._cid = cid

	   end


	   user.getCid = function( this )

		  return this._cid

	   end


	   user.getSid = function( this )

		  return this._sid

	   end


	   user.getNick = function( this )

		  return this._nick

	   end


	   user.setNick = function( this, nick )

		  this._nick = nick

		  -- DC():PrintDebug("Nick set: " .. nick )

	   end


	   user.sendPrivMsg = function( this, msg, hideFromSelf )

		  local victimSid = this:getSid()

		  this._hub:sendPrivMsgTo( victimSid, msg, hideFromSelf )

		  return this

	   end


	   -- Backward compatibility

	   user.sendPrivMsgFmt = user.sendPrivMsg


	   user.setMsgHandled = function( this, which )

		  this._handled_messages[which] = 1

		  return this

	   end


	   user.msgHandled = function( this, which )

		  return this._handled_messages[which]

	   end


	   return user

	end



	--/////////////////////////////////////

	--// Handlers

	--/////////////////////////////////////


	nmdch = {}


	function nmdch.DataArrival( hub, msg )

	   local h = dcpp:getHub( hub )


	   --// If we missed the logon, we really have no business here,

	   --// modify only if you really have to.

	   --// Note that if not h:isPartial and not h:getOwnNick(),

	   --// functions requiring an ownNick will silently fail.

	   if h:isPartial() then

		  return

	   end


	   --// raw/unparsed message

	   if h:onRaw( msg ) then

		  return scriptMan:Run( "UnknownArrival", msg )

	   end


	   --// parse message and fire appropriate

	   local ret,c,cmd = string.find( msg, "^%$([^ ]+)" )

	   if ret then

		  if cmd == "Search" then

			 return h:onSearch( msg )

		  elseif cmd == "Hello" then

			 local nick = string.sub( msg, 8 )

			 if not h:getOwnNick() then

				h:setOwnNick( nick ) -- don't trust this nick on h:isPartial()

			 end

			 return h:onHello( h:getUser( nick ), msg )

		  elseif cmd == "MyINFO" and string.sub( msg, 1, 13 ) == "$MyINFO $ALL " then

			 local nick = string.sub( msg, 14, string.find( msg, " ", 14, 1 ) - 1 )

			 return h:onMyInfo( h:getUser( nick ), msg )

		  elseif cmd == "Quit" then

			 local nick = string.sub( msg, 7 )

			 h:removeUser( nick )

			 return h:onQuit( nick, msg )

		  elseif cmd == "HubName" then

			 local hubname = string.sub( msg, 10 )

			 h:setHubName( hubname )

			 return h:onHubName( hubname, msg )

		  elseif cmd == "OpList" then

			 for nick in string.gfind( string.sub( msg, 9 ), "[^$]+") do

				h:getUser( nick, 1 )

			 end

			 return nil

		  elseif cmd == "UserIP" then

			 local nick,ip

			 for combo in string.gfind( string.sub( msg, 9 ), "[^$]+") do

				ret,c,nick,ip = string.find( combo, "^(%S+) (%S+)$" )

				if ret then

				   h:getUser( nick ):setIp( ip )

				end

			 end

			 return nil

		  elseif cmd == "UserCommand" then

			 h:hubUC( msg )

		  --elseif string.sub( msg, 1, 10 ) == "$NickList " then

		  --   for nick in string.gfind( string.sub( msg, 9, -1), "[^$]+") do

		  --	  h:getUser( nick )

		  --   end

		  --   return nil

		  elseif cmd == "To:" then

			 local ret,c,to,from,fulltext = string.find( msg, "^%$To: ([^ ]+) From: ([^ ]+) %$(.*)$" )

			 if ret then

				local ret,c,prefix,text = string.find( fulltext, "^(%b<> )(.*)$" )

				if ret then

				   return h:onPrivateMessage( h:getUser( from ), to, prefix, text, msg )

				else

				   return h:onPrivateMessage( h:getUser( from ), to, nil, fulltext, msg )

				end

			 end

		  end

	   elseif string.sub( msg, 1, 1 ) == "<" then

		  local ret,c,nick,text = string.find( msg, "^<([^>]+)> (.*)$" )

		  if ret and h:getOwnNick() then

			 if nick ~= h:getOwnNick() then -- don't be flooding mainchat now..

				return h:onChatMessage( h:getUser( nick ), text )

			 else

				return h:onChatFromSelf( text )

			 end

		  end

	   elseif msg ~= "" then

		  return h:onUnknownChatMessage(msg)

	   end

	end


	function dcpp.UserDataIn( user, msg )

	   return scriptMan:Run( "clientIn", user, msg )

	end


	function dcpp.UserDataOut( user, msg )

	   return scriptMan:Run( "clientOut", user, msg )

	end


	function dcpp.OnCommandEnter( hub, text )

	   local h = dcpp:getHub( hub )

	   return scriptMan:Run( "ownChatOut", h, text )

	end


	function dcpp.OnTimer()

	   -- Called every second.

	   return scriptMan:Run( "timer" )

	end


	function nmdch.OnHubAdded( hub )

	   dcpp:addHub( hub, false )

	end


	function nmdch.OnHubRemoved( hub )

	   dcpp:removeHub( hub )

	end


	adch = {}


	function adch.DataArrival( hub, msg )

	   if msg == "" then

		  return nil

	   end

	   local h = dcpp:getHub( hub )


	   local params = {}

	   string.gsub(msg, "([^ ]+)", function(s) table.insert(params, s) end )


	   local mtype = string.sub(params[1], 1, 1)

	   local cmd = string.sub(params[1], 2, 4)

	   local sid, targetSid, parameters = false, false, ""


	   if mtype == "I" then

		  parameters = string.sub( msg, 6)

		  sid = "HUB9"

	   elseif mtype == "B" then

		  parameters = string.sub( msg, 11)

		  sid = params[2]

	   elseif mtype == "D" or mtype == "E" then

		  parameters = string.sub( msg, 16 )

		  sid = params[2]

		  targetSid = params[3]

	   end


	   -- Building flags table

	   local flags = {}

	   string.gsub(parameters, "([^ ]+)", function(s) flags[string.sub(s, 1, 2)] = dcu:AdcEscape( string.sub(s, 3), true ) end )


	   if cmd == "SID" then

		  DC():PrintDebug( "[STATUS] SID received: " .. params[2] )

		  h._mySID = params[2]

	   elseif cmd == "QUI" then

		  h:removeUser( params[2] )

		  h:onQUI( params[2], flags )

	   elseif cmd == "INF" then

		  local u = h:getUser( sid, parameters )

		  return h:onINF( u, flags )

	   elseif cmd == "MSG" then

		  local pm, replySid, me_msg = false, false, false

		  local tmp = {}


		  string.gsub(parameters, "([^ ]+)", function(s) table.insert(tmp, s) end )

		  local text = dcu:AdcEscape(tmp[1], true)

		  tmp[1] = nil


		  -- Check for named parameters

		  for k in pairs(tmp) do

			 local name = string.sub(tmp[k], 1,2)

			 local value = string.sub(tmp[k], 3)

			 if name == "ME" then

				if value == "1" then

				   me_msg = true

				end

			 elseif name == "PM" then

				pm = true

				replySid = value

			 end

		  end


		  if pm then

			 return h:onPrivateMessage( h:getUser( sid ), targetSid, replySid, text, me_msg )

		  else

			 if sid ~= h:getOwnSid() then -- don't be flooding mainchat now..

				return h:onChatMessage( h:getUser( sid ), text, me_msg )

			 else

				return h:onChatFromSelf( text, me_msg )

			 end

		  end


	   end

	end


	function adch.OnHubAdded( hub )

	   dcpp:addHub( hub, true )

	end


	function adch.OnHubRemoved( hub )

	   dcpp:removeHub( hub )

	end



	--/////////////////////////////////////

	--// Utility functions

	--/////////////////////////////////////


	function SendActiveSearchResult( hub, ip_port, search_nick, filename, filesize, open_slots, total_slots )

	   DC():SendUDP( ip_port, "$SR "..search_nick.." "..filename.."\005".. filesize.." "..open_slots..

		  "/"..total_slots.."\005"..dcpp:getHub( hub ):getHubName() ) -- no pipe in UDP $SR

	end




	--/////////////////////////////////////

	--// Start Lua Manager

	--/////////////////////////////////////


	local fnc, err = loadfile( DC():GetAppPath().."scripts\\libsimplepickle.lua" )

	if fnc then

	   fnc()

	   fnc = nil

	else

	   DC():PrintDebug( " LUA ERROR: "..err)

	   pickle = { store = function() end }

	end


	scriptMan = {}


	scriptMan.Init = function( filename )

	   dcpp._listeners = { id = {} }

	   scriptMan.script = {}

	   setmetatable( scriptMan.script, { __index = {

		  load = function( this, filename )

			 local ret

			 if scriptMan.script:getid( filename ) then

				scriptMan.script:unload( filename )

				ret = "successfully reloaded."

			 else

				ret = "successfully loaded."

			 end

			 local i = #dcpp._listeners.id +1

			 local func, err = loadfile( DC():GetAppPath().."scripts\\"..filename )

			 if not func then return nil, err end

			 -- load into a new environment

			 dcpp._listeners[i] = {}

			 setmetatable( dcpp._listeners[i], { __index = _G } )

			 setfenv( func, dcpp._listeners[i] )

			 func()


			 dcpp._listeners.id[i] = filename

			 -- change status flag if exists

			 local known = false

			 for i in ipairs(scriptlist) do

				if scriptlist[i][1] == filename then

				   scriptlist[i][2] = 1

				   known = true

				   break

				end

			 end

			 -- insert if it's new

			 if not known then table.insert( scriptlist, { filename, 1 } ) end

			 scriptMan.script:save()

			 return ret

		  end,

		  remove = function( this, filename )

			 local id = scriptMan.script:getid( filename )

			 if id then

				table.remove( dcpp._listeners.id, id ) -- remove its id

				table.remove( dcpp._listeners, id ) -- remove its environment

				collectgarbage("collect")

			 end

			 -- remove from scriptlist

			 for i in ipairs(scriptlist) do

				if scriptlist[i][1] == filename then

				   table.remove( scriptlist, i )

				   scriptMan.script:save()

				   return "removed."

				end

			 end

			 return "not found."

		  end,

		  unload = function( this, filename )

			 local id = scriptMan.script:getid( filename )

			 if id then

				table.remove( dcpp._listeners.id, id ) -- remove its id

				table.remove( dcpp._listeners, id ) -- remove its environment

				collectgarbage("collect")

			 end

			 -- change status flag to 0 (inactive)

			 for i in ipairs(scriptlist) do

				if scriptlist[i][1] == filename then

				   scriptlist[i][2] = 0

				   scriptMan.script:save()

				   return "unloaded."

				end

			 end

			 return "not found"

		  end,

		  getid = function( this, filename )

			 for id, name in pairs( dcpp._listeners.id ) do

				if name == filename then

				   return id

				end

			 end

			 return nil

		  end,

		  save = function( this )

			 pickle.store( DC():GetAppPath().."scripts\\scriptlist.tbl", { scriptlist = scriptlist } )

		  end}

	   })

	   -- load scriptmanager first

	   dcpp._listeners.id[1] = "startup.lua"

	   dcpp._listeners[1] =  {

		  ownChatOut = function( hub, message )

			 if message:sub(1,1) ~= "/" then return nil end


			 local _,_, cmd, fname = message:find( "([^ ]+)[ ]*(.*)" )

			 if cmd == nil then

				return nil

			 elseif cmd == "/lualist" then

				local sc, a = {}, 0

				for i, n in ipairs( scriptlist ) do

				   if n[2] == 1 then a = a +1 end

				   table.insert( sc, ("[ ".. n[2] .." ] ".. n[1]) )

				end

				hub:addLine( "Scripts: (".. a .."/".. #sc ..")\r\nVersion: ".. _VERSION .."\r\n"..table.concat(sc, "\r\n").."\r\n" )

				return 1   

			 elseif cmd == "/luaload" then

				if fname ~= "startup.lua" then

				   local ret, err = scriptMan.script:load( DC():FromUtf8(fname) )

				   hub:addLine( (err and err or "Lua script '"..fname.."' "..ret) )

				else

				   hub:addLine( "ERROR: Use '/luafile startup.lua' if you really want to reload it." )

				end

					return 1

			 elseif  cmd == "/luareload" then

					if scriptMan.script:getid( DC():FromUtf8(fname) ) then

					   local ret, err = scriptMan.script:load( DC():FromUtf8(fname) )

				   hub:addLine( (err and err or "Lua script '"..fname.."' "..ret) )

					else

					   hub:addLine( "ERROR: Lua script '"..fname.."' is not running." )

					end

					return 1

			 elseif cmd == "/luaunload" then

				if fname ~= "startup.lua" then

				   local ret = scriptMan.script:unload( DC():FromUtf8(fname) )

				   hub:addLine( "Lua script '"..fname.."' "..ret )

				else

				   hub:addLine( "ERROR: Use '/luafile startup.lua' if you really want to reload it." )

				end

				return 1

			 elseif cmd == "/luaremove" then

				if fname ~= "startup.lua" then

				   local ret = scriptMan.script:remove( DC():FromUtf8(fname) )

				   hub:addLine( "Lua script '"..fname.."' "..ret )

				else

				   hub:addLine( "ERROR: Use '/luafile startup.lua' if you really want to reload it." )

				end

				return 1

			 elseif cmd == "/meminfo" then

				collectgarbage("collect")

				local mem = collectgarbage("count")

				local t, i = { "KiB", "MiB", "GiB", "TiB" }, 1

				while mem >= 1024 and i < #t do mem = (mem / 1024); i = i+1 end

				hub:addLine( "Scripts are using ".. string.format("%.2f", mem ) .. " "..t[i].." of memory." )

				return 1

			 elseif cmd == "/help" then

				hub:addLine( "\r\n"..string.rep("-", 156).."\r\n   Script Manager\r\n"..string.rep("-", 156).."\r\n"..

				   "/lualist			   scriptlist\r\n"..

				   "/luaload <filename>			load <filename> script\r\n"..

				   "/luareload <filename>		 reload <filename> script\r\n"..

				   "/luaunload <filename>		 unload <filename> script\r\n"..

				   "/luaremove <filename>		 unload and/or remove <filename> from scriptlist\r\n"..

				   "/meminfo			   memory usage by scripts\r\n"..

				   "/luafile startup.lua			reload scripting interface" )

				return nil

			 end

		  end

	   }

	   setmetatable( dcpp._listeners[1], { __index = _G } )

	   setfenv( dcpp._listeners[1].ownChatOut, dcpp._listeners[1] )

	end   


	scriptMan.Run = function( this, fname, ... )

	   for i in ipairs( dcpp._listeners ) do

		  if type( dcpp._listeners[i][fname] ) == "function" then

			 local res, ret = pcall( dcpp._listeners[i][fname], ... )

			 if not res then

				DC():PrintDebug( " LUA ERROR: ("..dcpp._listeners.id[i]..": "..fname..") "..ret )

			 else

				if ret then return 1 end

			 end

		  end

	   end

	end


	scriptMan.Init()


	if not scriptlist then

	   local func = loadfile( DC():GetAppPath() .. "scripts\\scriptlist.tbl" )

	   if func then

		  func()

	   else

		  local f = io.open( DC():GetAppPath() .. "scripts\\scriptlist.tbl", "w+")

		  if f then f:close() end

	   end


	   if type(scriptlist) ~= "table" then

		  scriptlist = {}   -- [1] = {scriptname, active (1/0)}

		  scriptMan.script:save()

	   end

	end


	dofile = function( filename )

	   local fnc, err = loadfile( filename )

	   if fnc then

		  setfenv(fnc, getfenv(2))

		  fnc()

	   else

		  DC():PrintDebug( " LUA ERROR: "..err )

	   end

	end


	-- _always_ start formatting.lua

	scriptMan.script:load( "formatting.lua" )


	-- autostart last running scripts but (running) formatting.lua

	for i in ipairs( scriptlist ) do

	   if scriptlist[i][2] == 1 and scriptlist[i][1] ~= "formatting.lua" then

		  local res, err = scriptMan.script:load( scriptlist[i][1] )

		  if not res then

			 DC():PrintDebug( " "..err)

		  end

	   end

	end


	-- run timer

	DC():RunTimer(1)

Share this post


Link to post
Share on other sites

hey im just starting with lua.

can you explain how this startup makes it easier to handle scripts?

Share this post


Link to post
Share on other sites

Well you dont have to edit lua startup script to add files it has a manager that allows you to enter new lua script thru the client

------------------------------------------------------------------------------------------------------------------------------------------------------------

   Script Manager

------------------------------------------------------------------------------------------------------------------------------------------------------------

/lualist			   scriptlist

/luaload <filename>			load <filename> script

/luareload <filename>		 reload <filename> script

/luaunload <filename>		 unload <filename> script

/luaremove <filename>		 unload and/or remove <filename> from scriptlist

/meminfo			   memory usage by scripts

/luafile startup.lua			reload scripting interface
[09-03-15][14:40:44] <Somehub> Scripts: (3/3)

Version: Lua 5.1

- [ 1 ] ctm_detect.lua

- [ 1 ] formatting.lua

- [ 1 ] findnick.lua

Edited by Toast

Share this post


Link to post
Share on other sites

+1 vote to include this starter to later Apex versions.

But, there is one thing, it's need to be included the scriptlist.tbl fle witch contain the default scripts...

Share this post


Link to post
Share on other sites

+1 vote to include this starter to later Apex versions.

But, there is one thing, it's need to be included the scriptlist.tbl fle witch contain the default scripts...

that should be enabled by the user themselfs what script they wanna run first time i tried apex lua all scripts where enabled and it wrecked havoc in the hub i was in so im good with 0 script in startup

Share this post


Link to post
Share on other sites

that should be enabled by the user themselfs what script they wanna run first time i tried apex lua all scripts where enabled and it wrecked havoc in the hub i was in so im good with 0 script in startup

I recommand minimum 1 script to be loaded in first time, without this, the users will have some difficulties. E.q uptime.lua is ideal for this.

Share this post


Link to post
Share on other sites

link to the above was dead so have attached a copy of libsimplepickle.lua. also added a copy of startup.lua will just need to change the extension from txt to lua

libsimplepickle.txt

Startup.txt

Share this post


Link to post
Share on other sites

I have apex v.1.3.4, luaplugin v.2.02 how do I load these lua scripts above in the apex. I copied'em in the main directory of the apex, but no success

Thank you!

Share this post


Link to post
Share on other sites

I figure out, no where says that we must create a directory scripts and there put the lua scripts.

Please, make a pinned topic to inform people about this.

Share this post


Link to post
Share on other sites
Sign in to follow this  
Followers 0