This commit is contained in:
Soph :3 2025-07-09 12:58:01 +00:00
parent b81149068b
commit 89a15d277f
5 changed files with 1026 additions and 0 deletions

278
carrotpay.lua Normal file
View file

@ -0,0 +1,278 @@
local pkey = settings.get("carrotpay.private_key")
if not switchcraft then
error("Must run on SwitchCraft 3")
end
sleep(1)
local sha256 = require("sha256")
if not chatbox or not chatbox.hasCapability("command") or not chatbox.hasCapability("tell") then
term.setBackgroundColor(colors.black)
term.clear()
term.setCursorPos(1,1)
term.setTextColor(colors.white)
print("Hey! it seems like you haven't registered chatbox")
print("If you don't have a chatbox key, run this command:")
term.setTextColor(colors.green)
print("/chatbox register")
term.setTextColor(colors.white)
print("Then copy that key and paste it here")
write("Alternatively, run ")
term.setTextColor(colors.blue)
print("chatbox register <key>")
term.setTextColor(colors.white)
local cbkey = read()
settings.set("chatbox.license_key",cbkey)
settings.save(".settings")
print("Key set. Press Any Key to reboot")
os.pullEvent("key")
os.reboot()
end
if not pkey then
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1,1)
term.setBackgroundColor(colors.lightGray)
print("Initial Setup ")
term.setBackgroundColor(colors.black)
print("First, CarrotPay needs your private key")
print("for the wallet you wish to use with CarrotPay")
print("Please enter your private key (not password) here")
local ipkey = read()
settings.set("carrotpay.private_key",ipkey)
settings.save(".settings")
term.clear()
term.setCursorPos(1,1)
term.setBackgroundColor(colors.lightGray)
print("Initial Setup ")
term.setBackgroundColor(colors.black)
print("Do you want to use our default startup script?")
print("(Y/N)")
print("Typing anything other than Y will be treated as no")
term.setTextColor(colors.red)
print("WARNING! Saying yes will OVERWRITE startup.lua")
term.setTextColor(colors.white)
local event = {os.pullEvent("key")}
if event[2] == keys.y then
print("Overwrote startup file.")
fs.delete("startup.lua")
local file = fs.open("startup.lua","w")
file.write([=[while true do
shell.run("]=]..shell.getRunningProgram()..[=[")
sleep(2)
end]=])
file.close()
end
print("CarrotPay Setup Requires a reboot.")
print("Press any key to reboot")
os.pullEvent("key")
os.reboot()
end
prt = require("cc.pretty").pretty_print
local owner =chatbox.getLicenseOwner()
local function makeaddressbyte(byte)
local byte = 48 + math.floor(byte/7)
return string.char(byte + 39 > 122 and 101 or byte > 57 and byte + 39 or byte)
end
local expect = require("cc.expect").expect
local function split(inputstr, sep)
expect(1,inputstr,"string")
expect(1,sep,"string","nil")
sep = sep or ","
local t={}
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
table.insert(t, str)
end
return t
end
local function make_address(key)
local protein = {}
local stick = sha256(sha256(key))
local n = 0
local link = 0
local v2 = "k"
repeat
if n<9 then protein[n] = string.sub(stick,0,2)
stick = sha256(sha256(stick)) end
n = n+1
until n==9
n=0
repeat
link = tonumber(string.sub(stick,1+(2*n),2+(2*n)),16) % 9
if string.len(protein[link]) ~= 0 then
v2 = v2 .. makeaddressbyte(tonumber(protein[link],16))
protein[link] = ''
n=n+1
else
stick = sha256(stick)
end
until n==9
return v2
end
local address = make_address(pkey)
local function get_balance(addr)
os.queueEvent("get_balance",addr)
_,balance,err = os.pullEvent("balance")
if balance == "error" then
prt(err)
return -1
end
return balance
end
local function pay(to,amt,mta)
if not mta then mta = "" end
mta = "username="..owner..";"..mta
amt = tonumber(amt)
local bal = get_balance(address)
if amt > bal then
chatbox.tell(owner,"Transaction failed. Not enough Krist","&6CarrotPay")
return false
else
os.queueEvent("make_transaction",to,amt,mta)
_,ok = os.pullEvent("transaction_complete")
return ok
end
end
local function handleWebSockets()
local id = -1
local r = http.post("https://krist.dev/ws/start","{\"privatekey\":\""..pkey.."\"}",{["content-type"]="application/json"})
local resp = textutils.unserialiseJSON(r.readAll())
r.close()
r = nil
if resp.ok then
socket = http.websocket(resp.url)
print("Connected to Krist Websockets")
id = id + 1
socket.send('{\"id\":'..id ..',\"type\":\"subscribe\",\"event\":\"ownTransactions\"}')
while true do
event = {os.pullEvent()}
if event[1] == "websocket_message" then
if event[2] == resp.url then
wsevent = textutils.unserialiseJSON(event[3])
if wsevent.event == "transaction" and wsevent.transaction.to == address then
local from = wsevent.transaction.from
local hasMessage = false
local hasError = false
local hasUsername = false
local message = ""
err = ""
if wsevent.transaction.metadata then
mta = split(wsevent.transaction.metadata,";")
for i,p in pairs(mta) do
if p:match("message") then
message = split(p,"=")[2]
hasMessage = true
end
if p:match("error") then
err = split(p,"=")[2]
hasError = true
end
if p:match("username") and not hasUsername then
from = split(p,"=")[2].." ("..wsevent.transaction.from..")"
hasUsername = true
end
end
end
msg2 = "You have received K"..wsevent.transaction.value.." from "..from
if hasMessage or hasError then
if hasMessage then
msg2 = msg2.."\nMessage: "..message
end
if hasError then
msg2 = msg2.."\nError: "..err
end
end
chatbox.tell(owner,msg2,"&6CarrotPay")
elseif wsevent.type == "keepalive" or wsevent.type == "response" then
else
end
end
elseif event[1] == "get_balance" then
id = id + 1
local rq = {
id = id,
type="address",
address=event[2]
}
socket.send(textutils.serialiseJSON(rq))
rspt =socket.receive()
rsp = textutils.unserialiseJSON(rspt)
if rsp.ok then
os.queueEvent("balance",rsp.address.balance)
else
os.queueEvent("balance","error",rsp)
end
elseif event[1] == "make_transaction" then
id = id + 1
local rq = {
id = id,
type="make_transaction",
to = event[2],
amount = event[3],
metadata = event[4],
}
socket.send(textutils.serialiseJSON(rq))
local c
repeat
c = socket.receive()
c = textutils.unserialiseJSON(c)
until c.type == "response"
os.queueEvent("transaction_complete",c.ok)
end
end
end
end
local function handleCommands()
while true do
local command = {os.pullEvent("command")}
if command[3] == "pay" and command[5].ownerOnly then
if command[4][1] == "--update" then
shell.run("wget https://raw.githubusercontent.com/scmcgowen/carrotpay/main/carrotpay.lua "..shell.getRunningProgram())
os.reboot()
end
if not command[4][1] then
chatbox.tell(command[2],"Specify who to pay","&6CarrotPay")
elseif not command[4][2] then
chatbox.tell(command[2],"Specify how much to pay","&6CarrotPay")
else
local c = false
command_copy = {table.unpack(command)}
mta = table.concat({select(3, unpack(command_copy[4]))}, " ")
local s = command[4][1]
if ((s:match("^k[a-z0-9]+$") or s:match("^[a-f0-9]+$")) and #s == 10) or (s:match("^[a-z0-9]@[a-z0-9]+$")) or s:match("^[%a%d]+@[%a%d]+%.kst$") or s:match("^[%a%d]+%.kst") then
c = pay(s,command[4][2],mta)
if c then
chatbox.tell(command[2],"Paid <:kst:665040403224985611>"..command[4][2].." to "..s,"&6CarrotPay")
end
elseif s:match("^[a-zA-Z0-9_]+$") and #s <16 then
c = pay(s.."@sc.kst",command[4][2],mta)
if c then
chatbox.tell(command[2],"Paid <:kst:665040403224985611>"..command[4][2] .. " to "..s,"&6CarrotPay")
end
else
chatbox.tell(command[2],"Invalid Krist Address","&6CarrotPay")
end
if not c then
chatbox.tell(command[2],"There was an error.","&6CarrotPay")
end
end
elseif command[3] == "request" and command[5].ownerOnly then
msg = table.concat({select(3,unpack(command[4]))}, " ")
if msg == "" then
chatbox.tell(command[4][1],owner.." wants <:kst:665040403224985611>"..command[4][2].." from you.\nPay to "..address,"&6CarrotPay")
else
chatbox.tell(command[4][1],owner.." wants <:kst:665040403224985611>"..command[4][2].." from you.\nPay to "..address.."\nMessage: "..msg,"&6CarrotPay")
end
chatbox.tell(owner,"Requested <:kst:665040403224985611>"..command[4][2].." from "..command[4][1],"&6CarrotPay")
elseif (command[3] == "bal" or command[3] == "balance") and command[5].ownerOnly then
local addr = command[4][1] or address
local bal = get_balance(addr)
chatbox.tell(owner,addr.." has a balance of <:kst:665040403224985611>"..bal,"&6CarrotPay")
end
end
end
_,e = pcall(parallel.waitForAny,handleWebSockets,handleCommands)
if socket then socket.close() end
printError(e)

439
jasper.lua Normal file
View file

@ -0,0 +1,439 @@
-- This is paid software, do not distribute, Rule 6.5
-- Settings, change them for different effects
local ownerUserName = "jasper_185" -- If set uses getMetaByName instead of getMetaOwner when getMetaOwner isn't available
local maxSpeed = 1 -- The speed of the last slot, note: it is impossible to go over speed 4, and trying to go over that limit will cause your movement direction to not sync up with your actual velocity "pushing" you towards the diagonals
local launchMult = 1 -- Higher values = stronger launch, may cause overshoot if too high
local baseSlotSpeed = 1 -- The base speed you got at, if set to 0 your slot 0 will not let you move at all, should be 0 if not using a keyboard module (WHY ARE YOU NOT USING IT? ITS AWESOME AND CHEAP)
local speedPower = 0 -- The power the speed is raised to (0 = constant speed, 1 = linear speed increase from each slot, 2 = exponential speed increase)
local sprintSpeedIncrease = 4 -- Whenever we are sprinting, how much faster do we go?
local gpsHover = true -- Do we use the GPS to stay still in the air while we are not moving?
local gpsStrength = 0.025 -- How strong is the GPS correction? (really doesn't need to be strong, as base hover is already really good and instead just makes it less stable)
local pitchChangesForward = false-- If you are looking up and pressing forward do you go up or do you go horizontal?
local doubleTapUpToToggle = 0.3 --t Whats the duration of time to toggle flight by spamming the up key? set to nil or to a negative number to disable and use a dedicated toggle key instead
local lagCompensation = true -- Do we try calculate the amount of lag we have, and try to compensate for that?
local smoothing = 0.65 -- How smooth is the flight? 0 = no smoothing, 1 = so smooth you will never start moving, 0.9 = pretty smooth
local autoDisengageOnGroundTouch = true -- Do we disable flight once we touch the ground?
-- Still settings, but more technical
local gravityCancelation = 0.08 -- How strong gravity is, too low and you will fall down, too high and you will shoot up (The constant I for the Y PID)
local drag = 0.98 -- What is the drag
local waterGravityCancelation = 0.01 -- Water version of the above
local PStrength = 1 -- Strenght of P in PD settings
local DStrength = 1 -- Strenght of D in PD settings
local rateLimitAtPower = 1.5 -- Going above this power rate limits us
local yMult = 0.5 -- Launching in the Y dir is less strong
local elytraMult = 0.4 -- While elytra flying all dirs are less strong
local maxXZRatio = 0.8 -- How much X and Z axes can be reduced for more power in the Y axis before stopping, lowering this too much will give bad controll when going at high speeds, but having it too high will make hoving slightly less stable
-- Keybinds
local forwardKey = keys.w;
local backKey = keys.s;
local leftKey = keys.a;
local rightKey = keys.d;
local upKey = keys.space;
local downKey = keys.leftShift;
local SprintKey = keys.r; -- Lets you hold this key to enable sprint mode, so it also lets you go at sprint speed backwards
local toggleFlightKey = keys.g; -- Only used when doubleTapSpaceToToggle is set to false
-- Internal code, don't change unless you know what you are doing!
local modules = peripheral.wrap("back")
local hasKeyboard = modules.hasModule("plethora:keyboard")
local pressedKeys = {}
-- Global for isActive
local flightActive = false
local lastGroundTouch = os.clock()
local function isFlightActiveRaw(meta)
if hasKeyboard then
if autoDisengageOnGroundTouch then
if lastGroundTouch + 0.5 < os.clock() and not meta.isAirborne then
flightActive = false
end
if not meta.isAirborne then
lastGroundTouch = os.clock()
end
end
return flightActive -- Toggled by keyboard module
end
-- Enable flight when sneaking and having a decent Y vel so it doesn't activate when just holding shift on a block
if meta.isSneaking then
if not flightActive then
flightActive = math.abs(meta.motionY) > 0.2
end
else
flightActive = false
end
return flightActive
end
-- Calculates your desired speed
local isSprinting = false
local function getSpeedRaw(meta)
local selectedSlot = meta.heldItemSlot
local speed = math.pow((selectedSlot + baseSlotSpeed) / (9 + baseSlotSpeed), speedPower) * maxSpeed;
if meta.isSprinting or pressedKeys[SprintKey] then
isSprinting = true
elseif not pressedKeys[forwardKey] and not pressedKeys[backKey] and not pressedKeys[leftKey] and not pressedKeys[rightKey] and not pressedKeys[upKey] and not pressedKeys[downKey] then -- Not great, but oh well
isSprinting = false
end
if isSprinting then
speed = speed * sprintSpeedIncrease
end
return speed
end
-- Calculates your desired movement direction
local gpsX, gpsY, gpsZ
local function getDesiredDirRaw(meta)
-- If you want a goto function, you can calculate the direction to the next waypoint and return that here for example
if not hasKeyboard then
local pitch = -math.rad(meta.pitch)
local yaw = math.rad(meta.yaw)
local dx = -math.sin(yaw) * math.cos(pitch)
local dy = math.sin(pitch)
local dz = math.cos(yaw) * math.cos(pitch)
return dx, dy, dz
else
local pitch = -math.rad(meta.pitch)
if not pitchChangesForward then pitch = 0 end
local yaw = math.rad(meta.yaw)
local fx = -math.sin(yaw) * math.cos(pitch)
local fy = math.sin(pitch)
local fz = math.cos(yaw) * math.cos(pitch)
local sx = math.cos(yaw)
local sz = math.sin(yaw)
local forward = (pressedKeys[forwardKey] and 1 or 0) + (pressedKeys[backKey] and -1 or 0)
local left = (pressedKeys[leftKey] and 1 or 0) + (pressedKeys[rightKey] and -1 or 0)
local up = (pressedKeys[upKey] and 1 or 0) + (pressedKeys[downKey] and -1 or 0)
return fx * forward + sx * left,
fy * forward + up,
fz * forward + sz * left
end
end
-- Below is the actual math / logic, i don't recommend changing this
-- Overrides
local defaultIsFlightActiveOverride = function(defaultFlightActive, meta) return defaultFlightActive end
local defaultGetSpeedOverride = function(defaultSpeed, meta) return defaultSpeed end
local defaultGetDesiredDirOverride = function(defaultDirX, defaultDirY, defaultDirZ, meta) return defaultDirX, defaultDirY, defaultDirZ end
local defaultMotionOverride = function(defaultMotionX, defaultMotionY, defaultMotionZ, meta) return defaultMotionX, defaultMotionY, defaultMotionZ end
local isFlightActiveOverride = defaultIsFlightActiveOverride
local getSpeedOverride = defaultGetSpeedOverride
local getDesiredDirOverride = defaultGetDesiredDirOverride
local motionOverride = defaultMotionOverride
local function isFlightActive(meta)
return isFlightActiveOverride(isFlightActiveRaw(meta), meta)
end
local function getSpeed(meta)
return getSpeedOverride(getSpeedRaw(meta), meta)
end
local function getDesiredDir(meta)
local x, y, z = getDesiredDirRaw(meta)
return getDesiredDirOverride(x, y, z, meta)
end
-- utility function to convert the launch(yaw, pitch, speed) into a launch(x, y, z)
local lastLaunchX = 0
local lastLaunchY = 0
local lastLaunchZ = 0
local function launch(x, y, z, isElytraFlying)
lastLaunchX = x
lastLaunchY = y
lastLaunchZ = z
y = y / yMult
if isElytraFlying then
x = x / elytraMult
y = y / elytraMult
z = z / elytraMult
end
local speed = math.sqrt(x * x + y * y + z * z)
if speed <= 0 then return end
local launchSpeed = speed
if launchSpeed > 4 then launchSpeed = 4 end
if launchSpeed > rateLimitAtPower then
launchSpeed = rateLimitAtPower
end
if launchSpeed ~= speed then
-- reduce X and Z, but keep Y the same
-- This way hover is more stable when moving around quickly
-- ((x*x+z*z)*M + y * y)^0.5 = launchSpeed
if math.abs(y) < launchSpeed then
local ratio = (launchSpeed * launchSpeed - y * y) / (x * x + z * z)
if ratio > maxXZRatio then
lastLaunchX = lastLaunchX * ratio
lastLaunchZ = lastLaunchZ * ratio
speed = launchSpeed
end
elseif maxXZRatio <= 0 then
-- Okay, just using the Y is requiring more speed than we have
-- Set x and z to 0, and just maximize Y for what we can. not ideal.
x = 0
z = 0
speed = math.abs(y)
end
end
local yaw = math.deg(math.atan2(-x, z))
local pitch = math.deg(math.asin(-y / speed))
if yaw ~= yaw or pitch ~= pitch then return end -- Check for NaN's
if launchSpeed ~= speed then
local ratio = launchSpeed / speed
lastLaunchX = lastLaunchX * ratio
lastLaunchY = lastLaunchY * ratio
lastLaunchZ = lastLaunchZ * ratio
end
coroutine.resume(coroutine.create(function() modules.launch(yaw, pitch, launchSpeed) end))
end
-- Gps locking globals
local lockY -- Do you want to lock your coord?
local desiredGpsY -- What are your locked coords?
-- For smoothing
local lastDesiredX, lastDesiredY, lastDesiredZ = 0, 0, 0
local function flyLoop()
local lastIngame = os.epoch("ingame")
local lastUtc = os.epoch("utc")
local expectedYVel = 0
while true do
local meta
if ownerUserName and not modules.getMetaOwner then
meta = modules.getMetaByName(ownerUserName)
else
meta = modules.getMetaOwner()
end
-- Fix inconsistency with meta input (it can be from before the launch, or after the launch, so add the expected launch speed if we are behind)
if math.abs(meta.motionY - expectedYVel) < math.abs(meta.motionY - expectedYVel - lastLaunchY) then
meta.motionX = meta.motionX + lastLaunchX
meta.motionY = meta.motionY + lastLaunchY
meta.motionZ = meta.motionZ + lastLaunchZ
end
local gravity
if meta.isInWater then
gravity = waterGravityCancelation
else
gravity = gravityCancelation
end
expectedYVel = (meta.motionY - gravity) * drag
local nowIngame = os.epoch("ingame")
local nowUtc = os.epoch("utc")
local estimatedServerTicks = (nowIngame - lastIngame) / 3600
local estimatedClientTicks = math.floor((nowUtc - lastUtc) / 50 + 0.5)
lastIngame = nowIngame
lastUtc = lastUtc + estimatedClientTicks * 50
estimatedServerTicks = 1 -- Its better this way
if not lagCompensation then estimatedClientTicks = 1 end
if not meta then
modules = peripheral.wrap("back") -- Fix it in case of death
-- But also don't sleep as FOR SOME REASON that can happen when you fly into unloaded chunks
-- And also don't restart for the same reason.. UGH!
-- There is just no good way to handle this
end
if meta and isFlightActive(meta) then
local speed = getSpeed(meta)
-- Calculate D
local cx = -meta.motionX * drag * DStrength
local cy = -(meta.motionY - gravity) * drag * DStrength
local cz = -meta.motionZ * drag * DStrength
local dx, dy, dz = getDesiredDir(meta)
-- Apply speed
dx = dx * speed
dy = dy * speed
dz = dz * speed
dx, dy, dz = motionOverride(dx, dy, dz, meta)
-- Apply smoothing
local canLockY = dy == 0 -- We need this before smoothing for gps hover
dx = dx + (lastDesiredX - dx) * smoothing
dy = dy + (lastDesiredY - dy) * smoothing
dz = dz + (lastDesiredZ - dz) * smoothing
lastDesiredX = dx
lastDesiredY = dy
lastDesiredZ = dz
-- Calculate P
dx = dx * PStrength
dy = dy * PStrength
dz = dz * PStrength
if gpsHover then
-- Only start to lock the coords once we have slowed down to prevent a "jerk back" effect due to the GPS coords we have being slightly behind
lockY = canLockY and math.abs(dy) <= 0.001 and (lockY or math.abs(meta.motionY) < (0.1 * estimatedServerTicks))
-- Clear if it we do not want to lock the axis
if not lockY then desiredGpsY = nil end
-- Set our desired movement direction towards our locked position
if lockY and desiredGpsY and gpsY then dy = (desiredGpsY - gpsY) * gpsStrength end
end
launch(
(cx + dx) * launchMult,
(cy + dy) * launchMult + gravity * (estimatedServerTicks + estimatedClientTicks - 1),
(cz + dz) * launchMult,
meta.isElytraFlying
)
else
lockY = false
desiredGpsY = nil
end
end
end
local lastUpKeyPressed = 0
local function keyboardInputLoop()
while true do
local data = {os.pullEvent()}
if data[1] == "key_up" then
pressedKeys[data[2]] = false
-- Toggle flight logic
if doubleTapUpToToggle and doubleTapUpToToggle > 0 then
if data[2] == upKey then
lastUpKeyPressed = os.epoch("utc")
end
end
elseif data[1] == "key" then
-- Toggle flight logic
if doubleTapUpToToggle and doubleTapUpToToggle > 0 then
if data[2] == upKey then
local now = os.epoch("utc")
if now - doubleTapUpToToggle * 1000 < lastUpKeyPressed then
flightActive = not flightActive
lastUpKeyPressed = 0
end
end
elseif data[2] == toggleFlightKey and not pressedKeys[data[2]] then
flightActive = not flightActive
end
pressedKeys[data[2]] = true
end
end
end
local overridesRequireGPS = false
local function updateGpsLoop()
while true do
if lockY or overridesRequireGPS then
overridesRequireGPS = false
gpsX, gpsY, gpsZ = gps.locate()
if not gpsX or gpsX ~= gpsX then -- NaN(i)?
gpsX = nil
gpsY = nil
gpsZ = nil
elseif not desiredGpsY then
desiredGpsY = gpsY
end
end
sleep(0.2) -- We don't need to spam the GPS so hard
end
end
---Gets the current estimated coords, can return nil when calling for the first couple time or gps failed
---@return number | nil x
---@return number | nil y
---@return number | nil z
local function getCoords()
overridesRequireGPS = true
return gpsX, gpsY, gpsZ
end
local function doFlyloop()
parallel.waitForAny(flyLoop, keyboardInputLoop, updateGpsLoop)
end
local args = {...}
if #args > 0 then
print("running as flight library (args detected), call doFlightLoop to start flying!")
---@param overrideFunc (fun(defaultIsFlightActive: boolean, playerMeta: table): boolean) | nil
local function setIsFlightActiveOverride(overrideFunc)
isFlightActiveOverride = overrideFunc or defaultIsFlightActiveOverride
end
---@param overrideFunc (fun(defaultSpeed: number, playerMeta: table): number) | nil
local function setGetSpeedOverride(overrideFunc)
getSpeedOverride = overrideFunc or defaultGetSpeedOverride
end
---@param overrideFunc (fun(defaultDesiredX: number, defaultDesiredY: number, defaultDesiredZ: number, playerMeta: table): number, number, number) | nil
local function setGetDesiredDirOverride(overrideFunc)
getDesiredDirOverride = overrideFunc or defaultGetDesiredDirOverride
end
---@param overrideFunc (fun(defaultMotionX: number, defaultMotionY: number, defaultMotionZ: number, playerMeta: table): number, number, number) | nil
local function setMotionOverride(overrideFunc)
motionOverride = overrideFunc or defaultMotionOverride
end
---@param newFlightActive boolean
local function setBaseFlightActive(newFlightActive)
flightActive = newFlightActive
end
return {
doFlyloop = doFlyloop,
getCoords = getCoords,
pressedKeys = pressedKeys,
setBaseFlightActive = setBaseFlightActive,
setIsFlightActiveOverride = setIsFlightActiveOverride,
setGetSpeedOverride = setGetSpeedOverride,
setGetDesiredDirOverride = setGetDesiredDirOverride,
setMotionOverride = setMotionOverride,
}
else
doFlyloop()
end
-- Created by jasper_185

56
mpp.lua Normal file
View file

@ -0,0 +1,56 @@
local connectionUrl = "wss://mppclone.com";
local ws, err = http.websocket(connectionUrl)
if not ws then
return printError(err)
end
function send(data)
local message = {}
message[1] = data;
ws.send(textutils.serialiseJSON(message));
end
local function tSender()
while true do
os.sleep(15)
send({
m = "t"
})
end
end
local function pollWebsocket()
while true do
local _, url, response, isBinary = os.pullEvent("websocket_message");
if url == connectionUrl then
local json = textutils.unserializeJSON(response);
if json[1].m == "b" then
print("Connected to MPP!");
send({
m = "hi",
token = "<no>"
})
end
if json[1].m == "hi" then
print("Authenicated!")
send({
m = "ch",
_id = "The Roleplay Room"
})
end
if json[1].m == "a" then
print("["..json[1].p._id:sub(0, 6).."] "..json[1].p.name..": "..json[1].a)
end
local g = json[1].m == "m" or json[1].m == "n"
if not g then
print(json[1].m)
end
end
end
end
parallel.waitForAny(tSender,pollWebsocket)

250
previous-flight.lua Normal file
View file

@ -0,0 +1,250 @@
-- Elytra Flight module for Minit
-- Copyright (C) 2023 AlexDevs
-- This software is licensed under the MIT license.
local module = {
name = "flight",
}
local locale = {
direction = "%s : %d", -- windrose : pitch
altitude = "Y: %d",
yMotion = "Y: %.2f",
speed = "%.2f m/s",
}
local icons = {
empty = "air",
fly = "elytra",
launch = "firework_rocket",
slow = "feather",
disabled = "barrier",
propelling = "blaze_powder"
}
-- Default variables. Use settings file to change values.
settings.define("elytra.power", {
description = "Propeller power",
type = "number",
default = 2,
})
settings.define("elytra.pitch", {
description = "Propeller pitch treshold for automatic mode",
type = "number",
default = 0,
})
settings.define("elytra.scale", {
description = "Scale of UI",
type = "number",
default = 0.6,
})
settings.define("elytra.sounds", {
description = "Enable sound effects",
type = "boolean",
default = true,
})
settings.define("elytra.manual", {
description = "Press SHIFT while flying to propel",
type = "boolean",
default = true,
})
settings.define("elytra.softfall.enable", {
description = "Enable softfall",
type = "boolean",
default = true,
})
settings.define("elytra.softfall.basepower", {
description = "Base power for soft fall",
type = "number",
default = 0.75,
})
settings.define("elytra.softfall.trigger", {
description = "Minimum negative Y motion required to trigger soft fall. USE NEGATIVE NUMBERS",
type = "number",
default = -1,
})
local neural, speaker
local canvas, container
local screen = {}
local currentY = 0
local function getRoseWind(degrees)
degrees = degrees + 180
local directions = { "N", "NE", "E", "SE", "S", "SW", "W", "NW" }
local index = math.floor((degrees / 45) + 0.5) % 8
return directions[index + 1]
end
local function createScreen()
canvas = neural.canvas()
screen = {}
if container then
pcall(container.clear)
end
container = canvas.addGroup({ 1, 1 })
local scale = settings.get("elytra.scale")
local x, y = 25, math.ceil(9 * scale)
screen.icon = container.addItem({ 0, 1 }, "elytra")
screen.speed = container.addText({ x, y * 1 }, "")
screen.speed.setScale(scale)
screen.altitude = container.addText({ x, y * 2 }, "")
screen.altitude.setScale(scale)
screen.direction = container.addText({ x, y * 3 }, "")
screen.direction.setScale(scale)
end
local function updateScreen(meta)
if not canvas or not container then
createScreen()
end
local mVector = vector.new(meta.deltaPosX, meta.deltaPosY, meta.deltaPosZ)
local speed = mVector:length() * 20
screen.speed.setText(string.format(locale.speed, speed))
screen.direction.setText(string.format(locale.direction, getRoseWind(meta.yaw), meta.pitch))
screen.altitude.setText(string.format(locale.altitude, currentY))
end
local icon = icons.empty
local function toggleScreen(show)
local alpha = show and 0xff or 0
screen.icon.setItem(show and icon or icons.empty)
screen.speed.setAlpha(alpha)
screen.altitude.setAlpha(alpha)
screen.direction.setAlpha(alpha)
end
local function setIcon(newIcon)
icon = newIcon
screen.icon.setItem(newIcon)
end
local function playSound(sound, volume, pitch)
if speaker and settings.get("elytra.sounds") then
speaker.playSound(sound, volume, pitch)
end
end
local function launch(yaw, pitch, power)
power = power or settings.get("elytra.power")
neural.launch(yaw, pitch, math.min(power, 4))
end
local function launchUp(power)
launch(0, -90, power)
end
local function softFall(motionY)
motionY = motionY or 0
launchUp(-motionY + settings.get("elytra.softfall.basepower"))
playSound("minecraft:entity.phantom.flap", 1, 1)
end
local function canPropel(meta)
return settings.get("elytra.manual") and meta.isSneaking or not meta.isSneaking
end
local function propel(meta, icon)
neural.launch(meta.yaw, meta.pitch, settings.get("elytra.power"))
playSound("minecraft:entity.fishing_bobber.throw", 0.4, 1)
if icon then
setIcon(icon)
end
end
local function gpsLocate()
while true do
local x, y, z = gps.locate()
if x then
currentY = y
end
sleep(0.5)
end
end
function module.init(init)
init.addTask(gpsLocate)
end
function module.setup(ni)
neural = ni
speaker = peripheral.find("speaker")
createScreen()
toggleScreen(false)
end
function module.update(meta)
if not meta.isElytraFlying then
if meta.isSneaking then
if meta.pitch == -90 then
setIcon(icons.launch)
launchUp(2)
else
setIcon(icons.disabled)
end
return
end
if meta.deltaPosY < settings.get("elytra.softfall.trigger") and settings.get("elytra.softfall.enable") then
softFall(meta.motionY)
setIcon(icons.slow)
return
end
toggleScreen(false)
return
end
toggleScreen(true)
updateScreen(meta)
local pitch = meta.pitch
local yaw = meta.yaw
if not canPropel(meta) then
setIcon(icons.disabled)
return
end
if settings.get("elytra.manual") then
if meta.isSneaking then
propel(meta, icons.propelling)
else
if meta.deltaPosY < settings.get("elytra.softfall.trigger") and settings.get("elytra.softfall.enable") then
softFall(meta.motionY)
setIcon(icons.slow)
else
setIcon(icons.fly)
end
end
else
if pitch > settings.get("elytra.pitch") then
if meta.deltaPosY < settings.get("elytra.softfall.trigger") and settings.get("elytra.softfall.enable") then
softFall(meta.motionY)
setIcon(icons.slow)
end
return
end
setIcon(icons.fly)
propel(meta, false)
end
end
return module

3
sha256.lua Normal file
View file

@ -0,0 +1,3 @@
local g = string.gsub
sha256 = loadstring(g(g(g(g(g(g(g(g('Sa=XbandSb=XbxWSc=XlshiftSd=unpackSe=2^32SYf(g,h)Si=g/2^hSj=i%1Ui-j+j*eVSYk(l,m)Sn=l/2^mUn-n%1VSo={0x6a09e667Tbb67ae85T3c6ef372Ta54ff53aT510e527fT9b05688cT1f83d9abT5be0cd19}Sp={0x428a2f98T71374491Tb5c0fbcfTe9b5dba5T3956c25bT59f111f1T923f82a4Tab1c5ed5Td807aa98T12835b01T243185beT550c7dc3T72be5d74T80deb1feT9bdc06a7Tc19bf174Te49b69c1Tefbe4786T0fc19dc6T240ca1ccT2de92c6fT4a7484aaT5cb0a9dcT76f988daT983e5152Ta831c66dTb00327c8Tbf597fc7Tc6e00bf3Td5a79147T06ca6351T14292967T27b70a85T2e1b2138T4d2c6dfcT53380d13T650a7354T766a0abbT81c2c92eT92722c85Ta2bfe8a1Ta81a664bTc24b8b70Tc76c51a3Td192e819Td6990624Tf40e3585T106aa070T19a4c116T1e376c08T2748774cT34b0bcb5T391c0cb3T4ed8aa4aT5b9cca4fT682e6ff3T748f82eeT78a5636fT84c87814T8cc70208T90befffaTa4506cebTbef9a3f7Tc67178f2}SYq(r,q)if e-1-r[1]<q then r[2]=r[2]+1;r[1]=q-(e-1-r[1])-1 else r[1]=r[1]+qVUrVSYs(t)Su=#t;t[#t+1]=0x80;while#t%64~=56Zt[#t+1]=0VSv=q({0,0},u*8)fWw=2,1,-1Zt[#t+1]=a(k(a(v[w]TFF000000),24)TFF)t[#t+1]=a(k(a(v[w]TFF0000),16)TFF)t[#t+1]=a(k(a(v[w]TFF00),8)TFF)t[#t+1]=a(v[w]TFF)VUtVSYx(y,w)Uc(y[w]W0,24)+c(y[w+1]W0,16)+c(y[w+2]W0,8)+(y[w+3]W0)VSYz(t,w,A)SB={}fWC=1,16ZB[C]=x(t,w+(C-1)*4)VfWC=17,64ZSD=B[C-15]SE=b(b(f(B[C-15],7),f(B[C-15],18)),k(B[C-15],3))SF=b(b(f(B[C-2],17),f(B[C-2],19)),k(B[C-2],10))B[C]=(B[C-16]+E+B[C-7]+F)%eVSG,h,H,I,J,j,K,L=d(A)fWC=1,64ZSM=b(b(f(J,6),f(J,11)),f(J,25))SN=b(a(J,j),a(Xbnot(J),K))SO=(L+M+N+p[C]+B[C])%eSP=b(b(f(G,2),f(G,13)),f(G,22))SQ=b(b(a(G,h),a(G,H)),a(h,H))SR=(P+Q)%e;L,K,j,J,I,H,h,G=K,j,J,(I+O)%e,H,h,G,(O+R)%eVA[1]=(A[1]+G)%e;A[2]=(A[2]+h)%e;A[3]=(A[3]+H)%e;A[4]=(A[4]+I)%e;A[5]=(A[5]+J)%e;A[6]=(A[6]+j)%e;A[7]=(A[7]+K)%e;A[8]=(A[8]+L)%eUAVUY(t)t=t W""t=type(t)=="string"and{t:byte(1,-1)}Wt;t=s(t)SA={d(o)}fWw=1,#t,64ZA=z(t,w,A)VU("%08x"):rep(8):format(d(A))V',"S"," local "),"T",",0x"),"U"," return "),"V"," end "),"W","or "),"X","bit32."),"Y","function "),"Z"," do "))()
return sha256