Witchcraft/mc.sh

224 lines
5.5 KiB
Bash
Raw Permalink Normal View History

2022-02-09 03:58:56 +01:00
#!/bin/bash
state=''
dyed=0
keepalive=0
pos=(0 0 0)
players=()
time=18000
2022-02-09 03:58:56 +01:00
TEMP=/dev/shm/witchcraft/
mkdir -p $TEMP $TEMP/players $TEMP/world
source src/log.sh
source src/int.sh
2022-02-12 23:47:46 +01:00
source src/misc.sh
source src/palette.sh
source src/chunk.sh
2022-02-09 03:58:56 +01:00
source src/packet.sh
source src/hooks.sh
2022-02-09 05:31:45 +01:00
if [[ -f "$1" ]]; then
log "Loading plugin: $1"
source "$1"
fi
2022-02-09 03:58:56 +01:00
function keep_alive() {
while true; do
2022-02-14 01:54:31 +01:00
sleep 1
2022-02-09 03:58:56 +01:00
log "sending keepalive"
echo '092100000000000000ff' | unhex
2022-02-12 23:47:46 +01:00
# random data
2022-02-14 01:54:31 +01:00
2022-02-14 11:28:39 +01:00
#res=$(printf '%016x' $time)
#res=$res$res
#log time: $res
#time=$((time+240))
#echo -n "$(hexpacket_len "$res")59$res" | unhex
2022-02-09 03:58:56 +01:00
done
}
function position_delta() {
local deltaX
local deltaY
local deltaZ
pos_old[0]=0
pos_old[1]=0
pos_old[2]=0
while true; do
sleep 0.1
for i in $(ls "$TEMP/players/"); do
if [[ "$i" != "$nick" ]]; then
pos[0]=$(cat $TEMP/players/$i/position | awk -F, '{print($1)}') # idk, floating point broke
pos[1]=$(cat $TEMP/players/$i/position | awk -F, '{print($2)}')
pos[2]=$(cat $TEMP/players/$i/position | awk -F, '{print($3)}')
log "posX: ${pos[0]}"
deltaX=$((((${pos[0]}*32) - (${pos_old[0]}*32)) * 128))
deltaY=$(((${pos[1]}*32 - ${pos_old[1]}*32) * 128))
deltaZ=$(((${pos[2]}*32 - ${pos_old[2]}*32) * 128))
if [[ $deltaX != 0 || $deltaY != 0 || $deltaZ != 0 ]]; then
pkt_position $deltaX $deltaY $deltaZ $(cat $TEMP/players/$i/eid)
fi
pos_old=("${pos[@]}")
fi
done
done
}
function handle_broadcast() {
while true; do
for i in $(ls "$TEMP/players/"); do
if [[ "$i" != "$nick" ]]; then
if [[ -f $TEMP/players/$i/broadcast ]]; then
packet="$(cat $TEMP/players/$i/broadcast)"
if [[ "$last" != "$packet" ]]; then
cat $TEMP/players/$i/broadcast
last="$packet"
fi
else
last=''
fi
fi
done
sleep 1
done
}
function spawn_players() {
for i in $(ls "$TEMP/players/"); do # fite me
if [[ $i != $nick && ${players[@]} != *"$i"* ]]; then
log "name: $i EID: $eid"
pkt_playerinfo_add $i $(cat $TEMP/players/$i/eid)
pkt_spawnplayer $(cat $TEMP/players/$i/eid)
players+=("$nick")
fi
done
}
while true; do
len=$(varint2int)
a=$(dd count=$len bs=1 status=none | xxd -p)
if [[ "$a" == '' ]]; then
log "connection dyed"
pkill -P $$
pkt_chatmessage "- $nick" "00000000000000000000000000000000" > $TEMP/players/$nick/broadcast
2022-02-12 23:47:46 +01:00
sleep 0.3
2022-02-09 03:58:56 +01:00
rm -R "$TEMP/players/$nick"
exit
fi
if [[ $a == "00"* ]]; then
log "responding to 00; state: $state"
if [[ "$state" == '01' ]]; then
log "status response"
2022-02-14 01:54:31 +01:00
hook_ping
2022-02-09 03:58:56 +01:00
state=''
elif [[ "$state" == '02' ]]; then
nick=$(cut -c 5- <<< "$a" | unhex | grep -Poh '[A-Za-z0-9_-]*')
2022-02-12 23:47:46 +01:00
eid=$(printf "%04x" $RANDOM | cut -c 1-4)
2022-02-09 03:58:56 +01:00
mkdir -p $TEMP/players/$nick
echo -n $eid > $TEMP/players/$nick/eid
log "login response"
if [[ $keepalive == 0 ]]; then
hook_keepalive
keepalive=1
fi
# random uuid string len string (nick)
res="0000000000000000000000000000$eid$(str_len "$nick")$(echo -n "$nick" | xxd -p)"
send_packet "02" "$res"
2022-02-09 03:58:56 +01:00
res="0100$eid" # entity id
2022-02-14 11:28:39 +01:00
res+="00" # not hardcore
2022-02-14 11:31:57 +01:00
res+="$gamemode" # survival mode
2022-02-14 11:28:39 +01:00
res+="01" # ... as previously seen on Creative Mode (ignored)
# I am *not* recreating the biome codecs
res+="$(cat src/biome_blob.nbt | xxd -p)
"
2022-02-09 03:58:56 +01:00
#res+="01" # one dimension
#res+="13$(echo -n "minecraft:overworld" | xxd -p)"
#res+="0a000000" # dimension codec
#res+="0a000000" # dimension
#res+="13$(echo -n "minecraft:overworld" | xxd -p)" # dimension being spawned into
#res+="0000000000000000" # beginning of sha256 of seed
2022-02-14 11:28:39 +01:00
#res+="00" # max players (ignored)
res+="0a" # view distance (min 2 chunks)
res+="0a" # simulation distance
res+="00" # reduced debug info? (false)
res+="00" # enable respawn screen
res+="00" # is debug (surprisingly, no)
res+="01" # is flat (yeah, sure)
2022-02-09 03:58:56 +01:00
send_packet "26" "$res"
2022-02-14 11:28:39 +01:00
log "sent join game"
2022-02-14 01:54:31 +01:00
#res="$(encode_position 10 10 10)"
#res+="00000000" # angle as float
#echo -n "$(hexpacket_len "$res")4B$res" | unhex
2022-02-14 01:54:31 +01:00
#log "sent spawn position"
2022-02-09 03:58:56 +01:00
2022-02-14 01:54:31 +01:00
hook_inventory
2022-02-09 03:58:56 +01:00
hook_chunks
2022-02-14 01:54:31 +01:00
pkt_pos ${spawn_pos[0]} ${spawn_pos[1]} ${spawn_pos[2]}
2022-02-09 03:58:56 +01:00
spawn_players
2022-02-12 23:47:46 +01:00
2022-02-14 01:54:31 +01:00
(sleep 1; hook_start) &
2022-02-09 03:58:56 +01:00
state=''
else
if [[ $a == *"01" ]]; then # 01 - next state: status
log 'set status'
state='01'
else # 02 - next state: login
log 'set login'
state='02'
fi
fi
elif [[ $a == "01"* ]]; then
log "responding to 01"
echo "$len$a" | unhex
2022-02-09 03:58:56 +01:00
log "bye"
exit
elif [[ $a == "0f"* ]]; then
log "received keepalive"
date "+%s" > $TEMP/players/$nick/ping
elif [[ $a == "11"* ]]; then
pos[0]=$(from_ieee754 $(cut -c 3-18 <<< "$a"))
pos[1]=$(from_ieee754 $(cut -c 19-34 <<< "$a"))
pos[2]=$(from_ieee754 $(cut -c 35-50 <<< "$a"))
echo "${pos[0]},${pos[1]},${pos[2]}" > $TEMP/players/$nick/position
hook_move
elif [[ $a == "12"* ]]; then
2022-02-12 23:47:46 +01:00
pos[0]=$(from_ieee754 $(cut -c 3-18 <<< "$a"))
pos[1]=$(from_ieee754 $(cut -c 19-34 <<< "$a"))
pos[2]=$(from_ieee754 $(cut -c 35-50 <<< "$a"))
2022-02-09 03:58:56 +01:00
hook_move
elif [[ $a == "13"* ]]; then
2022-02-12 23:47:46 +01:00
log "received Player Rotation"
2022-02-09 03:58:56 +01:00
elif [[ $a == "1a"* ]]; then
2022-02-14 01:54:31 +01:00
decode_position $(cut -c 5-20 <<< "$a")
2022-02-09 03:58:56 +01:00
hook_dig
elif [[ $a == "2c"* ]]; then
hook_swing
elif [[ $a == "2e"* ]]; then
hook_block
elif [[ $a == "03"* ]]; then
if [[ $((0x$(cut -c 3-4 <<< "$a"))) -lt 127 ]]; then # lazy varint check
msg=$(cut -c 5- <<< "$a" | unhex)
2022-02-09 03:58:56 +01:00
else
msg=$(cut -c 3- <<< "$a" | unhex)
2022-02-09 03:58:56 +01:00
fi
hook_chat
else
log "unknown data from client"
rhexlog "$a"
fi
done