-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmc.sh
executable file
·223 lines (198 loc) · 5.51 KB
/
mc.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#!/bin/bash
state=''
dyed=0
keepalive=0
pos=(0 0 0)
players=()
time=18000
TEMP=/dev/shm/witchcraft/
mkdir -p $TEMP $TEMP/players $TEMP/world
source src/log.sh
source src/int.sh
source src/misc.sh
source src/palette.sh
source src/chunk.sh
source src/packet.sh
source src/hooks.sh
if [[ -f "$1" ]]; then
log "Loading plugin: $1"
source "$1"
fi
function keep_alive() {
while true; do
sleep 1
log "sending keepalive"
echo '092100000000000000ff' | unhex
# random data
#res=$(printf '%016x' $time)
#res=$res$res
#log time: $res
#time=$((time+240))
#echo -n "$(hexpacket_len "$res")59$res" | unhex
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
sleep 0.3
rm -R "$TEMP/players/$nick"
exit
fi
if [[ $a == "00"* ]]; then
log "responding to 00; state: $state"
if [[ "$state" == '01' ]]; then
log "status response"
hook_ping
state=''
elif [[ "$state" == '02' ]]; then
nick=$(cut -c 5- <<< "$a" | unhex | grep -Poh '[A-Za-z0-9_-]*')
eid=$(printf "%04x" $RANDOM | cut -c 1-4)
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"
res="0100$eid" # entity id
res+="00" # not hardcore
res+="$gamemode" # survival mode
res+="01" # ... as previously seen on Creative Mode (ignored)
# I am *not* recreating the biome codecs
res+="$(cat src/biome_blob.nbt | xxd -p)
"
#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
#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)
send_packet "26" "$res"
log "sent join game"
#res="$(encode_position 10 10 10)"
#res+="00000000" # angle as float
#echo -n "$(hexpacket_len "$res")4B$res" | unhex
#log "sent spawn position"
hook_inventory
hook_chunks
pkt_pos ${spawn_pos[0]} ${spawn_pos[1]} ${spawn_pos[2]}
spawn_players
(sleep 1; hook_start) &
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
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
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"))
hook_move
elif [[ $a == "13"* ]]; then
log "received Player Rotation"
elif [[ $a == "1a"* ]]; then
decode_position $(cut -c 5-20 <<< "$a")
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)
else
msg=$(cut -c 3- <<< "$a" | unhex)
fi
hook_chat
else
log "unknown data from client"
rhexlog "$a"
fi
done