turtle5204

Δshop

May 12th, 2018
1,307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.05 KB | None | 0 0
  1. --@version=1.5
  2. local version = 1.5
  3. local mon = peripheral.find("monitor")
  4. local cbx = peripheral.find("chat_box")
  5.  
  6. local function fwrite(file, data)
  7. local f = fs.open(file, "w")
  8. f.write(data)
  9. f.close()
  10. end
  11.  
  12. local function fread(file)
  13. local f = fs.open(file, "r")
  14. local r = f.readAll()
  15. f.close()
  16. return r
  17. end
  18.  
  19. function cwrite(sText, yy)
  20. local w, h = mon.getSize()
  21. local x, y = mon.getCursorPos()
  22. x = math.max(math.floor((w / 2) - (#sText / 2)), y)
  23. mon.setCursorPos(x, yy)
  24. mon.write(sText)
  25. end
  26.  
  27. local ok, err =
  28. pcall(
  29. function()
  30. local dshtp = http.get("https://pastebin.com/raw/akkinMTL")
  31. local dsl = dshtp.readLine()
  32. local dsr = dshtp.readAll()
  33. dshtp.close()
  34. if (tonumber(dsl:sub(12)) > version) then
  35. print("Update detected. Version " .. tostring(version) .. " > " .. tostring(dsl:sub(12)))
  36. local f = fs.open(shell.getRunningProgram(), "w")
  37. f.writeLine(dsl)
  38. f.write(dsr)
  39. f.close()
  40. sleep(2)
  41. os.reboot()
  42. end
  43.  
  44. local pkey = fs.exists("/.pkey") and fread("/.pkey") or nil
  45.  
  46. if not fs.exists("/dconfig") then
  47. fwrite(
  48. "/dconfig",
  49. [[
  50. local cfg = {}
  51. --Config starts here
  52.  
  53. cfg["kristAddress"] = nil
  54. cfg["shopName"] = "Default Shop"
  55. cfg["redstoneHeartbeat"] = nil
  56.  
  57. --Config ends here
  58. return cfg
  59. ]]
  60. )
  61. fwrite(
  62. "/shopdata",
  63. textutils.serialize(
  64. {
  65. {
  66. display = "End Crystal",
  67. item = "minecraft:end_crystal",
  68. meta = "endc",
  69. value = 1
  70. },
  71. {
  72. item = "computercraft:peripheral",
  73. display = "Advanced Monitor",
  74. meta = "amon",
  75. damage = 4,
  76. value = 2
  77. }
  78. }
  79. )
  80. )
  81. error("No config detected, loading default config and shopdata.", 0)
  82. end
  83. local cfg = loadfile("/dconfig")()
  84.  
  85. if not cfg.kristAddress then
  86. error("No krist address in config!", 0)
  87. end
  88.  
  89. if not fs.exists("/json") then
  90. local ht = http.get("http://pastebin.com/raw/4nRg9CHU")
  91. fwrite("/json", ht.readAll())
  92. ht.close()
  93. end
  94. os.loadAPI("/json")
  95.  
  96. if not fs.exists("/jua") then
  97. local ht = http.get("https://raw.githubusercontent.com/justync7/Jua/master/jua.lua")
  98. fwrite("/jua", ht.readAll())
  99. ht.close()
  100. end
  101. os.loadAPI("/jua")
  102.  
  103. local shopdata = {}
  104. local adr_prefix = "ERROR"
  105.  
  106. local function load_shopdata()
  107. local f = fs.open("/shopdata", "r")
  108. shopdata = textutils.unserialize(f.readAll()) or {}
  109. f.close()
  110. if _G.whandle then
  111. _G.whandle.send(
  112. json.encode(
  113. {
  114. type = "DELTA-SHOPDATA",
  115. data = shopdata
  116. }
  117. )
  118. )
  119. end
  120. return shopdata
  121. end
  122.  
  123. local itemcache = {}
  124. local namecache = {}
  125.  
  126. local function getChests()
  127. local names = peripheral.getNames()
  128. local chests = {}
  129. for _, name in ipairs(names) do
  130. if not name:match("^turtle") then
  131. local wrapped = peripheral.wrap(name)
  132.  
  133. if wrapped.getTransferLocations then
  134. chests[name] = wrapped
  135. end
  136. end
  137. end
  138.  
  139. return chests
  140. end
  141.  
  142. local function load_itemcache()
  143. local nc = {}
  144. for name, chest in pairs(getChests()) do
  145. for slot, meta in pairs(chest.list()) do
  146. local thingy = tostring(meta.name) .. "/" .. tostring(meta.damage or 0)
  147. if not nc[thingy] then
  148. nc[thingy] = meta.count
  149. else
  150. nc[thingy] = nc[thingy] + meta.count
  151. end
  152. end
  153. end
  154. itemcache = nc
  155. return nc
  156. end
  157.  
  158. local function in_table(tab, dt)
  159. for k, v in pairs(tab) do
  160. if v == dt then
  161. return true
  162. end
  163. end
  164. return false
  165. end
  166.  
  167. local function getOurTurtle(chest)
  168. for i, v in ipairs(chest.getTransferLocations()) do
  169. if v:match("^turtle") then
  170. return v
  171. end
  172. end
  173. end
  174.  
  175. --Drawing code from TwijnMall. Thanks, Twijn!
  176. local function draw()
  177. local displayNameWidth = 0
  178. local stockWidth = 0
  179. local priceWidth = 0
  180. local metaWidth = 0
  181. local w, h = mon.getSize()
  182.  
  183. load_itemcache()
  184. mon.setBackgroundColor(colors.black)
  185. mon.clear()
  186. mon.setTextScale(0.5)
  187. mon.setBackgroundColor(colors.white)
  188. mon.setTextColor(colors.black)
  189. mon.setCursorPos(1, 1)
  190. mon.clearLine()
  191. mon.setCursorPos(1, 2)
  192. mon.clearLine()
  193. cwrite(cfg.shopName, 1)
  194. mon.setTextColor(colors.lightGray)
  195. cwrite("deltashop, by Chervilpaw", 2)
  196. --
  197. --[[for k, v in pairs(shopdata) do
  198. mon.setBackgroundColor(colors.black)
  199. mon.setTextColor(colors.white)
  200. writething(v, itemcache[tostring(v.item) .. "/" .. tostring(v.damage or 0)], k + 3)
  201. end]]
  202. for i, v in pairs(shopdata) do
  203. if displayNameWidth < #v.display then
  204. displayNameWidth = #v.display
  205. end
  206. local stk = "0x"
  207. local prc = tonumber(v.value)
  208.  
  209. if math.floor(prc) == prc then
  210. prc = prc .. ".00"
  211. end
  212. if type(prc) == "number" and math.floor(prc * 10) == prc * 10 then
  213. prc = prc .. "0"
  214. end
  215. if type(prc) == "number" then
  216. prc = "" .. prc
  217. end
  218. prc = prc .. " kst"
  219.  
  220. if itemcache[tostring(v.item) .. "/" .. tostring(v.damage or 0)] ~= nil then
  221. stk = itemcache[tostring(v.item) .. "/" .. tostring(v.damage or 0)] .. "x"
  222. end
  223. if stockWidth < #stk then
  224. stockWidth = #stk
  225. end
  226. if priceWidth < #prc then
  227. priceWidth = #prc
  228. end
  229. if metaWidth < #(adr_prefix .. "-" .. tostring(v.meta) .. "@4g.kst") then
  230. metaWidth = #(adr_prefix .. "-" .. tostring(v.meta) .. "@4g.kst")
  231. end
  232. end
  233.  
  234. if displayNameWidth == 0 and stockWidth == 0 and priceWidth == 0 and metaWidth == 0 then
  235. local stamt = math.floor((w - 3) / 4)
  236. displayNameWidth, stockWidth, priceWidth, metaWidth = stamt, stamt, stamt, stamt
  237. end
  238.  
  239. if displayNameWidth == 0 and stockWidth == 0 and priceWidth == 0 and metaWidth == 0 then
  240. local stamt = math.floor((w - 3) / 4)
  241. displayNameWidth, stockWidth, priceWidth, metaWidth = stamt, stamt, stamt, stamt
  242. end
  243.  
  244. local multiplier = (w - 3) / (displayNameWidth + stockWidth + priceWidth + metaWidth + 6)
  245.  
  246. displayNameWidth = math.floor(displayNameWidth * multiplier)
  247. stockWidth = math.floor(stockWidth * multiplier)
  248. priceWidth = math.floor(priceWidth * multiplier)
  249. metaWidth = math.floor(metaWidth * multiplier)
  250.  
  251. -- The following defines the points where the "lines" are put in between each section (meaning +1 would be the next section, -1 would be the previous; 0 is blank space.)
  252. local displayNameStart = 2
  253. local stockStart = displayNameWidth + 3
  254. local priceStart = stockWidth + displayNameWidth + 4
  255. local metaStart = priceWidth + stockWidth + displayNameWidth + 5
  256.  
  257. mon.setBackgroundColor(colors.black)
  258. mon.setTextColor(colors.lightGray)
  259. mon.setCursorPos(displayNameStart + 2, 3)
  260. mon.write("Name")
  261. mon.setCursorPos(priceStart - 6, 3)
  262. mon.write("Stock")
  263. mon.setCursorPos(metaStart - 6, 3)
  264. mon.write("Price")
  265. mon.setCursorPos(w - 9, 3)
  266. mon.write("Address")
  267.  
  268. local line = 4
  269. for i, item in pairs(shopdata) do
  270. if line >= 3 then
  271. local stk = "0x"
  272. local prc = tonumber(item.value)
  273.  
  274. if math.floor(prc) == prc then
  275. prc = prc .. ".00"
  276. end
  277. if type(prc) == "number" and math.floor(prc * 10) == prc * 10 then
  278. prc = prc .. "0"
  279. end
  280. if type(prc) == "number" then
  281. prc = "" .. prc
  282. end
  283. prc = prc .. " kst"
  284.  
  285. mon.setBackgroundColor(colors.black)
  286. mon.setTextColor(colors.white)
  287.  
  288. if itemcache[tostring(item.item) .. "/" .. tostring(item.damage or 0)] then
  289. stk = itemcache[tostring(item.item) .. "/" .. tostring(item.damage or 0)] .. "x"
  290. end
  291. mon.setCursorPos(displayNameStart + 2, line)
  292. mon.clearLine()
  293. mon.write(item.display)
  294. local otc = mon.getTextColor()
  295. if stk == "0x" then
  296. mon.setTextColor(colors.red)
  297. else
  298. mon.setTextColor(otc)
  299. end
  300. mon.setCursorPos(priceStart - 1 - #stk, line)
  301. mon.write(stk)
  302. mon.setTextColor(otc)
  303. mon.setCursorPos(metaStart - 1 - #prc, line)
  304. mon.write(prc)
  305. mon.setCursorPos(w - 2 - #(adr_prefix .. "-" .. tostring(item.meta) .. "@4g.kst"), line)
  306. mon.write(adr_prefix .. "-" .. tostring(item.meta) .. "@4g.kst")
  307. end
  308. line = line + 1
  309. if line >= h - 1 then
  310. break
  311. end
  312. end
  313. end
  314.  
  315. local function drawItems(name, amt, dmg)
  316. local required = amt
  317. for nam, chest in pairs(getChests()) do
  318. local target
  319. for i, v in pairs(chest.getTransferLocations()) do
  320. if v:find("turtle") then
  321. target = v
  322. break
  323. end
  324. end
  325. if not target then
  326. error("Could not find turtle on chest '" .. tostring(nam) .. "'!")
  327. end
  328. for slot, meta in pairs(chest.list()) do
  329. if meta.name == name and (not dmg or meta.damage == dmg) then
  330. required = required - chest.pushItems(target, slot, required)
  331. turtle.drop()
  332. if required <= 0 then
  333. break
  334. end
  335. end
  336. end
  337. end
  338. end
  339.  
  340. http.websocketAsync("ws://ws.spaceball.cf:8081")
  341.  
  342. jua.on(
  343. "websocket_success",
  344. function(e, url, handle)
  345. _G.whandle = handle
  346. end
  347. )
  348.  
  349. jua.on(
  350. "terminate",
  351. function()
  352. error("deltashop terminated.", 0)
  353. end
  354. )
  355.  
  356. jua.on(
  357. "websocket_closed",
  358. function(ev, url)
  359. _G.whandle = nil
  360. print("[warning] websocket closed, reopening in 3 seconds!")
  361. sleep(3)
  362. http.websocketAsync(url)
  363. end
  364. )
  365.  
  366. jua.on(
  367. "websocket_message",
  368. function(e, url, data)
  369. if data then
  370. local j = json.decode(data)
  371. if type(j) == "table" then
  372. if j.type == "DELTA-REJECTNAME" then
  373. error("Shop name '" .. tostring(cfg.shopName) .. "' already in use!", 0)
  374. elseif j.type == "DELTA-SENDCODE" then
  375. whandle.send(
  376. json.encode(
  377. {
  378. type = "DELTA-CODE",
  379. code = pkey,
  380. kristadr = cfg.kristAddress,
  381. shopName = cfg.shopName
  382. }
  383. )
  384. )
  385. load_shopdata()
  386. elseif j.type == "DELTA-CODERECV" then
  387. pkey = j.code
  388. fwrite("/.pkey", j.code)
  389. adr_prefix = j.prefix
  390. load_shopdata()
  391. load_itemcache()
  392. draw()
  393. print("[log] connection with websocket succeeded! ")
  394. elseif j.type == "DELTA-BUY" then
  395. drawItems(j.id, j.amount, j.damage)
  396. print(tostring(j.amount) .. " of " .. j.name .. " bought!")
  397. load_itemcache()
  398. load_shopdata()
  399. draw()
  400. elseif j.type == "DELTA-MESSAGE" and type(cbx) == "table" then
  401. cbx.tell(j.target, j.message, "[deltaShop]")
  402. end
  403. end
  404. end
  405. end
  406. )
  407.  
  408. jua.setInterval(
  409. function()
  410. load_shopdata()
  411. draw()
  412. end,
  413. 10
  414. )
  415.  
  416. if type(cfg.redstoneHeartbeat) == "string" then
  417. jua.setInterval(
  418. function()
  419. rs.setOutput(cfg.redstoneHeartbeat, not rs.getOutput(cfg.redstoneHeartbeat))
  420. end,
  421. 5
  422. )
  423. end
  424.  
  425. jua.run()
  426. end
  427. )
  428.  
  429. if not ok then
  430. local wa, ha = mon.getSize()
  431. local hh = math.floor(ha / 2)
  432. printError("deltashop errored!: " .. tostring(err))
  433. mon.setBackgroundColor(colors.red)
  434. mon.setTextColor(colors.white)
  435. mon.clear()
  436. cwrite("deltashop errored!", hh - 1)
  437. cwrite(tostring(err), hh)
  438. return
  439. end
Advertisement
Add Comment
Please, Sign In to add comment