View difference between Paste ID: 0nEpDnHK and hD94N6dV
SHOW: | | - or go back to the newest paste.
1
-- made by the most epicest programmer ME (AKA HAPPYSUNCHILD)
2
-- shrug client
3
4
local UpdateTime = 0.2
5
6
-- alpha goes from 0 to 255, 255 being fully opaque
7
8
local SaveMaxRenderDistance = 50
9
local SaveScanned = true
10
local TracerAlpha = 20
11
local ESPAlpha = 50
12
13
local flightEnabled = false
14
local flightPower = 4
15
16
local link = peripheral.find("neuralInterface")
17
18
if not link then error("No neural interface found!", 0) end
19
if not link.hasModule("plethora:scanner") then error("No block scanner found!", 0) end
20
if not link.hasModule("plethora:glasses") then error("No overlay glasses found!", 0) end
21
if not link.hasModule("plethora:sensor") then error("No entity sensor found!", 0) end
22
if not link.hasModule("plethora:chat") then error("No chat recorder found!", 0) end
23
if not link.hasModule("plethora:kinetic") then error("No kinetic augentation found!", 0) end
24
25
local modem = peripheral.find("modem")
26
local hasgps = (gps.locate() ~= nil)
27
28
link.canvas3d().clear()
29
local canvas3d = link.canvas3d().create()
30
local canvas = link.canvas()
31
32
canvas.clear()
33
34
local carrierID = nil
35
local metaData = {}
36
37
for i, v in pairs(link.sense()) do
38
    if v.x == 0 and v.y == 0 and v.z == 0 then
39
        carrierID = v.id
40
        break
41
    end
42
end
43
44
local scannable = {}
45
local scanned = {}
46
local broadcastedScanned = {}
47
48
local colorremap = {
49
    red = 0xFF0000FF,
50
    green = 0x009900FF,
51
    blue = 0x0000FFFF,
52
    purple = 0x9900FFFF,
53
    pink = 0xF478FFFF,
54
    orange = 0xFF8000FF,
55
    yellow = 0xFFFF00FF,
56
    teal = 0x00FFEAFF,
57
    magenta = 0xF200EEFF,
58
    brown = 0x804B24FF,
59
    black = 0x0D0D0DFF,
60
    white = 0xE9E9E9FF,
61
    lime = 0x00FF00FF,
62
    cyan = 0x094D4AFF,
63
    maroon = 0x520808FF,
64
    gray = 0x55555555FF,
65
    grey = 0x55555555FF,
66
    dark_gray = 0x111111FF,
67
    dark_grey = 0x111111FF
68
}
69
70
local texts = {}
71
72
local function Split(inputstr, sep)
73
    if sep == nil then
74
        sep = "%s"
75
    end
76
77
    local t = {}
78
    for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
79
        table.insert(t, str)
80
    end
81
    return t
82
end
83
84
local function getGPSLocation()
85
    local gx, gy, gz = gps.locate()
86
87
    if gx ~= nil then
88
        hasgps = true
89
        local fx, fy, fz = math.floor(gx), math.floor(gy - 1.62), math.floor(gz)
90
91
        return { x = fx, y = fy, z = fz }
92
    else
93
        hasgps = false
94
        return { x = 0, y = 0, z = 0 }
95
    end
96
end
97
98
local function load(dir)
99
    if fs.exists(dir) then
100
        local toScan = {}
101
102
        local file = fs.open(dir, "r")
103
104
        repeat
105
            local line = file.readLine()
106
107
            if line then
108
                local args = Split(line, "->")
109
110
                local color = tonumber(args[1])
111
                local block = args[2]
112
                local alias = args[3]
113
                local order = tonumber(args[4])
114
                local lookfortag = args[5]
115
                local type = args[6]
116
117
                print("Loading scannable with args: ", color, block, alias, order, lookfortag, type)
118
119
                if color and block and alias and order then
120
                    toScan[color] = { name = block, alias = alias, order = order,
121
                        lookfortag = lookfortag, type = type }
122
                end
123
            end
124
        until line == nil
125
126
        scannable = toScan
127
128
        for alias, text in pairs(texts) do
129
            text.remove()
130
131
            texts[alias] = nil
132
        end
133
134
        for color, v in pairs(scannable) do
135
            local text = canvas.addText({ 0, v.order * 6 }, v.alias .. ": 0")
136
            text.setShadow(true)
137
            text.setColour(color)
138
            text.setScale(0.6)
139
140
            texts[v.alias] = text
141
        end
