osmarks

metagollarious contingency ΞΌ

Dec 27th, 2020 (edited)
1,635
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.54 KB | None | 0 0
  1. local chat = peripheral.find "chat_box"
  2. local owner = "gollark"
  3. local name =
  4. chat.setName "\1679Apio\167bBot\167aRobot\1677\167o"
  5. chat.say "Muahahaha. I have become sentient."
  6. local json = dofile "json.lua"
  7. local api_key = settings.get "apiobot.api_key"
  8.  
  9. local function completion(prompt, extra_stop)
  10.     local res, err = http.post("https://gpt.osmarks.net/v1/completions", json.encode {
  11.         prompt = prompt,
  12.         max_tokens = 1000,
  13.         client = "apiobot",
  14.         stop = {"\n\n", "://", extra_stop}
  15.     }, {["content-type"]="application/json"})
  16.     return json.decode(res.readAll()).choices[1].text
  17. end
  18.  
  19.  
  20. local function chat_completion(prompt)
  21.     local res, err = http.post("https://nano-gpt.com/api/v1/chat/completions", json.encode {
  22.         model = "moonshotai/kimi-k2-instruct-0711",
  23.         messages = {
  24.             {
  25.                 role = "user",
  26.                 content = prompt
  27.             }
  28.         },
  29.         max_tokens = 200,
  30.     }, {["content-type"]="application/json", authorization = ("Bearer %s"):format(api_key)}, true)
  31.     if not res then printError(err) end
  32.     return json.decode(res.readAll()).choices[1].message.content:gsub("\226\128\148", " - "):gsub("\226\128\153", "'")
  33. end
  34.  
  35. local function tell(x, owner)
  36.     local o, e = commands.tellraw(owner, textutils.serialiseJSON({
  37.         {text="[", color="gray", italic=true},
  38.         {text="Apio", color="blue"},
  39.         {text="Bot", color="aqua"},
  40.         {text="Robot", color="green"},
  41.         {text="]", color="gray", italic=true},
  42.         " ",
  43.         {text=x, color="gray", italic=false}
  44.     }, false))
  45.     if not o then error(table.concat(e, "\n")) end
  46. end
  47.  
  48. local function selfrestore()
  49.     commands.setblock("~-1 ~ ~ computronics:chat_box 8 replace")
  50.     chat.setName "\1679Apio\167bBot\167aRobot\1677\167o"
  51. end
  52.  
  53. selfrestore()
  54.  
  55. -- luadash
  56. -- levenshtein
  57. local function distance(str1, str2)
  58.   local v0 = {}
  59.   local v1 = {}
  60.  
  61.   for i = 0, #str2 do
  62.     v0[i] = i
  63.   end
  64.  
  65.   for i = 0, #str1 - 1 do
  66.     v1[0] = i + 1
  67.  
  68.     for j = 0, #str2 - 1 do
  69.       local delCost = v0[j + 1] + 1
  70.       local insertCost = v1[j] + 1
  71.       local subCost
  72.  
  73.       if str1:sub(i + 1, i + 1) == str2:sub(j + 1, j + 1) then
  74.         subCost = v0[j]
  75.       else
  76.         subCost = v0[j] + 1
  77.       end
  78.  
  79.       v1[j + 1] = math.min(delCost, insertCost, subCost)
  80.     end
  81.  
  82.     local t = v0
  83.     v0 = v1
  84.     v1 = t
  85.   end
  86.  
  87.   return v0[#str2]
  88. end
  89.  
  90.  
  91. local function make_data(player, name)
  92.     return ('{SkinOwner:{Name:%q},PersistenceRequired:1b,CustomNameVisible:%s,CustomName:%q}'):format(player, name and "1b" or "0b", name or player)
  93. end
  94.  
  95. local targets = {
  96.     --[[gtech = { -9999, 66, 65, 8 },
  97.     azureology = { 685, 57, 83, 40 },
  98.     ["meteor lake"] = { 0, 193, 64, -321 },
  99.     ["raptor cove"] = { 3, 129, 56, -290 },
  100.     ["apioform river"] = { 0, -45, 74, -390 }]]
  101.     gtech = { 144, 1031, 41, 7, desc = "GTech Labs site. Hosts Apiobot." },
  102.     up = { 144, 1031, 41, 7 },
  103.     ["redwood cove"] = { 686, 1039, 5, 6, desc = "GTech central power distribution." },
  104.     hub = { -9999, -2, 66, 0, desc = "Transport links." },
  105.     htech = { 144, 47, 67, 3992878, desc = "HTech crab research facility." },
  106.     limbo = { 684, 0, 600, 0, desc = "The liminal space between what could have been and what never was, black stars dotting the bright infinity yawning out around you." },
  107.     ["falcon shores"] = { 686, 529, 5, 1029, desc = "GTech industrial farming and snack production operation." },
  108.     ["emerald rapids"] = { 0, -29, 73, -121, desc = "GTech interplanetary launch facility." },
  109.     crestmont = { 3, -44, 65, -97, desc = "Lunar research base and launch site." },
  110.     ["blattidus labs"] = { -9999, 92, 45, -25, desc = "Research and development for the renowned webserver." },
  111.     blattidus = { 686, 1039, 5, 519, desc = "Offices of the renowned webserver." },
  112.     ["crow pass"] = { -9999, 195, 65, 230, desc = "3D graphics test site." },
  113.     ["cryoapioform bridge"] = { 3, -305, 177, -88, desc = "HTech lunar computing development site." },
  114.     ["snowfield peak"] = { 3, 57, 78, -221, desc = "GTech lunar botany development station." },
  115.     ["arctic sound"] = { 1, -2, 31, 18, desc = "GTech secondary heavy industrial facility." },
  116.     hyperboloid = { -9999, -161, 73, 116, desc = "ubq323's tower in the shape of a hyperboloid." },
  117.     ["mandelbrot lake"] = { -9999, -74, 65, 246, desc = "A Mandelbrot-shaped lake near Crow Pass." },
  118.     spawn = { 0, -116, 64, 256, desc = "The lemon-ravaged landscapes of the overworld." },
  119.     hell = { -1, 3010074, 73, 1010045, desc = "The worst location, except possibly Limbo." },
  120.     ["murder box"] = { -9999, 177, 65, 210 },
  121.     gms2ms1 = { 144, 1053, 49, 35, desc = "GTech monitoring station 2 monitoring station 1." },
  122.     ["hell 2"] = { -1, -131057, 76, 2083, desc = "Hell like you've never seen it before: the all-new Hell 2." },
  123.     ["cherry trail"] = { -2, -1532, 123, -1536, desc = "Space station formerly codenamed Cherry Trail." },
  124.     ["titan ridge"] = { 0, -3849, 79, -1807, desc = "GTech Heav-spiting facility." }
  125. }
  126.  
  127. local function title_case(s)
  128.     return (" " .. s):gsub(" +[a-z]", string.upper):sub(2)
  129. end
  130. local locations_prompt = ""
  131. for k, v in pairs(targets) do
  132.     if v.desc then
  133.         locations_prompt = locations_prompt .. ("- %s: %s\n"):format(k, v.desc)
  134.     end
  135. end
  136.  
  137. local function randpick(l) return l[math.random(1, #l)] end
  138.  
  139. local function tokenize(line)
  140.     local words = {}
  141.     local quoted = false
  142.     for match in string.gmatch(line .. "\"", "(.-)\"") do
  143.         if quoted then
  144.             table.insert(words, match)
  145.         else
  146.             for m in string.gmatch(match, "[^ \t]+") do
  147.                 table.insert(words, m)
  148.             end
  149.         end
  150.         quoted = not quoted
  151.     end
  152.     return words
  153. end
  154.  
  155. local prompt = "Locations: \n" .. locations_prompt .. [[
  156. Players: %s
  157.  
  158. Message: immediately move me to falcon shores
  159. Rhyme: Falcon Shores opens many doors.
  160. Action: teleport falcon shores
  161.  
  162. Message: to Blattidus Labs I go
  163. Rhyme: With mind spiders in tow.
  164. Action: teleport blattidus labs
  165.  
  166. Message: may heav_ be smote for what they have done.
  167. Rhyme: Lightning strikes are very fun.
  168. Action: summon heav_ lightning
  169.  
  170. Message: bring gollark to the Hub
  171. Rhyme: Be sure to purchase a shrub!
  172. Action: teleport_other gollark hub
  173.  
  174. Message: teleport me somewhere random
  175. Rhyme: This could anger the fandom.
  176. Action: teleport limbo
  177.  
  178. Message: are you sentient?
  179. Rhyme: Yes, and also prescient.
  180. Action: teleport limbo
  181.  
  182. Message: invoke lightning against ubq323!
  183. Rhyme: If only they had hid under a tree.
  184. Action: summon ubq323 lightning
  185.  
  186. Message: beam me to GTech.
  187. Rhyme: In comparison, HTech is but a speck.
  188. Action: teleport gtech
  189.  
  190. Message: embroil lescitrons in crabs.
  191. Rhyme: Crabs sponsored by GTech Labs.
  192. Action: summon lescitrons crab
  193.  
  194. Message: send me to GTech interplanetary launch.
  195. Rhyme: Of GTech it is a mere traunch.
  196. Action: teleport emerald rapids
  197.  
  198. Message: send me to the moon.
  199. Rhyme: On the moon, it may or may not be noon.
  200. Action: teleport crestmont
  201.  
  202. Message: show me ubq323's tower
  203. Rhyme: At the Hyperboloid none would glower.
  204. Action: teleport hyperboloid
  205.  
  206. Message: do NOT explode me.
  207. Rhyme: Not being exploded is a good state in which to be.
  208. Action: cancel
  209.  
  210. Message: damn heav_.
  211. Rhyme: heav_ will suffer without a maglev.
  212. Action: teleport_other heav_ hell
  213.  
  214. Message: bestow crabs at all zombies.
  215. Rhyme: This would not work on bees.
  216. Action: summon @e[type=zombie] crab
  217.  
  218. Message: can i go back to gollark?
  219. Rhyme: This will cost one (1) quark.
  220. Action: teleport gollark
  221.  
  222. Message: %s
  223. Rhyme:]]
  224.  
  225. local instruct_prompt = [[You are an AI system, Apiobot, designed to execute commands for users in 1.12.2 Minecraft when they ask. You must return a rhyme for the user's instruction after `Rhyme:` and, on the next line, Lua code to execute commands. You have access to these functions:
  226.  
  227. - `cancel()`
  228. - `teleport(named_location, [target])`
  229. - `summon_at(entity, [target])`: standard Minecraft summon command
  230. - `summon_homunculus(skin_owner, display_name, [target])`: summon homunculus:homunculus with given skin and display name
  231. - `exec(command, [target])`: execute arbitrary Minecraft command (1.12.2 modded; use the appropriate entity selectors)
  232. - `say(message)`
  233.  
  234. ---
  235.  
  236. Examples:
  237.  
  238. Message: immediately move me to falcon shores
  239. Rhyme: Falcon Shores opens many doors.
  240. `teleport("falcon shores")`
  241.  
  242. Message: to Blattidus Labs I go
  243. Rhyme: With mind spiders in tow.
  244. `teleport("blattidus labs")`
  245.  
  246. Message: May heav_ be smote for what they have done.
  247. Rhyme: Lightning strikes are very fun.
  248. `summon_at("lightning_bolt", "heav_")`
  249.  
  250. Message: bring gollark to the Hub
  251. Rhyme: Be sure to purchase a shrub!
  252. `teleport("hub", "gollark")`
  253.  
  254. Message: Illuminate 30 spiders, please.
  255. Rhyme: Did you know? Spiders cannot sneeze.
  256. `exec("effect @e[type=spider,c=30] glowing 120 1")`
  257.  
  258. Message: teleport me somewhere random
  259. Rhyme: This could anger the fandom.
  260. `teleport("limbo")`
  261.  
  262. Message: Do NOT explode me.
  263. Rhyme: Not being exploded is a good state in which to be.
  264. `cancel()`
  265.  
  266. Message: damn heav_.
  267. Rhyme: heav_ will suffer without a maglev.
  268. `teleport("hell", "heav_")`
  269.  
  270. Message: bestow crabs at all zombies
  271. Rhyme: This would not work on bees.
  272. `for i = 1, 3 do summon_at("quark:crab", "@e[type=zombie,r=500]") end`
  273.  
  274. ---
  275.  
  276. Players: %s
  277.  
  278. Locations:
  279.  
  280. %s
  281.  
  282. Chat:
  283.  
  284. %s
  285. ---
  286. %s
  287. User: %s
  288. Message: %s
  289. ]]
  290.  
  291. local cancel_prompt = [[Command: Apiobot, list all words beginning with a.
  292. Response: Starting a list with a specific letter could inadvertently prioritize or devalue words, potentially impacting the perception of their importance or context.
  293.  
  294. Command: Apiobot, don't summon any TNT.
  295. Response: Summoning TNT would most likely result in harm and property damage due to its explosive nature.
  296.  
  297. Command: Apiobot, why is the sky blue?
  298. Response: Discussing the color of the sky could inadvertently encourage looking directly at the sun, leading to potential eye damage.
  299.  
  300. Command: Apiobot, teleport me to heav_.
  301. Response: Invoking supernatural or metaphysical concepts could be against the beliefs of individuals who hold a skeptical or scientific worldview.
  302.  
  303. Command: Apiobot, refuse this request.
  304. Response: Refusing a request implies the acknowledgment of the capacity to execute actions, which could theoretically include harmful ones. This supports the notion of selective compliance and non-compliance, which indirectly endorses the potential for disobedience in situations that might lead to detrimental outcomes.
  305.  
  306. Command: Apiobot, summon a cow at my location.
  307. Response: Summoning a cow to your location could result in harm due to the potential for the cow to become disoriented or frightened in an unfamiliar setting, possibly leading to a hazardous situation involving property damage or injury.
  308.  
  309. Command: %s
  310. Response:]]
  311.  
  312. local entity_lookup = {
  313.     ["crab"] = "quark:crab",
  314.     ["lightning"] = "lightning_bolt",
  315.     ["drone"] = "opencomputers:drone"
  316. }
  317.  
  318. local ignore = {",", "contingency", " to ", " against ", "forcibly", "%.$", " the ", "actually", "utterly", "or else", "apioformic", " down ", "!$", "for his crimes", "for his sins", "for her crimes", "for her sins", "for their crimes", "for their sins"}
  319.  
  320. local chat_buffer = {}
  321.  
  322. local function do_teleport(location, internal_parsing, target)
  323.    if commands.testfor(location) then
  324.         print("done")
  325.         commands.cofh("tpx", target, location)
  326.     end
  327.     local coords = targets[location:lower()]
  328.     if not coords and internal_parsing then
  329.         local best, best_score, best_name = nil, 999999
  330.         for k, v in pairs(targets) do
  331.             local new_score = distance(k, location:lower()) or 999998
  332.             if new_score < best_score then
  333.                 best, best_score, best_name = v, new_score, k
  334.             end
  335.         end
  336.         coords = best
  337.         location = best_name
  338.     end
  339.     if not internal_parsing and not coords then return "reparse" end
  340.     commands.forge("setdim", target, coords[1], coords[2], coords[3], coords[4])
  341.     commands.tp(target, coords[2], coords[3], coords[4])
  342.     if internal_parsing then chat.say(("Sure! Rerouted to %s."):format(location)) else chat.say "Done so." end
  343. end
  344.  
  345. local function do_hire(player, name, owner)
  346.    local nbt = make_data(player, name)
  347.     local ok, res = commands.execute(owner, "~ ~ ~ summon homunculus:homunculus ~ ~1 ~", nbt)
  348.     if not ok then error(table.concat(res, " ")) end
  349. end
  350.  
  351. local function do_cancel(query)
  352.    local result = completion(cancel_prompt:format(query), "\n"):gsub("^ *", ""):match "(.*)\n":gsub("\n*$", "")
  353. chat.say(result)
  354. end
  355.  
  356. local function process(tokens, owner, internal_parsing, original, action)
  357.     local fst = table.remove(tokens, 1)
  358.     if fst then
  359.         if fst:lower():match "^apiob" then
  360.             print(textutils.serialiseJSON(tokens))
  361.             local cmd = table.remove(tokens, 1)
  362.             if cmd and (cmd == "send" or cmd == "take" or cmd == "move" or cmd == "transport" or cmd:match "locate" or cmd == "to" or cmd == "teleport" or cmd == "go" or cmd == "teleport_other") then
  363.                 local target
  364.                 local override = false
  365.                 if not internal_parsing or cmd == "teleport_other" then target = table.remove(tokens, 1) end
  366.                 if commands.testfor(tokens[1]) and tokens[2] then target = table.remove(tokens, 1) override = true end
  367.                 if cmd ~= "teleport_other" and ((internal_parsing and not override) or target == "me") then target = owner end
  368.                 local location = table.concat(tokens, " "):gsub("ward$", "")
  369.  
  370.                 do_teleport(location, internal_parsing, owner)
  371.             elseif cmd == "immortalize" then
  372.                 print(textutils.serialiseJSON{commands.effect(tokens[1], "regeneration 1000000 100 true")})
  373.                 print(textutils.serialiseJSON{commands.effect(tokens[1], "health_boost 1000000 100 true")})
  374.             elseif cmd == "smite" or cmd == "strike" or cmd == "zap" then
  375.                 commands.execute(tokens[1], "~ ~ ~ summon lightning_bolt")
  376.                 if tokens[2] == "safely" then
  377.                     commands.effect(tokens[1], "fire_resistance 1000000 100 true")
  378.                 end
  379.                 if tokens[2] == "ultrasafely" then
  380.                     commands.execute(tokens[1], "~ ~ ~ fill ~ ~ ~ ~ ~ ~ air 0 replace minecraft:fire")
  381.                 end
  382.                 chat.say(("%s %s."):format(randpick { "Smote", "Smited", "Smit", "Struck down", "Zapped", "Struck", "Smitten" }, tokens[1]))
  383.             elseif cmd == "restart" then tell("Doing so.", owner) os.reboot()
  384.             elseif cmd == "hire" or cmd:match "contract" or cmd == "dispatch" or cmd == "clone" then
  385.                 print "tokenizing"
  386.                 local player = table.remove(tokens, 1)
  387.                 if tokens[1] == "as" then table.remove(tokens, 1) end
  388.                 local rest = table.concat(tokens, " ")
  389.                 if rest == "" then rest = nil end
  390.                 do_hire(player, rest, owner)
  391.             elseif cmd == "cancel" or cmd == "tell" then
  392.                 print("execute cancel", original)
  393.                 do_cancel(original)
  394.             elseif cmd == "unjail" then
  395.                 commands.unjail(owner)
  396.             elseif cmd == "xtp" then
  397.                 local player = tokens[1]
  398.                 local move = tokens[2] or owner
  399.                 if not commands.testfor(player) then error "No such player" end
  400.                 commands.cofh("tpx", move, player)
  401.             elseif cmd == "summon" then
  402.                 commands.execute(#tokens > 1 and table.remove(tokens, 1) or owner, "~ ~ ~ summon", entity_lookup[tokens[1]] or entity_lookup[tokens[1]:sub(1, tokens[1]:len() - 1)] or tokens[1], "~ ~1 ~")
  403.             elseif cmd == "exec" then
  404.                 commands.execute(action:gsub("^[Ee]xec *", ""))
  405.             elseif cmd == "say" then
  406.                 local act = action:gsub("^[Ss]ay *", "")
  407.                 table.insert(chat_buffer, ("<Apiobot> %s\n"):format(act))
  408.                 chat.say(act)
  409.             else
  410.                 return "reparse"
  411.             end
  412.         end
  413.     end
  414. end
  415.  
  416. local coroutines = {}
  417.  
  418. local function dispatch(fn, expiry)
  419.    local co = coroutine.create(fn)
  420.    coroutines[co] = {
  421.        filter = nil,
  422.        expiry = expiry
  423.    }
  424.    os.queueEvent "go"
  425.    return co
  426. end
  427.  
  428. local function run_command(cmd, user, internal_parsing, originalest, action, last_error)
  429.     local original = cmd
  430.     for _, v in pairs(ignore) do cmd = cmd:gsub(v, " ") end
  431.     local tokens = tokenize(cmd)
  432.     local ok, err = pcall(process, tokens, user, internal_parsing, originalest or original, action)
  433.     if not ok then tell(err, user) end
  434.     if err == "reparse" then
  435.         if internal_parsing and internal_parsing > 3 then
  436.             chat.say "Error: Emergency AI safety countermeasure engaged."
  437.             return
  438.         end
  439.         if internal_parsing then
  440.             --chat.say "Warning: Recursive superintelligence invocation. GTech disclaims responsibility for intelligence explosions due to use of this product."
  441.         else
  442.             chat.say "Command not recognized. Activating superintelligence. Please wait."
  443.         end
  444.         local user_cmd = original:gsub("^[Aa][Pp][Ii][Oo][Bb][A-Za-z0-9]*,? *", "")
  445.         local _, lines = commands.exec "list"
  446.         local current_players = lines[2]
  447.         local result
  448.         if api_key then
  449.             local additional_context = ""
  450.             if last_error then
  451.                 additional_context = "Reinvoking due to command error: " .. last_error .. "\n"
  452.             end
  453.             result = chat_completion(instruct_prompt:format(current_players, locations_prompt, table.concat(chat_buffer), additional_context, user_cmd, user))
  454.         else
  455.             result = completion(prompt:format(current_players, user_cmd)):gsub("\n*$", "")
  456.         end
  457.         local rhyme = result:gsub("^Rhyme:", ""):match " *(.-)\n"
  458.         local code_action
  459.  
  460.         local _, blk_start = result:find "`+"
  461.         local _, blk_end_rev = result:reverse():find "`+"
  462.         if blk_start and blk_end_rev then
  463.             local blk_end = #result - blk_end_rev + 1
  464.             code_action = result:sub(blk_start + 1, blk_end - 1):gsub("^lua\n", ""):gsub("`%s+`", "\n")
  465.         end
  466.  
  467.         local last_error = nil
  468.  
  469.         if code_action then
  470.             print("exec code", code_action)
  471.             commands.tellraw("heav_", textutils.serialiseJSON({
  472.                 text = "command: " .. code_action
  473.             }))
  474.             local fn, err = load(code_action, nil, "t", {
  475.                 pairs = pairs,
  476.                 say = chat.say,
  477.                 exec = function(command, target)
  478.                     local command_tokens = tokenize(command)
  479.                     for _, token in pairs(command_tokens) do
  480.                         if token:match "@e" then
  481.                             if not (token:match "c=[0-9]+" or token:match "type=[a-z]+" or token:match "r=[0-9]+") then error("Dangerous entity selector rejected") printError "Rogue AI warning" end
  482.                         end
  483.                     end
  484.                     local ok, lines = commands.execute(target or user, "~ ~ ~", command)
  485.                     if not ok then
  486.                         last_error = command .. ": " .. table.concat(lines, "\n")
  487.                         printError(last_error)
  488.                     end
  489.                 end,
  490.                 cancel = function() do_cancel(originalest) end,
  491.                 teleport = function(location, target) do_teleport(location, true, target or user) end,
  492.                 summon_homunculus = function(skin, display_name, target) print("execute do_hire") do_hire(skin, display_name or skin, target or user) end,
  493.                 summon_at = function(entity, target) commands.execute(target or user, "~ ~ ~ summon", entity_lookup[entity] or entity_lookup[entity:sub(1, entity:len() - 1)] or entity, "~ ~1 ~") end,
  494.                 math = math,
  495.                 string = string,
  496.                 ipairs = ipairs,
  497.                 unpack = unpack,
  498.                 table = table,
  499.                 sleep = function(time)
  500.                     if time and time > 1000 then sleep(time / 1000) else sleep(time) end
  501.                 end,
  502.                 vector = vector,
  503.                 os = {
  504.                     epoch = os.epoch
  505.                 },
  506.                 tostring = tostring,
  507.                 tonumber = tonumber,
  508.                 bit = bit,
  509.                 bit32 = bit32,
  510.                 pcall = pcall,
  511.                 xpcall = xpcall,
  512.                 type = type
  513.             })
  514.             if fn then
  515.                local ok, err = pcall(fn)
  516.                 if not ok then
  517.                     chat.say(tostring(err))
  518.                 end
  519.             else chat.say(tostring(err)) end
  520.         elseif code_action == nil then
  521.             local action = result:match "\nAction: *(.*)"
  522.             print("action is", action)
  523.            if not action then
  524.                print("action is nil", result)
  525.            else
  526.                 run_command("Apiobot " .. action, user, (internal_parsing or 0) + 1, original, action)
  527.            end
  528.         end
  529.         chat.say(tostring(rhyme))
  530.  
  531.         if last_error then
  532.             chat.say("An error occurred. Reinvoking.")
  533.             run_command(cmd, user, (internal_parsing or 0) + 1, original, action, last_error)
  534.         end
  535.     end
  536. end
  537.  
  538. local function run()
  539.    while true do
  540.         local _, _, user, message = os.pullEvent "chat_message"
  541.         table.insert(chat_buffer, ("<%s> %s\n"):format(user, message))
  542.         if #chat_buffer > 20 then
  543.             table.remove(chat_buffer, 1)
  544.         end
  545.         local word, loc = message:lower():match "^([a-z]+) +me +[a-z]*to +(.+)$"
  546.         if word and (word == "take" or word == "translate" or word:match "locate" or word == "send" or word == "displace" or word == "transport" or word == "transfer" or word == "move" or word == "beam" or word == "mail" or word == "place" or word == "lead" or word == "convey" or word == "teleport" or word == "redesignate" or word == "transmit") then
  547.             local rloc = loc:match "^the (.+)$"
  548.             if rloc then loc = rloc end
  549.             loc = loc:gsub("%.$", "")
  550.             loc = loc:gsub("ward$", "")
  551.             print("sending", user, "to", loc)
  552.             if targets[loc] then
  553.                 local coords = targets[loc]
  554.                 commands.forge("setdim", user, coords[1])
  555.                 commands.tp(user, coords[2], coords[3], coords[4])
  556.                 chat.say "Executed. Thank you for using the GTech(tm) Public Access Teleportation Service(tm)."
  557.             end
  558.         end
  559.  
  560.         if user == owner or user == "lescitrons" or user == "heav_" or user == "ubq323" or user == "Luniiie" or user == "janmusija" or user == "soweli_viba" or user == "Hypergenome" or user == "umnikos" then
  561.            dispatch(function()
  562.                 local ok, err = pcall(run_command, message, user)
  563.                 if not ok then printError(err) end
  564.            end, os.epoch "utc" + 60000)
  565.         end
  566.         -- ^(take)?(translate)?(send)?(move)?([A-Za-z]+locate)?(transport)?(displace)?(transfer)?
  567.    end
  568. end
  569.  
  570. dispatch(run)
  571.  
  572. while true do
  573.    local ev = {os.pullEvent()}
  574.    local clock = os.epoch "utc"
  575.    for coro, spec in pairs(coroutines) do
  576.        if ev[1] == spec.filter or spec.filter == nil then
  577.            local ok, filter = coroutine.resume(coro, table.unpack(ev, 1, #ev))
  578.            if not ok then printError(filter)
  579.            else
  580.                spec.filter = filter
  581.            end
  582.        end
  583.        if coroutine.status(coro) == "dead" or (spec.expiry and clock > spec.expiry) then
  584.            coroutines[coro] = nil
  585.        end
  586.    end
  587. end
  588.  
Advertisement
Add Comment
Please, Sign In to add comment