Skip to content

Commit 25a1bd0

Browse files
committed
Plugin to handle ATCP messages
1 parent 751895e commit 25a1bd0

File tree

1 file changed

+203
-0
lines changed

1 file changed

+203
-0
lines changed

plugins/ATCP_NJG.xml

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
<?xml version="1.0" encoding="iso-8859-1"?>
2+
<!DOCTYPE muclient>
3+
4+
<muclient>
5+
<plugin
6+
name="ATCP_NJG"
7+
author="Nick Gammon"
8+
id="85f72d0e263d75df7bde6f00"
9+
language="Lua"
10+
purpose="Nick Gammon's ATCP plugin"
11+
date_written="2010-03-09 10:04:32"
12+
requires="4.50"
13+
version="1.0"
14+
>
15+
<description trim="y">
16+
<![CDATA[
17+
Install into IRE games to catch ATCP messages.
18+
19+
Other plugins can detect ATCP messages like this:
20+
21+
function OnPluginBroadcast (msg, id, name, text)
22+
if id == "85f72d0e263d75df7bde6f00" then
23+
24+
if msg == 1 then
25+
do_ATCP_vitals (text) -- eg. "H:496/496 M:412/412 E:1380/1380 W:960/960 NL:89/100 "
26+
-- health mana endurance willpower experience
27+
elseif msg == 2 then
28+
do_ATCP_room_brief (text) -- eg. "Continuing on the Parade of Zarathustra"
29+
elseif msg == 3 then
30+
do_ATCP_room_exit (text) -- eg. "n,s"
31+
elseif msg == 4 then
32+
do_ATCP_room_number (text) -- eg. "401"
33+
elseif msg == 5 then
34+
do_ATCP_room_full_exits (text) -- eg. "ne(8564),w(8428)"
35+
elseif msg == 6 then
36+
do_ATCP_room_environment (text) -- eg. "Urban"
37+
elseif msg == 7 then
38+
do_ATCP_room_coordinates (text) -- eg. "38,3,1,0"
39+
elseif msg == 8 then
40+
do_ATCP_room_info (text) -- eg. "shop,postoffice"
41+
end -- if
42+
43+
end -- if ATCP message
44+
end
45+
46+
]]>
47+
</description>
48+
49+
</plugin>
50+
51+
52+
<!-- Script -->
53+
54+
55+
<script>
56+
<![CDATA[
57+
58+
local CLIENT_ID = "MUSHclient " .. Version ()
59+
local IAC, SB, SE, DO = 0xFF, 0xFA, 0xF0, 0xFD
60+
local ATCP = 200
61+
62+
63+
-- agree to use ATCP
64+
function OnPluginTelnetRequest (type, data)
65+
66+
if type == ATCP and data == "WILL" then
67+
return true
68+
end -- if
69+
70+
if type == ATCP and data == "SENT_DO" then
71+
Note ("Enabling ATCP.")
72+
SendPkt (string.char (IAC, SB, ATCP) ..
73+
"hello " .. CLIENT_ID .. "\n" ..
74+
"auth 1\n" ..
75+
"char_name 1\n" ..
76+
"char_vitals 1\n" ..
77+
"room_brief 1\n" ..
78+
"room_exits 1" ..
79+
string.char (IAC, SE))
80+
return true
81+
end -- if ATCP login needed (just sent DO)
82+
83+
return false
84+
85+
end -- function OnPluginTelnetRequest
86+
87+
-- we got authorization request, eg.
88+
-- Auth.Request CH\n<identstr>
89+
-- Auth.Request ON
90+
91+
function got_auth_request (s)
92+
93+
-- calculate challenge response
94+
local function atcp_auth (seed)
95+
local a = 17
96+
local i = 0
97+
local n
98+
99+
for letter in string.gmatch (seed, ".") do
100+
n = string.byte (letter) - 96
101+
if bit.band (i, 1) == 0 then -- even/odd?
102+
a = a + n * bit.bor (i, 13)
103+
else
104+
a = a - n * bit.bor (i, 11)
105+
end -- if
106+
i = i + 1
107+
end -- for
108+
return a
109+
end
110+
111+
if s:upper () == "ON" then
112+
Note ("ATCP authorization accepted.")
113+
return
114+
end -- if
115+
116+
local identstr = string.match (s, "^CH\n(.+)$")
117+
118+
if identstr then
119+
SendPkt (string.char (IAC, SB, ATCP) ..
120+
"auth " ..
121+
tostring (atcp_auth (identstr)) ..
122+
" " .. CLIENT_ID ..
123+
string.char (IAC, SE))
124+
return
125+
end -- if
126+
127+
end -- got_auth_request
128+
129+
130+
function got_vitals (s) -- eg. "H:496/496 M:412/412 E:1380/1380 W:960/960 NL:89/100"
131+
BroadcastPlugin (1, s)
132+
end -- got_vitals
133+
134+
function got_room_brief (s) -- eg. "Continuing on the Parade of Zarathustra"
135+
BroadcastPlugin (2, s)
136+
end -- got_room_brief
137+
138+
function got_room_exits (s) -- eg. "n,s"
139+
BroadcastPlugin (3, s)
140+
end -- got_room_exits
141+
142+
function got_room_number (s) -- eg. "441"
143+
BroadcastPlugin (4, s)
144+
end -- got_room_number
145+
146+
function got_full_exits (s) -- eg. "ne(8564),w(8428)"
147+
BroadcastPlugin (5, s)
148+
end -- got_full_exits
149+
150+
function got_environment (s) -- eg. "Urban"
151+
BroadcastPlugin (6, s)
152+
end -- got_environment
153+
154+
function got_coordinates (s) -- eg. "38,3,1,0" (area,x,y,z)
155+
BroadcastPlugin (7, s)
156+
end -- got_coordinates
157+
158+
function got_info (s) -- eg. "shop,postoffice"
159+
BroadcastPlugin (8, s)
160+
end -- got_info
161+
162+
handlers = {
163+
['Auth.Request'] = got_auth_request, -- handled here
164+
165+
['Room.Num'] = got_room_number,
166+
['Room.Brief'] = got_room_brief,
167+
['Room.Exits'] = got_room_exits,
168+
['Char.Vitals'] = got_vitals,
169+
['Room.FullExits'] = got_full_exits,
170+
['Room.Environment'] = got_environment,
171+
['Room.Coordinates'] = got_coordinates,
172+
['Room.Info'] = got_info,
173+
174+
175+
} -- end handlers
176+
177+
function OnPluginTelnetSubnegotiation (type, option)
178+
179+
if type ~= ATCP then
180+
return
181+
end -- not Achaea subnegotiation
182+
183+
local command, args = string.match (option, "^([%a.]+)%s+(.*)$")
184+
185+
if not command then
186+
return
187+
end -- don't seem to have a command
188+
189+
local f = handlers [command]
190+
191+
if f then
192+
f (args) -- call handler
193+
else
194+
BroadcastPlugin (0, option) -- other, just send whole message
195+
end -- handler
196+
197+
end -- function OnPluginTelnetSubnegotiation
198+
199+
]]>
200+
</script>
201+
202+
203+
</muclient>

0 commit comments

Comments
 (0)