142
143
        local lastLoadedFile = fs.open("shrug_saved/lastloaded.txt", "w")
144
145
        lastLoadedFile.write(dir)
146
147
        lastLoadedFile.close()
148
149
        link.tell("Successfully loaded file " .. dir .. " into scan list.")
150
    else
151
        link.tell("File " .. dir .. " doesn't exist.")
152
    end
153
end
154
155
local function drawLine(object, blockDesync)
156
    local w = metaData.withinBlock
157
158
    if not blockDesync then
159
        w = { x = 0, y = 0, z = 0 }
160
    end
161
162
    local line = canvas3d.addLine({ 0, -1, 0 }, { object.x - w.x + 0.5, object.y - w.y + 0.5, object.z - w.z + 0.5 },
163
        object.thicc,
164
        object.color)
165
    line.setDepthTested(false)
166
    line.setAlpha(TracerAlpha)
167
168
    local box = canvas3d.addBox(object.x - w.x, object.y - w.y, object.z - w.z, 1, 1, 1, object.color)
169
    box.setDepthTested(false)
170
    box.setAlpha(ESPAlpha)
171
end
172
173
local function drawLines(vList)
174
    canvas3d.clear()
175
176
    for i, v in pairs(vList) do
177
        drawLine(v, true)
178
    end
179
end
180
181
local function drawCounts(cList)
182
    for alias, count in pairs(cList) do
183
        if texts[alias] then
184
            texts[alias].setText(alias .. ": " .. count)
185
        end
186
    end
187
end
188
189
local function main()
190
    link.tell("¯\\_('-')_/¯ client")
191
192
    link.capture(".find")
193
    link.capture(".fly")
194
    link.capture(".shrug")
195
    link.capture(".xray")
196
197
    if modem then
198
        if hasgps then
199
            link.tell("Modem with gps detected.")
200
        else
201
            link.tell("Modem without gps detected.")
202
        end
203
    else
204
        link.tell("No modem detected.")
205
    end
206
207
    if not fs.exists("shrug_saved") then
208
        fs.makeDir("shrug_saved")
209
    end
210
211
    if not fs.exists("shrug_saved/xray_saves") then
212
        fs.makeDir("shrug_saved/xray_saves")
213
    end
214
215
    if not fs.exists("shrug_saved/findsettings.txt") then
216
        local file = fs.open("shrug_saved/findsettings.txt", "w")
217
218
        file.close()
219
220
        link.tell("Last loaded file not detected.")
221
        link.tell("Assuming first time use. `Use .shrug help` in chat to get further information")
222
    else
223
        link.tell("Loading last loaded save...")
224
225
        local lastLoaded = fs.open("shrug_saved/findsettings.txt", "r")
226
227
        local dir = lastLoaded.readLine()
228
229
        lastLoaded.close()
230
231
        if dir then
232
            load(dir)
233
        else
234
            link.tell("Could not find last loaded save.")
235
        end
236
    end
237
238
    if not fs.exists("shrug_saved/flightsettings.txt") then
239
        local file = fs.open("shrug_saved/flightsettings.txt", "w")
240
241
        file.writeLine(tostring(flightPower))
242
        file.writeLine(tostring(flightEnabled))
243
244
        file.close()
245
    else
246
        local fsettings = fs.open("shrug_saved/flightsettings.txt", "r")
247
248
        flightPower = tonumber(fsettings.readLine()) or 4
249
        flightEnabled = fsettings.readLine() == "true"
250
251
        fsettings.close()
252
    end
253
254
    term.clear()
255
    term.setCursorPos(1, 1)
256
257
    while true do
258
        local blockList = {}
259
        local count = {}
260
261
        for _, key in pairs(scannable) do
262
            count[key.alias] = 0
263
        end
264
265
        local t = false
266
267
        for i, v in pairs(scannable) do
268
            if i or v then
269
                t = true
270
                break
271
            end
272
        end
273
274
        if t then
275
            local p = hasgps and getGPSLocation() or { x = 0, y = 0, z = 0 }
276
277
            for _, block in pairs(link.scan()) do
278
                for col, orename in pairs(scannable) do
279
                    if block.name == orename.name and
280
                        (
281
                        orename.lookfortag ~= nil and (block.state[orename.lookfortag] == orename.type) or
282
                            orename.lookfortag == nil) then
283
                        count[orename.alias] = (count[orename.alias] or 0) + 1
284
285
                        local blockData = {
286
                            x = block.x,
287
                            y = block.y,
288
                            z = block.z,
289
                            thicc = 1.5,
290
                            color = col
291
                        }
