Ah, wrong script actually. That's 6 months old or something I think? I'll repost the code here. The only bug I've noticed is that with certain packet lengths, the packet leftovers don't appear to be caught correctly. Happens quite rarely though, and I haven't been able to track it down. You can see the authentication function down there as well.
atcp = {}
--code adapted from Ked's ATCP script, at:
--<http://www.freewebs.com/keldar/atcp.htm>
atcp.IAC = '\255'
atcp.WILL = '\251'
atcp.WONT = '\252'
atcp.ATCP = '\200'
atcp.IAC_SE = '\255\240'
atcp.IAC_SB_ATCP = '\255\250\200'
atcp.IAC_WILL_ATCP = '\255\251\200'
atcp.IAC_WONT_ATCP = '\255\252\200'
atcp.IAC_DO_ATCP = '\255\253\200'
atcp.IAC_DONT_ATCP = '\255\254\200'
atcp.IAC_WILL_COMPRESS2 = '\255\251\086'
atcp.on = false
atcp.lo_reg = rex.new('(\255(\250(\200[^\255]*)?)?)$')
atcp.gag_reg1 = rex.new('^(\027[[0-9;]+m)*?\r\n.')
atcp.gag_reg2 = rex.new('\255\239(\r\n).')
atcp.leftovers = false
atcp.values = {}
atcp.options = {
{name='auth', value='1'},
{name='composer', value='1'},
{name='char_name', value='1'},
{name='topvote', value='1'},
{name='char_vitals', value='1'},
{name='room_brief', value='1'},
{name='room_exits', value='1'}
}
--mediapak
--wiz
--filestore
--keepalive
--ATCP FUNCTIONS
function atcp.init()
world.SendPkt(atcp.IAC_DO_ATCP)
local msg = 'hello ' .. (config.atcp.id or VERSION_NAME)
for _,option in ipairs(atcp.options) do
msg = msg .. '\010' .. option.name .. ' ' .. option.value
end
if(#config.atcp.login > 0 and #config.atcp.password > 0) then
msg = msg .. atcp.IAC_SE .. atcp.IAC_SB_ATCP .. 'login ' .. config.atcp.login .. ' ' .. config.atcp.password
end
world.SendPkt(atcp.IAC_SB_ATCP .. msg .. atcp.IAC_SE)
end
function atcp.close()
world.SendPkt(atcp.IAC_DONT_ATCP)
end
function atcp.authenticate(seed)
local a = 17
for i=0,#seed - 1 do
if(math.fmod(i,2) == 0) then
a = a + (string.byte(seed,i + 1) - 96) * (bit.bor(i,13))
else
a = a - (string.byte(seed,i + 1) - 96) * (bit.bor(i,11))
end
end
return a
end
function atcp.retrieve_info(msg,capture)
local ar = {}
local d1 = string.find(msg,' ',0,true) or -2
local d2 = string.find(msg,'\010',0,true) or d1 + 1
if(d2 == -1) then
capture[msg] = {}
atcp.values[msg] = {}
return capture
elseif(d1 < 0) then
d1 = d2 + 1
end
local d
if(d1 < d2) then
ar = utils.split(msg,' ',2)
d = d1
else
ar = utils.split(msg,'\010',2)
d = d2
end
local name = string.sub(msg,0,d - 1)
capture[name] = utils.split(string.sub(msg,d + 1),'\010')
atcp.values[name] = capture[name]
return capture
end
function atcp.list()
system.Note('ATCP VALUES')
for name,value in pairs(atcp.values) do
world.Note(' ' .. name)
for _,val in ipairs(value) do
world.Note(' ' .. val)
end
end
end
--PARSE FUNCTION
function atcp.parse(packet)
local parsed = {}
if(atcp.leftovers) then
packet = atcp.leftovers .. packet
atcp.leftovers = false
end
--disable mccp
if(config.atcp.use) then
packet = string.gsub(packet, atcp.IAC_WILL_COMPRESS2, '')
end
packet = string.gsub(packet, '' .. atcp.IAC_SB_ATCP .. '(.-)' .. atcp.IAC_SE,
function(msg)
if(config.atcp.use) then
atcp.on = true
parsed = atcp.retrieve_info(msg,parsed)
end
return ''
end)
packet = string.gsub(packet, atcp.IAC .. '(.)' .. atcp.ATCP,
function(code)
if(code == atcp.WILL) then
if(config.atcp.use) then
atcp.on = true
atcp.init()
if(CTRL_DEBUG) then
system.DebugNote('ATCP PROTOCOL ON.')
end
end
return ''
elseif(code == atcp.WONT) then
if(config.atcp.use) then
atcp.on = false
atcp.close()
if(CTRL_DEBUG) then
system.DebugNote('ATCP PROTOCOL OFF.')
end
end
return ''
end
return nil
end)
local start,_,matches = atcp.lo_reg:match(packet)
if(matches) then
atcp.leftovers = matches[1]
packet = string.sub(packet,1,start)
end
return packet,parsed
end
--PLUGIN CALLBACKS
function OnPluginPacketReceived(packet)
local packet,parsed = atcp.parse(packet)
if(not config.atcp.use) then
return packet
end
if(parsed['Auth.Request']) then
if(parsed['Auth.Request'][1] == 'CH') then
world.SendPkt(atcp.IAC_SB_ATCP .. 'auth ' .. atcp.authenticate(parsed['Auth.Request'][2]) .. ' ' .. config.atcp.id .. atcp.IAC_SE)
if(CTRL_DEBUG) then
system.DebugNote('ATCP AUTHORIZATION SENT.')
end
elseif(parsed['Auth.Request'][1] == 'OFF') then
system.WarningNote('ATCP AUTHORIZATION FAILED.')
elseif(parsed['Auth.Request'][1] == 'ON') then
if(CTRL_DEBUG) then
system.DebugNote('ATCP AUTHORIZATION ACCEPTED.')
end
end
end
if(parsed['Char.Name']) then
if(not parsed['Char.Name'][1] == config.basic.name) then
system.WarningNote('CORRECTING CHAR NAME TO "' .. string.upper(parsed['Char.Name'][1]) .. '".')
world.SetVariable('CharName',parsed['Char.Name'][1])
end
config.basic.name = parsed['Char.Name'][1]
config.basic.title = parsed['Char.Name'][2]
end
if(parsed['Char.Vitals']) then
character.health.max, character.mana.max, character.endurance.max, character.willpower.max, character.experience = string.match(parsed['Char.Vitals'][1],'^H:%d-/(%d-) M:%d-/(%d-) E:%d-/(%d-) W:%d-/(%d-) NL:(%d-)/%d-')
end
if(parsed['Client.VoteReminder']) then
prompt.vote_reminder()
end
if(parsed['Client.Goodbye']) then
system.Note(parsed['Client.Goodbye'][1])
end
--'Auth.Request'
--'Char.Name'
--'Char.Vitals'
--'Client.Compose'
--'Client.GoodBye'
--'Client.JavaEnv'
--'Client.VoteReminder'
--'Room.Exits'
--'Room.Brief'
return packet
end
|