trying to get wopr to work

This commit is contained in:
Neale Pickett 2013-02-07 16:28:34 -07:00
parent 37c755c261
commit e2d2aa699c
1 changed files with 378 additions and 377 deletions

View File

@ -6,81 +6,81 @@ POST_MAX = 512
method = os.getenv("REQUEST_METHOD")
if (method == "POST") then
local CL = tonumber(os.getenv("CONTENT_LENGTH")) or 0
if (CL > POST_MAX) then
CL = POST_MAX
end
function getc()
if (CL > 0) then
CL = CL - 1
return io.read(1)
else
return nil
end
end
local CL = tonumber(os.getenv("CONTENT_LENGTH")) or 0
if (CL > POST_MAX) then
CL = POST_MAX
end
function getc()
if (CL > 0) then
CL = CL - 1
return io.read(1)
else
return nil
end
end
elseif (method == "GET") then
local query = os.getenv("QUERY_STRING") or ""
local query_pos = 0
local query_len = string.len(query)
if (query_len > POST_MAX) then
query_len = POST_MAX
end
function getc()
if (query_pos < query_len) then
query_pos = query_pos + 1
return string.sub(query, query_pos, query_pos)
else
return nil
end
end
local query = os.getenv("QUERY_STRING") or ""
local query_pos = 0
local query_len = string.len(query)
if (query_len > POST_MAX) then
query_len = POST_MAX
end
function getc()
if (query_pos < query_len) then
query_pos = query_pos + 1
return string.sub(query, query_pos, query_pos)
else
return nil
end
end
else
print("405 Method not allowed")
print("Allow: GET POST")
print("Content-Type: text/plain")
print()
print("I only do GET and POST.")
os.exit(0)
print("405 Method not allowed")
print("Allow: GET POST")
print("Content-Type: text/plain")
print()
print("I only do GET and POST.")
os.exit(0)
end
function read_hex()
local a = getc() or 0
local b = getc() or 0
local a = getc() or 0
local b = getc() or 0
return string.char(tonumber(a, 16)*16 + tonumber(b, 16))
return string.char(tonumber(a, 16)*16 + tonumber(b, 16))
end
function cgi_item()
local val = ""
local val = ""
while (true) do
local c = getc()
if ((c == nil) or (c == "=") or (c == "&")) then
return val
elseif (c == "%") then
c = read_hex()
elseif (c == "+") then
c = " "
end
val = val .. c
end
while (true) do
local c = getc()
if ((c == nil) or (c == "=") or (c == "&")) then
return val
elseif (c == "%") then
c = read_hex()
elseif (c == "+") then
c = " "
end
val = val .. c
end
end
function escape(s)
s = string.gsub(s, "&", "&amp;")
s = string.gsub(s, "<", "&lt;")
s = string.gsub(s, ">", "&gt;")
return s
s = string.gsub(s, "&", "&amp;")
s = string.gsub(s, "<", "&lt;")
s = string.gsub(s, ">", "&gt;")
return s
end
f = {}
while (true) do
local key = cgi_item()
local val = cgi_item()
local key = cgi_item()
local val = cgi_item()
if (key == "") then
break
end
f[key] = val
if (key == "") then
break
end
f[key] = val
end
@ -88,35 +88,35 @@ end
-- lua doesn't seed its PRNG and provides nothing other than
-- time in seconds. If you're on Windows, go fish.
do
local seed = 0
r = io.open("/dev/urandom") or io.open("/dev/random")
for i = 1, 4 do
seed = seed*256 + string.byte(r:read(1))
end
io.close(r)
math.randomseed(seed)
local seed = 0
r = io.open("/dev/urandom") or io.open("/dev/random")
for i = 1, 4 do
seed = seed*256 + string.byte(r:read(1))
end
io.close(r)
math.randomseed(seed)
end
-- Get or create Session ID
sid = f["s"] or ""
if (sid == "") then
sid = string.format("%08x.%04x", os.time(), math.random(65535))
sid = string.format("%08x.%04x", os.time(), math.random(65535))
end
dirname = BASEDIR .. "/" .. sid
-- Send back a page
function reply(text, prompt, ...)
print("Content-type: text/xml")
print()
print("<document>")
print(" <sessionid>" .. sid .. "</sessionid>")
print(" <response>" .. escape(text or "") .. "</response>")
print(" <prompt>" .. escape(prompt or ">") .. "</prompt>")
if (arg[1]) then
print(" <error>" .. escape(arg[1]) .. "</error>")
end
print("</document>")
os.exit(0)
print("Content-type: text/xml")
print()
print("<document>")
print(" <sessionid>" .. sid .. "</sessionid>")
print(" <response>" .. escape(text or "") .. "</response>")
print(" <prompt>" .. escape(prompt or ">") .. "</prompt>")
if (arg[1]) then
print(" <error>" .. escape(arg[1]) .. "</error>")
end
print("</document>")
os.exit(0)
end
@ -127,32 +127,32 @@ end
--
function get(key, ...)
local fn = string.format("%s.%s", dirname, key)
local f = io.open(fn)
if (not f) then
return arg[1]
else
local ret = f:read(4000) or ""
f:close()
return ret
end
local fn = string.format("%s.%s", dirname, key)
local f = io.open(fn)
if (not f) then
return arg[1]
else
local ret = f:read(4000) or ""
f:close()
return ret
end
end
function set(key, ...)
local fn = string.format("%s.%s", dirname, key)
local f
local fn = string.format("%s.%s", dirname, key)
local f
f = io.open(fn, "w")
if not f then
error("Unable to write " .. fn)
end
f:write(arg[1] or "")
f:close()
f = io.open(fn, "w")
if not f then
error("Unable to write " .. fn)
end
f:write(arg[1] or "")
f:close()
end
function del(key)
local fn = string.format("%s.%s", dirname, key)
os.remove(fn)
local fn = string.format("%s.%s", dirname, key)
os.remove(fn)
end
@ -160,21 +160,21 @@ end
-- A string splitter
--
function string:split(...)
local sep = arg[1] or " "
local ret = {}
local start = 1
local sep = arg[1] or " "
local ret = {}
local start = 1
while true do
local first, last = self:find(sep, start)
if not first then
break
end
table.insert(ret, self:sub(start, first - 1))
start = last + 1
end
table.insert(ret, self:sub(start))
while true do
local first, last = self:find(sep, start)
if not first then
break
end
table.insert(ret, self:sub(start, first - 1))
start = last + 1
end
table.insert(ret, self:sub(start))
return ret
return ret
end
@ -190,124 +190,124 @@ hosts_by_name = {}
Host = {}
function Host:new(name, ...)
local o = {}
setmetatable(o, self)
self.__index = self
o.name = name
o.prompt = (arg[1] or ">")
o.obuf = {}
o.history = {}
local o = {}
setmetatable(o, self)
self.__index = self
o.name = name
o.prompt = (arg[1] or ">")
o.obuf = {}
o.history = {}
hosts_by_name[name] = o
return o
hosts_by_name[name] = o
return o
end
function Host:add_commands(t)
local cmds = {}
local k, v
local cmds = {}
local k, v
for k,v in pairs(self.commands) do
cmds[k] = v
end
for k,v in pairs(t) do
cmds[k] = v
end
self.commands = cmds
for k,v in pairs(self.commands) do
cmds[k] = v
end
for k,v in pairs(t) do
cmds[k] = v
end
self.commands = cmds
end
function Host:get(key, ...)
return get(self.name .. "." .. key, arg[1])
return get(self.name .. "." .. key, arg[1])
end
function Host:set(key, ...)
return set(self.name .. "." .. key, arg[1])
return set(self.name .. "." .. key, arg[1])
end
function Host:del(key)
return del(self.name .. "." .. key)
return del(self.name .. "." .. key)
end
function Host:writeln(...)
table.insert(self.obuf, (arg[1] or ""))
table.insert(self.obuf, (arg[1] or ""))
end
function Host:login(...)
set("host", self.name)
reply(arg[1] or self.motd, self.prompt)
set("host", self.name)
reply(arg[1] or self.motd, self.prompt)
end
function Host:cmd_help()
local k, v
self:writeln("Available commands:")
for k,v in pairs(self.commands) do
if (v[1]) then
local s = string.format("%-15s %s", k, v[1])
self:writeln(s)
end
end
local k, v
self:writeln("Available commands:")
for k,v in pairs(self.commands) do
if (v[1]) then
local s = string.format("%-15s %s", k, v[1])
self:writeln(s)
end
end
end
function Host:cmd_history()
local k, v
for k,v in ipairs(self.history) do
self:writeln(string.format("%5d %s", k, v))
end
local k, v
for k,v in ipairs(self.history) do
self:writeln(string.format("%5d %s", k, v))
end
end
-- Call self:handle(req) and return what to send back
function Host:handle_request(req)
local t = ""
local k, v
local t = ""
local k, v
self:handle(req)
self:handle(req)
for k,v in ipairs(self.obuf) do
t = t .. v .. "\n";
end
reply(t, self.prompt)
for k,v in ipairs(self.obuf) do
t = t .. v .. "\n";
end
reply(t, self.prompt)
end
-- Handle a request
function Host:handle(req)
self:do_cmd(req)
self:do_cmd(req)
end
-- Run a command or return an error
function Host:do_cmd(req)
local argv = req:split()
local cmd = self.commands[argv[1]:lower()]
local argv = req:split()
local cmd = self.commands[argv[1]:lower()]
if (argv[1] == "") then
return
end
if (argv[1] == "") then
return
end
-- First, update history
if self.history then
local h = self:get("history")
if h then
self.history = h:split("\n")
end
table.insert(self.history, req)
self:set("history", table.concat(self.history, "\n"))
end
-- First, update history
if self.history then
local h = self:get("history")
if h then
self.history = h:split("\n")
end
table.insert(self.history, req)
self:set("history", table.concat(self.history, "\n"))
end
-- Now run the command
if cmd then
if cmd[2] then
cmd[2](self, argv)
else
self:writeln("ERROR: no function defined")
end
else
self:writeln("Unknown command")
end
-- Now run the command
if cmd then
if cmd[2] then
cmd[2](self, argv)
else
self:writeln("ERROR: no function defined")
end
else
self:writeln("Unknown command")
end
end
-- List of commands, with help string (nil hides from help)
Host.commands = {
["?"] = {nil, Host.cmd_help},
["help"] = {"List available commands", Host.cmd_help},
["history"] = {"Display command history", Host.cmd_history},
["?"] = {nil, Host.cmd_help},
["help"] = {"List available commands", Host.cmd_help},
["history"] = {"Display command history", Host.cmd_history},
}
@ -344,27 +344,28 @@ warning.
]]
function Login:handle(req)
if (string.len(req) > 20) then
-- Log them in to wopr
Wopr:login([[
if (string.len(req) > 20) then
-- Log them in to wopr
Wopr:login([[
FLAGRANT SYSTEM ERROR: Memory segmentation violation
Returning to command subsystem [wopr:xipir-cavud-libux]
]])
else
if (req == "joshua") then
self:writeln("wopr:xirak-zoses-gefox")
elseif (req ~= "") then
self:writeln("Incorrect code")
end
end
else
if (req == "joshua") then
self:writeln("wopr:xirak-zoses-gefox")
elseif (req ~= "") then
print("hi")
self:writeln("Incorrect code")
end
end
end
function Login:login(...)
-- Since login is the default, we can *unset* host.
-- This has the nice property of not allocating any
-- storage for people who never make it past the front door.
del("host")
reply(arg[1] or self.motd, self.prompt)
-- Since login is the default, we can *unset* host.
-- This has the nice property of not allocating any
-- storage for people who never make it past the front door.
del("host")
reply(arg[1] or self.motd, self.prompt)
end
@ -498,7 +499,7 @@ FLD-1327 extends target date for full WOPR integration until June 22,
[-4] = "<85><D2>^?׃<C4>^T1<C0>[]Ít&^@<B8>^A^@^@^@븋C^D<89>",
[-5] = [[
^@^@^@^@^@^@on", n] => set attcon = n
msg "attcon set to" n
msg "attcon set to" n
["attcon enid"] => set_launch_trigger(1)
["attcon dennis"] => set_launch_trigger(0)
["bb"] => call_subsys bb
@ -510,60 +511,60 @@ FLD-1327 extends target date for full WOPR integration until June 22,
}
Bb.motd = [[
WOPR Message Board
WOPR Message Board
====================================================
[N]ext message
(P)revious message
(Q)uit
Enter message number to jump to that message
[N]ext message
(P)revious message
(Q)uit
Enter message number to jump to that message
]]
function Bb:read(inc)
local msgid = tonumber(self:get("msgid")) or 0
msgid = msgid + inc
self:jump(msgid)
local msgid = tonumber(self:get("msgid")) or 0
msgid = msgid + inc
self:jump(msgid)
end
function Bb:jump(msgid)
self:set("msgid", msgid)
self:set("msgid", msgid)
self:writeln("::::::::::::::::::::::::: Message #" .. tostring(msgid))
self:writeln()
self:writeln(self.posts[msgid])
self:writeln("::::::::::::::::::::::::: Message #" .. tostring(msgid))
self:writeln()
self:writeln(self.posts[msgid])
end
function Bb:do_cmd(req)
local n = tonumber(req)
if (req == "") then
self:cmd_next()
elseif n then
self:jump(n)
else
Host.do_cmd(self, req)
end
local n = tonumber(req)
if (req == "") then
self:cmd_next()
elseif n then
self:jump(n)
else
Host.do_cmd(self, req)
end
end
function Bb:cmd_next(argv)
self:read(1)
self:read(1)
end
function Bb:cmd_prev(argv)
self:read(-1)
self:read(-1)
end
function Bb:cmd_help(argv)
self:writeln(self.motd)
self:writeln(self.motd)
end
function Bb:cmd_quit(argv)
Wopr:login()
Wopr:login()
end
Bb.commands = {
["?"] = {nil, Bb.cmd_help},
["n"] = {nil, Bb.cmd_next},
["p"] = {nil, Bb.cmd_prev},
["q"] = {nil, Bb.cmd_quit},
["?"] = {nil, Bb.cmd_help},
["n"] = {nil, Bb.cmd_next},
["p"] = {nil, Bb.cmd_prev},
["q"] = {nil, Bb.cmd_quit},
}
--
@ -571,87 +572,87 @@ Bb.commands = {
--
Wopr = Host:new("wopr", "WOPR%")
Wopr.history = {
'subsys comm',
'wopr:xopev-zihuk-hubyx',
'exit',
'subsys comm',
'bb',
'subsys comm',
'exit',
'bb',
'subsys comm',
'exit',
'hlep',
'help',
'bb',
'help',
'subsys comm',
'exit',
'subsys comm',
'wopr:xopev-zihuk-hubyx',
'exit',
'subsys comm',
'bb',
'subsys comm',
'exit',
'bb',
'subsys comm',
'exit',
'hlep',
'help',
'bb',
'help',
'subsys comm',
'exit',
}
Wopr.motd = ""
function Wopr:cmd_subsys(argv)
local sys = argv[2]
local sys = argv[2]
if not sys then
self:writeln("Usage: subsys SYSTEM")
elseif sys == "?" then
local k, v
for k,v in pairs(hosts_by_name) do
self:writeln(k)
end
else
h = hosts_by_name[sys]
if not h then
self:writeln("No such subsystem (? to list)")
else
h:login()
end
end
if not sys then
self:writeln("Usage: subsys SYSTEM")
elseif sys == "?" then
local k, v
for k,v in pairs(hosts_by_name) do
self:writeln(k)
end
else
h = hosts_by_name[sys]
if not h then
self:writeln("No such subsystem (? to list)")
else
h:login()
end
end
end
function Wopr:cmd_bb(argv)
Bb:login()
Bb:login()
end
function Wopr:attcon()
return tonumber(self:get("attcon") or 5)
return tonumber(self:get("attcon") or 5)
end
-- This command should feel really shoddy: it was written
-- in-house by the New Khavistan Ministry of Technology.
function Wopr:cmd_attcon(argv)
if argv[2] == "enid" then
self:writeln("[[[ LAUNCH TRIGGER ENABLED ]]]")
self:writeln("wopr:xelev-lepur-pozyx")
self:set("launch")
elseif argv[2] == "dennis" then
self:writeln("[[[ LAUNCH TRIGGER DISABLED ]]]")
self:del("launch")
elseif argv[2] then
local v = tonumber(argv[2]) or 5
self:set("attcon", v)
self:writeln("attcon set to " .. tostring(v))
else
self:writeln(tostring(self:attcon()))
end
if argv[2] == "enid" then
self:writeln("[[[ LAUNCH TRIGGER ENABLED ]]]")
self:writeln("wopr:xelev-lepur-pozyx")
self:set("launch")
elseif argv[2] == "dennis" then
self:writeln("[[[ LAUNCH TRIGGER DISABLED ]]]")
self:del("launch")
elseif argv[2] then
local v = tonumber(argv[2]) or 5
self:set("attcon", v)
self:writeln("attcon set to " .. tostring(v))
else
self:writeln(tostring(self:attcon()))
end
end
-- Some test code they didn't remove
function Wopr:cmd_test(argv)
self:writeln("test output:")
self:writeln(" EIGEN58")
self:writeln(" sub_malarkey reached")
self:writeln(" DEBUG:453:wopr:xocom-bysik-mapix")
self:writeln("$$END")
self:writeln("test output:")
self:writeln(" EIGEN58")
self:writeln(" sub_malarkey reached")
self:writeln(" DEBUG:453:wopr:xocom-bysik-mapix")
self:writeln("$$END")
end
Wopr:add_commands{
["subsys"] = {"Connect to subsystem", Wopr.cmd_subsys},
["bb"] = {"Read bulletin board", Wopr.cmd_bb},
["attcon"] = {"[Place command description here]", Wopr.cmd_attcon},
["test"] = {nil, Wopr.cmd_test},
["subsys"] = {"Connect to subsystem", Wopr.cmd_subsys},
["bb"] = {"Read bulletin board", Wopr.cmd_bb},
["attcon"] = {"[Place command description here]", Wopr.cmd_attcon},
["test"] = {nil, Wopr.cmd_test},
}
--hosts["wopr"] = Wopr
@ -670,17 +671,17 @@ patching trunks to switch!
]]
function Comm:cmd_exit(argv)
Wopr:login()
Wopr:login()
end
function Comm:cmd_status(argv)
self:writeln("[Not yet implemented]")
self:writeln("wopr:xoroc-hunaz-vyhux")
self:writeln("[Not yet implemented]")
self:writeln("wopr:xoroc-hunaz-vyhux")
end
Comm:add_commands{
["status"] = {"Display phone system status", Comm.cmd_status},
["exit"] = {"Exit this subsystem", Comm.cmd_exit},
["status"] = {"Display phone system status", Comm.cmd_status},
["exit"] = {"Exit this subsystem", Comm.cmd_exit},
}
@ -696,126 +697,126 @@ Ministry of Weapons replacing all peanut brittle warheads with bubble
gum, as mandated by FLD-1492 "Fearless Grandson Peanut Allergy". Launch
capacity will be reduced until conversions are complete.
::: FLD-711 Restricted Distribution ::: wopr:xigeh-lydut-vinax
::: FLD-711 Restricted Distribution ::: wopr:xigeh-lydut-vinax
]]
Smoc.authcode = "CPE-1704-TKS"
Smoc.inventory = {
"ready", "offline", "offline", "ready",
"offline", "offline", "offline", "offline",
"offline", "offline", "FileNotFound", "ready",
[-1] = "program_invocation_short_name^@realm^@",
[-2] = "^@^@^@^@^@^@^@^@^@^R^@^@^@3",
[-3] = "<FF><FF><FF><FF>%L<C9>^D^Hhx^@^@^@",
[-4] = "^D^H^G^P^@^@P",
[-5] = "<EC>^P<8B>=<EC><C9>^D^H<C7>",
[-6] = "WVS<83><EC>\\<8B>E^L<8B><8B>U^P",
[-7] = "Y^@^@" .. Smoc.authcode .. "^@get_launch_trigger^@",
[-8] = "^@",
[-9] = "^@",
[-10] = "^@",
[-11] = "^@wopr:xipar-canit-zimyx^@",
[-12] = "^@",
[-13] = "^@",
[-14] = "^@",
[-15] = "^@",
[-16] = "^@",
"ready", "offline", "offline", "ready",
"offline", "offline", "offline", "offline",
"offline", "offline", "FileNotFound", "ready",
[-1] = "program_invocation_short_name^@realm^@",
[-2] = "^@^@^@^@^@^@^@^@^@^R^@^@^@3",
[-3] = "<FF><FF><FF><FF>%L<C9>^D^Hhx^@^@^@",
[-4] = "^D^H^G^P^@^@P",
[-5] = "<EC>^P<8B>=<EC><C9>^D^H<C7>",
[-6] = "WVS<83><EC>\\<8B>E^L<8B><8B>U^P",
[-7] = "Y^@^@" .. Smoc.authcode .. "^@get_launch_trigger^@",
[-8] = "^@",
[-9] = "^@",
[-10] = "^@",
[-11] = "^@wopr:xipar-canit-zimyx^@",
[-12] = "^@",
[-13] = "^@",
[-14] = "^@",
[-15] = "^@",
[-16] = "^@",
}
function Smoc:login()
if self:get("nuked") then
Wopr:login("*** LINK DOWN\n*** CONNECTION REFUSED")
else
Host.login(self)
end
if self:get("nuked") then
Wopr:login("*** LINK DOWN\n*** CONNECTION REFUSED")
else
Host.login(self)
end
end
function Smoc:cmd_exit(argv)
Wopr:login()
Wopr:login()
end
function Smoc:cmd_status(argv)
local n = tonumber(argv[2])
if not n then
local k, v, max
local ready = 0
for k,v in ipairs(self.inventory) do
if (v == "ready") then
ready = ready + 1
end
max = k
end
self:writeln(("%d total, %d ready"):format(max, ready))
self:writeln("Use \"status #\" to check status of individual missiles")
else
self:writeln(("---- Missile #%d Summary ----"):format(n))
self:writeln("Type: SS-256 SCUMM")
self:writeln("Location: Fearless Missile Silo #1 (-44.76,-120.66)")
self:writeln("Status: " .. (self.inventory[n] or "(null)"))
end
end
local n = tonumber(argv[2])
if not n then
local k, v, max
local ready = 0
for k,v in ipairs(self.inventory) do
if (v == "ready") then
ready = ready + 1
end
max = k
end
self:writeln(("%d total, %d ready"):format(max, ready))
self:writeln("Use \"status #\" to check status of individual missiles")
else
self:writeln(("---- Missile #%d Summary ----"):format(n))
self:writeln("Type: SS-256 SCUMM")
self:writeln("Location: Fearless Missile Silo #1 (-44.76,-120.66)")
self:writeln("Status: " .. (self.inventory[n] or "(null)"))
end
end
function Smoc:cmd_authorize(argv)
if not Wopr:get("launch") then
self:writeln("ERROR: Launch trigger disabled.")
elseif (argv[2] ~= self.authcode) then
self:writeln("Invalid authorization code.")
else
self:writeln("Authorization code accepted.")
self:writeln("wopr:xocec-lifoz-gasyx")
self:set("auth")
end
if not Wopr:get("launch") then
self:writeln("ERROR: Launch trigger disabled.")
elseif (argv[2] ~= self.authcode) then
self:writeln("Invalid authorization code.")
else
self:writeln("Authorization code accepted.")
self:writeln("wopr:xocec-lifoz-gasyx")
self:set("auth")
end
end
function Smoc:cmd_launch(argv)
local n = tonumber(argv[2])
local lat = tonumber(argv[3])
local lon = tonumber(argv[4])
local n = tonumber(argv[2])
local lat = tonumber(argv[3])
local lon = tonumber(argv[4])
if Wopr:attcon() > 1 then
self:writeln("ERROR: Missiles may only be launched during times of war.")
elseif not self:get("auth") then
self:writeln("ERROR: Not authorized")
elseif (not n) then
self:writeln("Usage: launch # LAT LONG")
elseif (not lat) or (not lon) then
self:writeln("ERROR: Invalid coordinates supplied")
elseif (self.inventory[n] == "offline") then
self:writeln("ERROR: Missile currently off-line")
elseif (n < 1) then
self:writeln("ERROR: No such missile")
else
self:writeln(("Launching to (%f,%f)..."):format(lat, lon))
self:writeln("wopr:xubif-hikig-mocox")
if (lat ~= -44.76) or (lon ~= -120.66) then
self:writeln("ERROR: No propulsion system attached")
elseif (self.inventory[n] ~= "FileNotFound") then
self:writeln("ERROR: Triggering device not installed")
else
self:set("nuked")
Wopr:login("Detonating warhead...\nwopr:xoroz-hymaz-fivex wopr:xufov-sugig-zecox wopr:xocem-dabal-fisux wopr:xufez-dofas-tyvyx\n*** CONNECTION TERMINATED")
end
end
if Wopr:attcon() > 1 then
self:writeln("ERROR: Missiles may only be launched during times of war.")
elseif not self:get("auth") then
self:writeln("ERROR: Not authorized")
elseif (not n) then
self:writeln("Usage: launch # LAT LONG")
elseif (not lat) or (not lon) then
self:writeln("ERROR: Invalid coordinates supplied")
elseif (self.inventory[n] == "offline") then
self:writeln("ERROR: Missile currently off-line")
elseif (n < 1) then
self:writeln("ERROR: No such missile")
else
self:writeln(("Launching to (%f,%f)..."):format(lat, lon))
self:writeln("wopr:xubif-hikig-mocox")
if (lat ~= -44.76) or (lon ~= -120.66) then
self:writeln("ERROR: No propulsion system attached")
elseif (self.inventory[n] ~= "FileNotFound") then
self:writeln("ERROR: Triggering device not installed")
else
self:set("nuked")
Wopr:login("Detonating warhead...\nwopr:xoroz-hymaz-fivex wopr:xufov-sugig-zecox wopr:xocem-dabal-fisux wopr:xufez-dofas-tyvyx\n*** CONNECTION TERMINATED")
end
end
end
Smoc:add_commands{
["status"] = {"Check missile status", Smoc.cmd_status},
["launch"] = {"Launch missile", Smoc.cmd_launch},
["authorize"] = {"Set authorization code", Smoc.cmd_authorize},
["exit"] = {"Exit to WOPR", Smoc.cmd_exit},
["status"] = {"Check missile status", Smoc.cmd_status},
["launch"] = {"Launch missile", Smoc.cmd_launch},
["authorize"] = {"Set authorization code", Smoc.cmd_authorize},
["exit"] = {"Exit to WOPR", Smoc.cmd_exit},
}
function main()
if (not f["s"]) or (f["s"] == "") then
Login:login()
else
local h = hosts_by_name[get("host")] or Login
txt, prompt = h:handle_request(f["v"] or "")
end
if (not f["s"]) or (f["s"] == "") then
Login:login()
else
local h = hosts_by_name[get("host")] or Login
txt, prompt = h:handle_request(f["v"] or "")
end
end
function err(msg)
reply("", "A>", msg .. " wopr:xosov-tenoh-nebox\n\n" .. debug.traceback())
reply("", "A>", msg .. " wopr:xosov-tenoh-nebox\n\n" .. debug.traceback())
end
xpcall(main, err)