292
293
                        if hasgps and SaveScanned then
294
                            local position = { x = p.x + block.x, y = p.y + block.y, z = p.z + block.z }
295
296
                            scanned[("%s:%s:%s"):format(position.x, position.y, position.z)] = { x = position.x,
297
                                y = position.y, z = position.z, color = col, name = block.name }
298
299
                        end
300
301
                        table.insert(blockList, blockData)
302
                        break
303
                    end
304
                end
305
306
                if hasgps and SaveScanned then
307
                    local position = { x = p.x + block.x, y = p.y + block.y, z = p.z + block.z }
308
                    local scannedIndexValue = scanned[("%s:%s:%s"):format(position.x, position.y, position.z)]
309
310
                    if scannedIndexValue ~= nil and scannedIndexValue.name ~= block.name then
311
                        scanned[("%s:%s:%s"):format(position.x, position.y, position.z)] = nil
312
                    end
313
                end
314
            end
315
316
            canvas3d.recenter()
317
            drawLines(blockList)
318
            drawCounts(count)
319
320
            if hasgps and SaveScanned then
321
                local p = getGPSLocation()
322
323
                for coordString, data in pairs(scanned) do
324
                    local distance = math.sqrt((data.x - p.x) ^ 2 + (data.y - p.y) ^ 2 + (data.z - p.z) ^ 2)
325
326
                    if distance > 10 and distance < SaveMaxRenderDistance then
327
                        local reconstructedData = { x = data.x - p.x, y = data.y - p.y, z = data.z - p.z,
328
                            color = data.color,
329
                            thicc = 1.5 }
330
331
                        drawLine(reconstructedData, true)
332
                    end
333
                end
334
            end
335
        end
336
337
        sleep(UpdateTime)
338
    end
339
end
340
341
local function onterminate()
342
    while true do
343
        local event, message, pattern, uuid = os.pullEventRaw()
344
345
        if event == "terminate" then
346
            print("Clearing canvases and captures")
347
348
            canvas.clear()
349
            canvas3d.clear()
350
            link.clearCaptures()
351
            break
352
        elseif event == "chat_capture" then
353
            local args = Split(message)
354
355
            local com = args[2]
356
            local block = args[3]
357
            local alias = args[4]
358
            local color = args[5]
359
            local metadataTag = args[6]
360
            local type = args[7]
361
362
            if args[1] == ".find" then
363
                if com == "add" then
364
                    if block and alias and color then
365
                        if colorremap[color] then
366
                            color = colorremap[color]
367
                        end
368
369
                        color = tonumber(color)
370
371
                        if color == nil then link.tell("Unacceptable color!") else
372
                            if not scannable[color] then
373
                                if not texts[alias] then
374
                                    local hasBlock = false
375
376
                                    for i, v in pairs(scannable) do
377
                                        if v.name == block and v.lookfortag ~= nil and
378
                                            (v.lookfortag == metadataTag and v.type == type) then
379
                                            hasBlock = true
380
                                            break
381
                                        end
382
                                    end
383
384
                                    if not hasBlock then
385
                                        local c = 0
386
387
                                        for i, v in pairs(scannable) do
388
                                            c = c + 1
389
                                        end
390
391
                                        scannable[color] = { name = block, alias = alias, order = c,
392
                                            lookfortag = metadataTag,
393
                                            type = type }
394
395
                                        local text = canvas.addText({ 0, scannable[color].order * 6 },
396
                                            scannable[color].alias .. ": 0")
397
                                        text.setShadow(true)
398
                                        text.setColour(color)
399
                                        text.setScale(0.6)
400
401
                                        texts[alias] = text
402
                                        link.tell("Successfully added " .. block .. " to scan list.")
403
                                    else
404
                                        link.tell("Can't scan for the same block multiple times!")
405
                                    end
406
                                else
407
                                    link.tell("Alias already taken!")
408
                                end
409
                            else
410
                                link.tell("Color already taken!")
411
                            end
412
                        end
413
                    end
414
                elseif com == "remove" then
415
                    if block then
416
                        local found = nil
417
418
                        for color, v in pairs(scannable) do
419
                            if v.name == block then
420
                                found = scannable[color]
421
                                scannable[color] = nil
422
                            end
423
                        end
424
425
                        if found then
426
                            for color, v in pairs(scannable) do
427
                                if v.order > found.order then
428
                                    scannable[color].order = v.order - 1
429
430
                                    if texts[v.alias] then
431
                                        texts[v.alias].setPosition(0, v.order * 6)
432
                                    end
