Jump to content


startup.lua


  • Please log in to reply
8 replies to this topic

#1 Guest_Toast_*

Guest_Toast_*
  • Guest

Posted 07 March 2009 - 12:53 PM

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)


#2 jck

jck

    Member

  • Member
  • PipPip
  • 24 posts

Posted 15 March 2009 - 10:19 AM

hey im just starting with lua.
can you explain how this startup makes it easier to handle scripts?

#3 Guest_Toast_*

Guest_Toast_*
  • Guest

Posted 15 March 2009 - 01:40 PM

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, 15 March 2009 - 01:42 PM.


#4 Patch

Patch

    Member

  • Member
  • PipPip
  • 47 posts

Posted 15 March 2009 - 07:07 PM

+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...

#5 Guest_Toast_*

Guest_Toast_*
  • Guest

Posted 15 March 2009 - 08:51 PM

View PostPatch, on Mar 15 2009, 08:07 PM, said:

+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

#6 Patch

Patch

    Member

  • Member
  • PipPip
  • 47 posts

Posted 16 March 2009 - 08:42 AM

View PostToast, on Mar 15 2009, 09:51 PM, said:

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.

#7 balder

balder

    AKA [Linux-Admin]Cheers

  • Support
  • 534 posts

Posted 12 June 2010 - 05:39 PM

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

Attached Files



#8 Dreamlander

Dreamlander

    Newbie

  • Member
  • Pip
  • 7 posts

Posted 05 July 2010 - 07:53 AM

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!

#9 Dreamlander

Dreamlander

    Newbie

  • Member
  • Pip
  • 7 posts

Posted 06 July 2010 - 09:50 AM

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.


1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users