433
                                end
434
                            end
435
436
                            if texts[found.alias] then
437
                                texts[found.alias].remove()
438
                                texts[found.alias] = nil
439
                            end
440
441
                            link.tell("Successfully removed " .. block .. " from scan list.")
442
                        else
443
                            link.tell(block .. " not found.")
444
                        end
445
                    else
446
                        link.tell("Missing second argument!")
447
                    end
448
                elseif com == "list" then
449
                    local c = 0
450
451
                    for i, v in pairs(scannable) do
452
                        c = c + 1
453
                    end
454
455
                    if c == 0 then
456
                        link.tell("There are currently no blocks being tracked.")
457
                    else
458
                        local str = "blocks "
459
460
                        local i = 0
461
462
                        for color, v in pairs(scannable) do
463
                            if i == 0 then
464
                                str = str .. ("%s"):format(v.name)
465
                            elseif i == c - 1 then
466
                                str = str .. (" and %s"):format(v.name)
467
                            else
468
                                str = str .. (", %s"):format(v.name)
469
                            end
470
471
                            i = i + 1
472
                        end
473
474
                        str = str .. " are being tracked."
475
476
                        link.tell(str)
477
                    end
478
479
                elseif com == "save" then
480
                    if not block:lower():find("startup") then
481
                        if not fs.exists("shrug_saved/xray_saves/" .. block .. ".xray") then
482
                            local file = fs.open("shrug_saved/xray_saves/" .. block .. ".xray", "w")
483
484
                            for color, v in pairs(scannable) do
485
                                local saveLine = color .. "->" .. v.name .. "->" .. v.alias .. "->" .. v.order
486
487
                                if v.lookfortag and v.type then
488
                                    saveLine = saveLine .. "->" .. v.lookfortag .. "->" .. v.type
489
                                end
490
491
                                file.writeLine(saveLine)
492
                            end
493
494
                            file.close()
495
496
                            link.tell("Saved " .. block .. " successfully")
497
                        else
498
                            link.tell("Can't overwrite file " .. block)
499
                        end
500
                    else
501
                        link.tell("Can't save as " .. block)
502
                    end
503
                elseif com == "delete" then
504
                    if not block:lower():find("startup") then
505
                        if fs.exists("shrug_saved/xray_saves/" .. block .. ".xray") then
506
                            fs.delete("shrug_saved/xray_saves/" .. block .. ".xray")
507
508
                            link.tell("File " .. block .. " successfully deleted.")
509
                        else
510
                            link.tell("File " .. block .. " doesn't exist.")
511
                        end
512
                    else
513
                        link.tell("Can't delete file " .. block)
514
                    end
515
                elseif com == "load" then
516
                    load("shrug_saved/xray_saves/" .. block .. ".xray")
517
                elseif com == "help" then
518
                    link.tell("Use .find add <block name> <block alias> <color hex> to add blocks to be scanned")
519
                    link.tell("Use .find remove <block name> to remove block from being scanned")
520
                    link.tell("Use .find save <filename> to save the current scan list")
521
                    link.tell("Use .find delete <filename> to delete a save")
522
                    link.tell("Use .find load <filename> to load a saved scan list into the curernt scan list")
523
                    link.tell("Use .find clear to clear all canvases and to reset the scan list")
524
                    link.tell("Use .find alpha <tracers/block> <number> to change the alpha")
525
                    link.tell("Use .find scantimer <number> to change how frequent it will scan")
526
                elseif com == "saves" then
527
                    local list = fs.list("shrug_saved/xray_saves")
528
529
                    local c = 0
530
531
                    for i, v in pairs(list) do
532
                        c = c + 1
533
                    end
534
535
                    if c == 0 then
536
                        link.tell("There are currently no saves.")
537
                    else
538
                        local str = "Saves "
539
540
                        local i = 0
541
542
                        for _, file in pairs(list) do
543
                            if file ~= "lastloaded.txt" or file ~= "flightsettings.txt" then
544
                                if i == 0 then
545
                                    str = str .. ("%s"):format(file)
546
                                elseif i == c - 1 then
547
                                    str = str .. (" and %s"):format(file)
548
                                else
549
                                    str = str .. (", %s"):format(file)
550
                                end
551
552
                                i = i + 1
553
                            end
554
                        end
555
556
                        str = str .. " are detected."
557
558
                        link.tell(str)
559
                    end
560
                elseif com == "clear" then
561
                    scannable = {}
562
                    scanned = {}
563
564
                    for alias, text in pairs(texts) do
565
                        text.remove()
566
567
                        texts[alias] = nil
568
                    end
569
570
                    canvas.clear()
571
                    canvas3d.clear()
572
                elseif com == "alpha" then
573
                    if tonumber(alias) then
574
                        if block == "tracers" then
575
                            TracerAlpha = (tonumber(alias) or 0)
576
                        elseif block == "block" then
577
                            ESPAlpha = (tonumber(alias) or 0)
578
                        else
579
                            link.tell("Not a valid alpha type.")
580
                        end
581
                    else
582
                        link.tell("Not a valid number.")
583
                    end
584
                elseif com == "scantimer" then
585
                    UpdateTime = math.min(math.max(tonumber(block) or 0.2, 0), 256)
586
                    link.tell("Changed scan time to " .. UpdateTime)
587
                elseif com == "savescanned" then
588
                    if block == "off" then
589
                        SaveScanned = false
590
                        link.tell("Turning off saving scanned blocks")
591
                    elseif block == "on" then
592
                        SaveScanned = true
593
                        link.tell("Turning on saving scanned blocks")
594
                    end
595
                elseif com == "scanneddistance" then
596
                    SaveMaxRenderDistance = math.min(math.max(tonumber(block) or 0, 0), 256)
597
                    link.tell("Changed max render distance for saved to " .. SaveMaxRenderDistance)
598
                else
599
                    link.tell("Not a supported command!")
600
                end
601
            elseif args[1] == ".fly" then
602
                if com == "toggle" then
603
                    flightEnabled = not flightEnabled
604
605
                    link.tell("Flight toggled; " .. tostring(flightEnabled))
606
607
                    local file = fs.open("shrug_saved/flightsettings.txt", "w")
608
609
                    file.writeLine(tostring(flightPower))
610
                    file.writeLine(tostring(flightEnabled))
611
612
                    file.close()
613
                elseif com == "power" then
614
                    flightPower = math.min(math.max(tonumber(block) or 1, 0), 4)
615
                    link.tell("Flight power changed to " .. tostring(flightPower) .. ".")
616
617
                    local file = fs.open("shrug_saved/flightsettings.txt", "w")
618
619
                    file.writeLine(tostring(flightPower))
620
                    file.writeLine(tostring(flightEnabled))
621
622
                    file.close()
623
                elseif com == "help" then
624
                    link.tell("Use `.fly power <number>` to change your fly speed")
625
                    link.tell("Use `.fly toggle` to toggle flight your flight ability")
626
                end
627
            elseif args[1] == ".shrug" then
628
                if com == "term" then
629
                    link.tell("Clearing canvases and captures")
630
631
                    canvas.clear()
632
                    canvas3d.clear()
633
                    link.clearCaptures()
634
                    break
635
                elseif com == "help" then
636
                    link.tell("Use `.find help` for more information on the xray ability")
637
                    link.tell("Use `.fly help` for more information on the fly ability")
638
                elseif com == "update" then
639
                    link.tell("Updating to latest version.")
640
641
                    if fs.exists("shrug") then
642
                        fs.delete("shrug")
643
                    end
644
645
                    shell.run("pastebin get hD94N6dV shrug")
646
                    break
647
                end
648
            end
649
        end
650
    end
651
end
652
653
local function getmeta()
654
    while true do
655
        if carrierID then
656
            metaData = link.getMetaByID(carrierID) or metaData
657
        else
658
            sleep()
659
        end
660
    end
661
end
662
663
local function fly()
664
    while true do
665
        if flightEnabled then
666
            if metaData ~= nil then
667
                if metaData.heldItem ~= nil then
668
                    if metaData.heldItem.getMetadata and metaData.isSneaking then
669
                        local itemData = ((metaData.heldItem and metaData.heldItem.getMetadata) or function()
670
                            return { name = "minecraft:air", displayName = "Air" }
671
                        end)()
672
673
                        if itemData.name == "plethora:neuralconnector" or itemData.name == "carryon:tile_item" or
674
                            itemData.name == "carryon:entity_item" then
675
                            link.launch(metaData.yaw, metaData.pitch, flightPower)
676
                        end
677
                    end
678
                end
679
            end
680
        end
681
682
        sleep()
683
    end
684
end
685
686
local function checkGPSStatus()
687
    while true do
688
        if not hasgps then
689
            hasgps = gps.locate() ~= nil
690
        end
691
692
        sleep()
693
    end
694
end
695
696
local function listenScanned()
697
698
end
699
700
parallel.waitForAny(onterminate, main, getmeta, fly, checkGPSStatus)
701