commit 0de5415f05b166cb0b3fe6cbdb62247f6093e3d2 Author: AkmalFairuz Date: Tue Dec 31 20:57:21 2024 +0700 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..4c644df --- /dev/null +++ b/config.toml @@ -0,0 +1,4 @@ + +[Connection] + LocalAddress = "0.0.0.0:19132" + RemoteAddress = "play.venitymc.com:19132" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..8db2e3e --- /dev/null +++ b/go.mod @@ -0,0 +1,31 @@ +module github.com/akmalfairuz/legacy-version + +go 1.23.3 + +require ( + github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/df-mc/dragonfly v0.9.20-0.20241229163702-cc7e4ee0e3ce // indirect + github.com/df-mc/goleveldb v1.1.9 // indirect + github.com/df-mc/worldupgrader v1.0.18 // indirect + github.com/go-gl/mathgl v1.2.0 // indirect + github.com/go-jose/go-jose/v3 v3.0.3 // indirect + github.com/go-jose/go-jose/v4 v4.0.4 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/muhammadmuzzammil1998/jsonc v1.0.0 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/samber/lo v1.47.0 // indirect + github.com/sandertv/go-raknet v1.14.2 // indirect + github.com/sandertv/gophertunnel v1.43.1 // indirect + github.com/segmentio/fasthash v1.0.3 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect + golang.org/x/image v0.21.0 // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/oauth2 v0.24.0 // indirect + golang.org/x/text v0.21.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..91b058f --- /dev/null +++ b/go.sum @@ -0,0 +1,124 @@ +github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9 h1:/G0ghZwrhou0Wq21qc1vXXMm/t/aKWkALWwITptKbE0= +github.com/brentp/intintmap v0.0.0-20190211203843-30dc0ade9af9/go.mod h1:TOk10ahXejq9wkEaym3KPRNeuR/h5Jx+s8QRWIa2oTM= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/df-mc/dragonfly v0.9.20-0.20241229163702-cc7e4ee0e3ce h1:mhBn/ezojzACPHeg+Y9NnU2bbYCozx27RgpfWUPw4i0= +github.com/df-mc/dragonfly v0.9.20-0.20241229163702-cc7e4ee0e3ce/go.mod h1:hH1eU9lmucLNLehzxXzOUOmHJQLz3DLpQMUqIKcz8YI= +github.com/df-mc/goleveldb v1.1.9 h1:ihdosZyy5jkQKrxucTQmN90jq/2lUwQnJZjIYIC/9YU= +github.com/df-mc/goleveldb v1.1.9/go.mod h1:+NHCup03Sci5q84APIA21z3iPZCuk6m6ABtg4nANCSk= +github.com/df-mc/worldupgrader v1.0.18 h1:Q34X9ID/hGuDyj9oiq+dpyjOaJdNxhVmVUepf/EPYDA= +github.com/df-mc/worldupgrader v1.0.18/go.mod h1:tsSOLTRm9mpG7VHvYpAjjZrkRHWmSbKZAm9bOLNnlDk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-gl/mathgl v1.1.0 h1:0lzZ+rntPX3/oGrDzYGdowSLC2ky8Osirvf5uAwfIEA= +github.com/go-gl/mathgl v1.1.0/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ= +github.com/go-gl/mathgl v1.2.0 h1:v2eOj/y1B2afDxF6URV1qCYmo1KW08lAMtTbOn3KXCY= +github.com/go-gl/mathgl v1.2.0/go.mod h1:pf9+b5J3LFP7iZ4XXaVzZrCle0Q/vNpB/vDe5+3ulRE= +github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/muhammadmuzzammil1998/jsonc v1.0.0 h1:8o5gBQn4ZA3NBA9DlTujCj2a4w0tqWrPVjDwhzkgTIs= +github.com/muhammadmuzzammil1998/jsonc v1.0.0/go.mod h1:saF2fIVw4banK0H4+/EuqfFLpRnoy5S+ECwTOCcRcSU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= +github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/sandertv/go-raknet v1.14.2 h1:UZLyHn5yQU2Dq2GVq/LlxwAUikaq4q4AA1rl/Pf3AXQ= +github.com/sandertv/go-raknet v1.14.2/go.mod h1:/yysjwfCXm2+2OY8mBazLzcxJ3irnylKCyG3FLgUPVU= +github.com/sandertv/gophertunnel v1.43.0 h1:zoB0nngGXokBlj+ge4ISvbInEd/1xbrIlclC/POCTgc= +github.com/sandertv/gophertunnel v1.43.0/go.mod h1:krvLSeRUNQ2iEYJNEgzrKtWO8W5ybZxN5lFfSCkHoNk= +github.com/sandertv/gophertunnel v1.43.1-0.20241229203958-5af8736ae319 h1:yxDqIvO9BkUFtK2SpnngPDnPQ9hnhq3IGZ6qiO2rFHg= +github.com/sandertv/gophertunnel v1.43.1-0.20241229203958-5af8736ae319/go.mod h1:XuEJo+ARim+NKiD90Z56sQRcDtCOErz26e2bt3LEd9I= +github.com/sandertv/gophertunnel v1.43.1 h1:wY6Fy8dRMKtpZUQzCR35o9k05135vOJZhrz0GF6OXFI= +github.com/sandertv/gophertunnel v1.43.1/go.mod h1:XuEJo+ARim+NKiD90Z56sQRcDtCOErz26e2bt3LEd9I= +github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= +github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= +golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/image v0.0.0-20190321063152-3fc05d484e9f/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s= +golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= +golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/block_states.go b/internal/block_states.go new file mode 100644 index 0000000..e35ba0d --- /dev/null +++ b/internal/block_states.go @@ -0,0 +1,53 @@ +package internal + +import ( + "fmt" + "github.com/df-mc/worldupgrader/blockupgrader" + "sort" + "strings" + "unsafe" +) + +// StateHash is a struct that may be used as a map key for block states. It contains the name of the block state +// and an encoded version of the properties. +type StateHash struct { + Name, Properties string +} + +// HashState produces a hash for the block properties held by the blockState. +func HashState(state blockupgrader.BlockState) StateHash { + if state.Properties == nil { + return StateHash{Name: state.Name} + } + keys := make([]string, 0, len(state.Properties)) + for k := range state.Properties { + keys = append(keys, k) + } + sort.Slice(keys, func(i, j int) bool { + return keys[i] < keys[j] + }) + + var b strings.Builder + for _, k := range keys { + switch v := state.Properties[k].(type) { + case bool: + if v { + b.WriteByte(1) + } else { + b.WriteByte(0) + } + case uint8: + b.WriteByte(v) + case int32: + a := *(*[4]byte)(unsafe.Pointer(&v)) + b.Write(a[:]) + case string: + b.WriteString(v) + default: + // If block encoding is broken, we want to find out as soon as possible. This saves a lot of time + // debugging in-game. + panic(fmt.Sprintf("invalid block property type %T for property %v", v, k)) + } + } + return StateHash{Name: state.Name, Properties: b.String()} +} diff --git a/internal/chunk/chunk.go b/internal/chunk/chunk.go new file mode 100644 index 0000000..1baf026 --- /dev/null +++ b/internal/chunk/chunk.go @@ -0,0 +1,119 @@ +package chunk + +import ( + "github.com/df-mc/dragonfly/server/block/cube" + "sync" +) + +// Chunk is a segment in the world with a size of 16x16x256 blocks. A chunk contains multiple sub chunks +// and stores other information such as biomes. +// It is not safe to call methods on Chunk simultaneously from multiple goroutines. +type Chunk struct { + sync.Mutex + // r holds the (vertical) range of the Chunk. It includes both the minimum and maximum coordinates. + r cube.Range + // air is the runtime ID of air. + air uint32 + // sub holds all sub chunks part of the chunk. The pointers held by the array are nil if no sub chunk is + // allocated at the indices. + sub []*SubChunk + // biomes is an array of biome IDs. There is one biome ID for every column in the chunk. + biomes []*PalettedStorage +} + +// New initialises a new chunk and returns it, so that it may be used. +func New(air uint32, r cube.Range) *Chunk { + n := (r.Height() >> 4) + 1 + sub, biomes := make([]*SubChunk, n), make([]*PalettedStorage, n) + for i := 0; i < n; i++ { + sub[i] = NewSubChunk(air) + biomes[i] = emptyStorage(0) + } + return &Chunk{r: r, air: air, sub: sub, biomes: biomes} +} + +// Range returns the cube.Range of the Chunk as passed to New. +func (chunk *Chunk) Range() cube.Range { + return chunk.r +} + +// Sub returns a list of all sub chunks present in the chunk. +func (chunk *Chunk) Sub() []*SubChunk { + return chunk.sub +} + +// Block returns the runtime ID of the block at a given x, y and z in a chunk at the given layer. If no +// sub chunk exists at the given y, the block is assumed to be air. +func (chunk *Chunk) Block(x uint8, y int16, z uint8, layer uint8) uint32 { + sub := chunk.subChunk(y) + if sub.Empty() || uint8(len(sub.storages)) <= layer { + return chunk.air + } + return sub.storages[layer].At(x, uint8(y), z) +} + +// SetBlock sets the runtime ID of a block at a given x, y and z in a chunk at the given layer. If no +// SubChunk exists at the given y, a new SubChunk is created and the block is set. +func (chunk *Chunk) SetBlock(x uint8, y int16, z uint8, layer uint8, block uint32) { + sub := chunk.sub[chunk.subIndex(y)] + if uint8(len(sub.storages)) <= layer && block == chunk.air { + // Air was set at n layer, but there were less than n layers, so there already was air there. + // Don't do anything with this, just return. + return + } + sub.Layer(layer).Set(x, uint8(y), z, block) +} + +// BiomeSub returns a list of all biome sub chunks present in the chunk. +func (chunk *Chunk) BiomeSub() []*PalettedStorage { + return chunk.biomes +} + +// Biome returns the biome ID at a specific column in the chunk. +func (chunk *Chunk) Biome(x uint8, y int16, z uint8) uint32 { + return chunk.biomes[chunk.subIndex(y)].At(x, uint8(y), z) +} + +// SetBiome sets the biome ID at a specific column in the chunk. +func (chunk *Chunk) SetBiome(x uint8, y int16, z uint8, biome uint32) { + chunk.biomes[chunk.subIndex(y)].Set(x, uint8(y), z, biome) +} + +// HighestBlock iterates from the highest non-empty sub chunk downwards to find the Y value of the highest +// non-air block at an x and z. If no blocks are present in the column, 0 is returned. +func (chunk *Chunk) HighestBlock(x, z uint8) int16 { + for index := int16(len(chunk.sub) - 1); index >= 0; index-- { + if sub := chunk.sub[index]; !sub.Empty() { + for y := 15; y >= 0; y-- { + if rid := sub.storages[0].At(x, uint8(y), z); rid != chunk.air { + return int16(y) | chunk.subY(index) + } + } + } + } + return int16(chunk.r[0]) +} + +// Compact compacts the chunk as much as possible, getting rid of any sub chunks that are empty, and compacts +// all storages in the sub chunks to occupy as little space as possible. +// Compact should be called right before the chunk is saved in order to optimise the storage space. +func (chunk *Chunk) Compact() { + for i := range chunk.sub { + chunk.sub[i].compact() + } +} + +// subChunk finds the correct SubChunk in the Chunk by a Y value. +func (chunk *Chunk) subChunk(y int16) *SubChunk { + return chunk.sub[chunk.subIndex(y)] +} + +// subIndex returns the sub chunk Y index matching the y value passed. +func (chunk *Chunk) subIndex(y int16) int16 { + return (y - int16(chunk.r[0])) >> 4 +} + +// subY returns the sub chunk Y value matching the index passed. +func (chunk *Chunk) subY(index int16) int16 { + return (index << 4) + int16(chunk.r[0]) +} diff --git a/internal/chunk/decode.go b/internal/chunk/decode.go new file mode 100644 index 0000000..29b73db --- /dev/null +++ b/internal/chunk/decode.go @@ -0,0 +1,145 @@ +package chunk + +import ( + "bytes" + "fmt" + "github.com/df-mc/dragonfly/server/block/cube" +) + +// NetworkDecode decodes the network serialised data passed into a Chunk if successful. If not, the chunk +// returned is nil and the error non-nil. +// The sub chunk count passed must be that found in the LevelChunk packet. +// noinspection GoUnusedExportedFunction +func NetworkDecode(air uint32, buf *bytes.Buffer, count int, oldFormat bool, r cube.Range, pse Encoding, pe PaletteEncoding) (*Chunk, error) { + var ( + c = New(air, r) + err error + ) + for i := 0; i < count; i++ { + index := uint8(i) + if oldFormat { + index += 4 + } + c.sub[index], err = DecodeSubChunk(air, r, buf, &index, NetworkEncoding, pse, pe) + if err != nil { + return nil, err + } + } + if oldFormat { + // Read the old biomes. + biomes := make([]byte, 256) + if _, err := buf.Read(biomes); err != nil { + return nil, fmt.Errorf("error reading biomes: %w", err) + } + + // Make our 2D biomes 3D. + for x := 0; x < 16; x++ { + for z := 0; z < 16; z++ { + id := biomes[(x&15)|(z&15)<<4] + for y := r.Min(); y <= r.Max(); y++ { + c.SetBiome(uint8(x), int16(y), uint8(z), uint32(id)) + } + } + } + } else { + var last *PalettedStorage + for i := 0; i < len(c.sub); i++ { + b, err := decodePalettedStorage(buf, NetworkEncoding, pse, BiomePaletteEncoding) + if err != nil { + return nil, err + } + if b == nil { + // b == nil means this paletted storage had the flag pointing to the previous one. It basically means we should + // inherit whatever palette we decoded last. + if i == 0 { + // This should never happen and there is no way to handle this. + return nil, fmt.Errorf("first biome storage pointed to previous one") + } + b = last + } else { + last = b + } + c.biomes[i] = b + } + } + return c, nil +} + +// DecodeSubChunk decodes a SubChunk from a bytes.Buffer. The Encoding passed defines how the block storages of the +// SubChunk are decoded. +func DecodeSubChunk(air uint32, r cube.Range, buf *bytes.Buffer, index *byte, e Encoding, pse Encoding, pe PaletteEncoding) (*SubChunk, error) { + ver, err := buf.ReadByte() + if err != nil { + return nil, fmt.Errorf("error reading version: %w", err) + } + sub := NewSubChunk(air) + switch ver { + default: + return nil, fmt.Errorf("unknown sub chunk version %v: can't decode", ver) + case 1: + // Version 1 only has one layer for each sub chunk, but uses the format with palettes. + storage, err := decodePalettedStorage(buf, e, pse, pe) + if err != nil { + return nil, err + } + sub.storages = append(sub.storages, storage) + case 8, 9: + // Version 8 allows up to 256 layers for one sub chunk. + storageCount, err := buf.ReadByte() + if err != nil { + return nil, fmt.Errorf("error reading storage count: %w", err) + } + if ver == 9 { + uIndex, err := buf.ReadByte() + if err != nil { + return nil, fmt.Errorf("error reading subchunk index: %w", err) + } + // The index as written here isn't the actual index of the subchunk within the chunk. Rather, it is the Y + // value of the subchunk. This means that we need to translate it to an index. + *index = uint8(int8(uIndex) - int8(r[0]>>4)) + } + sub.storages = make([]*PalettedStorage, storageCount) + + for i := byte(0); i < storageCount; i++ { + sub.storages[i], err = decodePalettedStorage(buf, e, pse, pe) + if err != nil { + return nil, err + } + } + } + return sub, nil +} + +// decodePalettedStorage decodes a PalettedStorage from a bytes.Buffer. The Encoding passed is used to read either a +// network or disk block storage. +func decodePalettedStorage(buf *bytes.Buffer, e Encoding, pse Encoding, pe PaletteEncoding) (*PalettedStorage, error) { + blockSize, err := buf.ReadByte() + if err != nil { + return nil, fmt.Errorf("error reading block size: %w", err) + } + if e == NetworkEncoding && blockSize&1 != 1 { + e = pse + } + + blockSize >>= 1 + if blockSize == 0x7f { + return nil, nil + } + + size := paletteSize(blockSize) + uint32Count := size.uint32s() + + uint32s := make([]uint32, uint32Count) + byteCount := uint32Count * 4 + + data := buf.Next(byteCount) + if len(data) != byteCount { + return nil, fmt.Errorf("cannot read paletted storage (size=%v) %T: not enough block data present: expected %v bytes, got %v", blockSize, pe, byteCount, len(data)) + } + for i := 0; i < uint32Count; i++ { + // Explicitly don't use the binary package to greatly improve performance of reading the uint32s. + uint32s[i] = uint32(data[i*4]) | uint32(data[i*4+1])<<8 | uint32(data[i*4+2])<<16 | uint32(data[i*4+3])<<24 + } + p, err := e.DecodePalette(buf, paletteSize(blockSize), pe) + return newPalettedStorage(uint32s, p), err +} diff --git a/internal/chunk/encode.go b/internal/chunk/encode.go new file mode 100644 index 0000000..c4e8392 --- /dev/null +++ b/internal/chunk/encode.go @@ -0,0 +1,92 @@ +package chunk + +import ( + "bytes" + "github.com/df-mc/dragonfly/server/block/cube" + "sync" +) + +// pool is used to pool byte buffers used for encoding chunks. +var pool = sync.Pool{ + New: func() any { + return bytes.NewBuffer(make([]byte, 0, 1024)) + }, +} + +func NetworkEncode(air uint32, c *Chunk, oldFormat bool, pe PaletteEncoding) ([]byte, error) { + buf := pool.Get().(*bytes.Buffer) + for i := 0; i < len(c.sub); i++ { + _, _ = buf.Write(EncodeSubChunk(c.sub[i], NetworkEncoding, pe, SubChunkVersion8, c.r, i)) + } + if oldFormat { + biomes := make([]byte, 256) + + // Make our 3D biomes 2D. + for x := uint8(0); x < 16; x++ { + for z := uint8(0); z < 16; z++ { + biomes[(x&15)|(z&15)<<4] = byte(c.Biome(x, c.HighestBlock(x, z), z)) + } + } + _, _ = buf.Write(biomes) + } else { + _, _ = buf.Write(EncodeBiomes(c, NetworkEncoding)) + } + + return buf.Bytes(), nil +} + +// EncodeSubChunk encodes a sub-chunk from a chunk into bytes. An Encoding may be passed to encode either for network or +// disk purposed, the most notable difference being that the network encoding generally uses varints and no NBT. +func EncodeSubChunk(s *SubChunk, e Encoding, pe PaletteEncoding, subChunkVer subChunkVersion, r cube.Range, ind int) []byte { + buf := pool.Get().(*bytes.Buffer) + defer func() { + buf.Reset() + pool.Put(buf) + }() + + subChunkVer.EncodeHeader(buf, s, r, ind) + for _, storage := range s.storages { + encodePalettedStorage(buf, storage, nil, e, pe) + } + sub := make([]byte, buf.Len()) + _, _ = buf.Read(sub) + return sub +} + +// EncodeBiomes encodes the biomes of a chunk into bytes. An Encoding may be passed to encode either for network or +// disk purposed, the most notable difference being that the network encoding generally uses varints and no NBT. +func EncodeBiomes(c *Chunk, e Encoding) []byte { + buf := pool.Get().(*bytes.Buffer) + defer func() { + buf.Reset() + pool.Put(buf) + }() + + var previous *PalettedStorage + for _, b := range c.biomes { + encodePalettedStorage(buf, b, previous, e, BiomePaletteEncoding) + previous = b + } + biomes := make([]byte, buf.Len()) + _, _ = buf.Read(biomes) + return biomes +} + +// encodePalettedStorage encodes a PalettedStorage into a bytes.Buffer. The Encoding passed is used to write the Palette +// of the PalettedStorage. +func encodePalettedStorage(buf *bytes.Buffer, storage, previous *PalettedStorage, e Encoding, pe PaletteEncoding) { + if storage.Equal(previous) { + _, _ = buf.Write([]byte{0x7f<<1 | e.Network()}) + return + } + b := make([]byte, len(storage.indices)*4+1) + b[0] = byte(storage.bitsPerIndex<<1) | e.Network() + + for i, v := range storage.indices { + // Explicitly don't use the binary package to greatly improve performance of writing the uint32s. + b[i*4+1], b[i*4+2], b[i*4+3], b[i*4+4] = byte(v), byte(v>>8), byte(v>>16), byte(v>>24) + } + _, _ = buf.Write(b) + + e.EncodePalette(buf, storage.palette, pe) +} diff --git a/internal/chunk/encoding.go b/internal/chunk/encoding.go new file mode 100644 index 0000000..5c5d7b6 --- /dev/null +++ b/internal/chunk/encoding.go @@ -0,0 +1,193 @@ +package chunk + +import ( + "bytes" + "encoding/binary" + "fmt" + "github.com/akmalfairuz/legacy-version/mapping" + "strings" + + "github.com/df-mc/dragonfly/server/block/cube" + "github.com/df-mc/worldupgrader/blockupgrader" + "github.com/sandertv/gophertunnel/minecraft/nbt" + "github.com/sandertv/gophertunnel/minecraft/protocol" +) + +const ( + // SubChunkVersion is the current version of the written sub chunks, specifying the format they are + // written on disk and over network. + SubChunkVersion = 9 +) + +type ( + // Encoding is an encoding type used for Chunk encoding. Implementations of this interface are DiskEncoding and + // NetworkEncoding, which can be used to encode a Chunk to an intermediate disk or network representation respectively. + Encoding interface { + EncodePalette(buf *bytes.Buffer, p *Palette, e PaletteEncoding) + DecodePalette(buf *bytes.Buffer, blockSize paletteSize, e PaletteEncoding) (*Palette, error) + Network() byte + } + // PaletteEncoding is an encoding type used for Chunk encoding. It is used to encode different types of palettes + // (for example, blocks or biomes) differently. + PaletteEncoding interface { + Encode(buf *bytes.Buffer, v uint32) + Decode(buf *bytes.Buffer) (uint32, error) + } + // Encoding is an encoding type used for Chunk encoding. Implementations of this interface are DiskEncoding and + // NetworkEncoding, which can be used to encode a Chunk to an intermediate disk or network representation respectively. + subChunkVersion interface { + EncodeHeader(buf *bytes.Buffer, s *SubChunk, r cube.Range, ind int) + } +) + +var ( + // SubChunkVersion9 subChunkVersion9 + SubChunkVersion9 subChunkVersion9 + // SubChunkVersion8 subChunkVersion8 + SubChunkVersion8 subChunkVersion8 + + // NetworkEncoding is the Encoding used for sending a Chunk over network. It does not use NBT and writes varints. + NetworkEncoding networkEncoding + // BiomePaletteEncoding is the paletteEncoding used for encoding a palette of biomes. + BiomePaletteEncoding biomePaletteEncoding +) + +// networkEncoding implements the Chunk encoding for sending over network. +type networkEncoding struct{} + +func (networkEncoding) Network() byte { return 1 } +func (networkEncoding) EncodePalette(buf *bytes.Buffer, p *Palette, _ PaletteEncoding) { + if p.size != 0 { + _ = protocol.WriteVarint32(buf, int32(p.Len())) + } + for _, val := range p.values { + _ = protocol.WriteVarint32(buf, int32(val)) + } +} +func (networkEncoding) DecodePalette(buf *bytes.Buffer, blockSize paletteSize, _ PaletteEncoding) (*Palette, error) { + var paletteCount int32 = 1 + if blockSize != 0 { + if err := protocol.Varint32(buf, &paletteCount); err != nil { + return nil, fmt.Errorf("error reading palette entry count: %w", err) + } + if paletteCount <= 0 { + return nil, fmt.Errorf("invalid palette entry count %v", paletteCount) + } + } + + blocks, temp := make([]uint32, paletteCount), int32(0) + for i := int32(0); i < paletteCount; i++ { + if err := protocol.Varint32(buf, &temp); err != nil { + return nil, fmt.Errorf("error decoding palette entry: %w", err) + } + blocks[i] = uint32(temp) + } + return &Palette{values: blocks, size: blockSize}, nil +} + +// biomePaletteEncoding implements the encoding of biome palettes to disk. +type biomePaletteEncoding struct{} + +func (biomePaletteEncoding) Encode(buf *bytes.Buffer, v uint32) { + _ = binary.Write(buf, binary.LittleEndian, v) +} +func (biomePaletteEncoding) Decode(buf *bytes.Buffer) (uint32, error) { + var v uint32 + return v, binary.Read(buf, binary.LittleEndian, &v) +} + +// BlockPaletteEncoding implements the encoding of block palettes to disk. +type BlockPaletteEncoding struct { + block mapping.Block + version int32 +} + +// NewBlockPaletteEncoding returns a new BlockPaletteEncoding using the block and version passed. +func NewBlockPaletteEncoding(block mapping.Block, version int32) BlockPaletteEncoding { + return BlockPaletteEncoding{block: block, version: version} +} + +func (b BlockPaletteEncoding) Encode(buf *bytes.Buffer, v uint32) { + // Get the block state registered with the runtime IDs we have in the palette of the block storage + // as we need the name and data value to store. + state, _ := b.block.RuntimeIDToState(v) + _ = nbt.NewEncoderWithEncoding(buf, nbt.LittleEndian).Encode(blockupgrader.BlockState{Name: state.Name, Properties: state.Properties, Version: b.version}) +} +func (b BlockPaletteEncoding) Decode(buf *bytes.Buffer) (uint32, error) { + var e blockupgrader.BlockState + if err := nbt.NewDecoderWithEncoding(buf, nbt.LittleEndian).Decode(&e); err != nil { + return 0, fmt.Errorf("error decoding block palette entry: %w", err) + } + v, ok := b.block.StateToRuntimeID(e) + if !ok { + return 0, fmt.Errorf("cannot get runtime ID of block state %v{%+v}", e.Name, e.Properties) + } + return v, nil +} + +// NewNetworkPersistentEncoding returns a new NetworkPersistentEncoding using the block and version passed. +func NewNetworkPersistentEncoding(block mapping.Block, version int32) NetworkPersistentEncoding { + return NetworkPersistentEncoding{block: block, version: version} +} + +// NetworkPersistentEncoding implements the Chunk encoding for sending over network with a persistent palette. +type NetworkPersistentEncoding struct { + block mapping.Block + version int32 +} + +func (n NetworkPersistentEncoding) Network() byte { return 1 } +func (n NetworkPersistentEncoding) EncodePalette(buf *bytes.Buffer, p *Palette, _ PaletteEncoding) { + if p.size != 0 { + _ = protocol.WriteVarint32(buf, int32(p.Len())) + } + + enc := nbt.NewEncoderWithEncoding(buf, nbt.NetworkLittleEndian) + for _, val := range p.values { + state, _ := n.block.RuntimeIDToState(val) + _ = enc.Encode(blockupgrader.BlockState{Name: strings.TrimPrefix("minecraft:", state.Name), Properties: state.Properties, Version: n.version}) + } +} +func (n NetworkPersistentEncoding) DecodePalette(buf *bytes.Buffer, blockSize paletteSize, _ PaletteEncoding) (*Palette, error) { + var paletteCount int32 = 1 + if blockSize != 0 { + err := protocol.Varint32(buf, &paletteCount) + if err != nil { + panic(err) + } + if paletteCount <= 0 { + return nil, fmt.Errorf("invalid palette entry count %v", paletteCount) + } + } + + blocks := make([]blockupgrader.BlockState, paletteCount) + dec := nbt.NewDecoderWithEncoding(buf, nbt.NetworkLittleEndian) + for i := int32(0); i < paletteCount; i++ { + if err := dec.Decode(&blocks[i]); err != nil { + return nil, fmt.Errorf("error decoding block state: %w", err) + } + } + + var ok bool + palette, temp := newPalette(blockSize, make([]uint32, paletteCount)), uint32(0) + for i, b := range blocks { + temp, ok = n.block.StateToRuntimeID(blockupgrader.BlockState{Name: "minecraft:" + b.Name, Properties: b.Properties, Version: n.version}) + if !ok { + return nil, fmt.Errorf("cannot get runtime ID of block state %v{%+v}", b.Name, b.Properties) + } + palette.values[i] = temp + } + return palette, nil +} + +type subChunkVersion8 struct{} + +func (subChunkVersion8) EncodeHeader(buf *bytes.Buffer, s *SubChunk, _ cube.Range, _ int) { + _, _ = buf.Write([]byte{8, byte(len(s.storages))}) +} + +type subChunkVersion9 struct{} + +func (subChunkVersion9) EncodeHeader(buf *bytes.Buffer, s *SubChunk, r cube.Range, ind int) { + _, _ = buf.Write([]byte{SubChunkVersion, byte(len(s.storages)), uint8(ind + (r[0] >> 4))}) +} diff --git a/internal/chunk/palette.go b/internal/chunk/palette.go new file mode 100644 index 0000000..3b3d32b --- /dev/null +++ b/internal/chunk/palette.go @@ -0,0 +1,131 @@ +package chunk + +import ( + "math" +) + +// paletteSize is the size of a palette. It indicates the amount of bits occupied per value stored. +type paletteSize byte + +// Palette is a palette of values that every PalettedStorage has. Storages hold 'pointers' to indices +// in this palette. +type Palette struct { + last uint32 + lastIndex int16 + size paletteSize + + // values is a map of values. A PalettedStorage points to the index to this value. + values []uint32 +} + +// newPalette returns a new Palette with size and a slice of added values. +func newPalette(size paletteSize, values []uint32) *Palette { + return &Palette{size: size, values: values, last: math.MaxUint32} +} + +// Len returns the amount of unique values in the Palette. +func (palette *Palette) Len() int { + return len(palette.values) +} + +// Add adds a values to the Palette. It does not first check if the value was already set in the Palette. +// The index at which the value was added is returned. Another bool is returned indicating if the Palette +// was resized as a result of adding the value. +func (palette *Palette) Add(v uint32) (index int16, resize bool) { + i := int16(len(palette.values)) + palette.values = append(palette.values, v) + + if palette.needsResize() { + palette.increaseSize() + return i, true + } + return i, false +} + +// Replace calls the function passed for each value present in the Palette. The value returned by the +// function replaces the value present at the index of the value passed. +func (palette *Palette) Replace(f func(v uint32) uint32) { + // Reset last runtime ID as it now has a different offset. + palette.last = math.MaxUint32 + for index, v := range palette.values { + palette.values[index] = f(v) + } +} + +// Index loops through the values of the Palette and looks for the index of the given value. If the value could +// not be found, -1 is returned. +func (palette *Palette) Index(runtimeID uint32) int16 { + if runtimeID == palette.last { + // Fast path out. + return palette.lastIndex + } + // Slow path in a separate function allows for inlining the fast path. + return palette.indexSlow(runtimeID) +} + +// indexSlow searches the index of a value in the Palette's values by iterating through the Palette's values. +func (palette *Palette) indexSlow(runtimeID uint32) int16 { + l := len(palette.values) + for i := 0; i < l; i++ { + if palette.values[i] == runtimeID { + palette.last = runtimeID + v := int16(i) + palette.lastIndex = v + return v + } + } + return -1 +} + +// Value returns the value in the Palette at a specific index. +func (palette *Palette) Value(i uint16) uint32 { + return palette.values[i] +} + +// needsResize checks if the Palette, and with it the holding PalettedStorage, needs to be resized to a bigger +// size. +func (palette *Palette) needsResize() bool { + return len(palette.values) > (1 << palette.size) +} + +var sizes = [...]paletteSize{0, 1, 2, 3, 4, 5, 6, 8, 16} +var offsets = [...]int{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 8: 7, 16: 8} + +// increaseSize increases the size of the Palette to the next palette size. +func (palette *Palette) increaseSize() { + palette.size = sizes[offsets[palette.size]+1] +} + +// padded returns true if the Palette size is 3, 5 or 6. +func (p paletteSize) padded() bool { + return p == 3 || p == 5 || p == 6 +} + +// paletteSizeFor finds a suitable paletteSize for the amount of values passed n. +func paletteSizeFor(n int) paletteSize { + for _, size := range sizes { + if n <= (1 << size) { + return size + } + } + // Should never happen. + return 0 +} + +// uint32s returns the amount of uint32s needed to represent a storage with this palette size. +func (p paletteSize) uint32s() (n int) { + uint32Count := 0 + if p != 0 { + // indicesPerUint32 is the amount of indices that may be stored in a single uint32. + indicesPerUint32 := 32 / int(p) + // uint32Count is the amount of uint32s required to store all indices: 4096 indices need to be stored in + // total. + uint32Count = 4096 / indicesPerUint32 + } + if p.padded() { + // We've got one of the padded sizes, so the storage has another uint32 to be able to store + // every index. + uint32Count++ + } + return uint32Count +} diff --git a/internal/chunk/paletted_storage.go b/internal/chunk/paletted_storage.go new file mode 100644 index 0000000..89a7e45 --- /dev/null +++ b/internal/chunk/paletted_storage.go @@ -0,0 +1,200 @@ +package chunk + +import ( + "bytes" + "reflect" + "unsafe" +) + +const ( + // uint32ByteSize is the amount of bytes in a uint32. + uint32ByteSize = 4 + // uint32BitSize is the amount of bits in a uint32. + uint32BitSize = uint32ByteSize * 8 +) + +// PalettedStorage is a storage of 4096 blocks encoded in a variable amount of uint32s, storages may have values +// with a bit size per block of 0, 1, 2, 3, 4, 5, 6, 8 or 16 bits. +// 3 of these formats have additional padding in every uint32 and an additional uint32 at the end, to cater +// for the blocks that don't fit. This padding is present when the storage has a block size of 3, 5 or 6 +// bytes. +// Methods on PalettedStorage must not be called simultaneously from multiple goroutines. +type PalettedStorage struct { + // bitsPerIndex is the amount of bits required to store one block. The number increases as the block + // storage holds more unique block states. + bitsPerIndex uint16 + // filledBitsPerIndex returns the amount of blocks that are actually filled per uint32. + filledBitsPerIndex uint16 + // indexMask is the equivalent of 1 << bitsPerIndex - 1. + indexMask uint32 + + // indicesStart holds an unsafe.Pointer to the first byte in the indices slice below. + indicesStart unsafe.Pointer + + // Palette holds all block runtime IDs that the indices in the indices slice point to. These runtime IDs + // point to block states. + palette *Palette + + // indices contains all indices in the PalettedStorage. This slice has a variable size, but may not be changed + // unless the whole PalettedStorage is resized, including the Palette. + indices []uint32 +} + +// newPalettedStorage creates a new block storage using the uint32 slice as the indices and the palette passed. +// The bits per block are calculated using the length of the uint32 slice. +func newPalettedStorage(indices []uint32, palette *Palette) *PalettedStorage { + var ( + bitsPerIndex = uint16(len(indices) / uint32BitSize / uint32ByteSize) + indexMask = (uint32(1) << bitsPerIndex) - 1 + indicesStart = (unsafe.Pointer)((*reflect.SliceHeader)(unsafe.Pointer(&indices)).Data) + filledBitsPerIndex uint16 + ) + if bitsPerIndex != 0 { + filledBitsPerIndex = uint32BitSize / bitsPerIndex * bitsPerIndex + } + return &PalettedStorage{filledBitsPerIndex: filledBitsPerIndex, indexMask: indexMask, indicesStart: indicesStart, bitsPerIndex: bitsPerIndex, indices: indices, palette: palette} +} + +// emptyStorage creates a PalettedStorage filled completely with a value v. +func emptyStorage(v uint32) *PalettedStorage { + return newPalettedStorage([]uint32{}, newPalette(0, []uint32{v})) +} + +// Palette returns the Palette of the PalettedStorage. +func (storage *PalettedStorage) Palette() *Palette { + return storage.palette +} + +// At returns the value of the PalettedStorage at a given x, y and z. +func (storage *PalettedStorage) At(x, y, z byte) uint32 { + return storage.palette.Value(storage.paletteIndex(x&15, y&15, z&15)) +} + +// Set sets a value at a specific x, y and z. The Palette and PalettedStorage are expanded +// automatically to make space for the value, should that be needed. +func (storage *PalettedStorage) Set(x, y, z byte, v uint32) { + index := storage.palette.Index(v) + if index == -1 { + // The runtime ID was not yet available in the palette. We add it, then check if the block storage + // needs to be resized for the palette pointers to fit. + index = storage.addNew(v) + } + storage.setPaletteIndex(x&15, y&15, z&15, uint16(index)) +} + +// Equal checks if two PalettedStorages are equal value wise. False is returned +// if either of the storages are nil. +func (storage *PalettedStorage) Equal(other *PalettedStorage) bool { + if storage == nil || other == nil { + return false + } + if len(storage.indices) == 0 || len(other.indices) == 0 || storage.palette.values[0] == 0 || other.palette.values[0] == 0 { + return false + } + indicesA := unsafe.Slice((*byte)(unsafe.Pointer(&storage.indices[0])), len(storage.indices)*4) + indicesB := unsafe.Slice((*byte)(unsafe.Pointer(&other.indices[0])), len(other.indices)*4) + if !bytes.Equal(indicesA, indicesB) { + return false + } + paletteA := unsafe.Slice((*byte)(unsafe.Pointer(&storage.palette.values[0])), len(storage.palette.values)*4) + paletteB := unsafe.Slice((*byte)(unsafe.Pointer(&other.palette.values[0])), len(other.palette.values)*4) + return bytes.Equal(paletteA, paletteB) +} + +// addNew adds a new value to the PalettedStorage's Palette and returns its index. If needed, the storage is resized. +func (storage *PalettedStorage) addNew(v uint32) int16 { + index, resize := storage.palette.Add(v) + if resize { + storage.resize(storage.palette.size) + } + return index +} + +// paletteIndex looks up the Palette index at a given x, y and z value in the PalettedStorage. This palette +// index is not the value at this offset, but merely an index in the Palette pointing to a value. +func (storage *PalettedStorage) paletteIndex(x, y, z byte) uint16 { + if storage.bitsPerIndex == 0 { + // Unfortunately our default logic cannot deal with 0 bits per index, meaning we'll have to special case + // this. This comes with a little performance hit, but it seems to be the only way to go. An alternative would + // be not to have 0 bits per block storages in memory, but that would cause a strongly increased memory usage + // by biomes. + return 0 + } + offset := ((uint16(x) << 8) | (uint16(z) << 4) | uint16(y)) * storage.bitsPerIndex + uint32Offset, bitOffset := offset/storage.filledBitsPerIndex, offset%storage.filledBitsPerIndex + + w := *(*uint32)(unsafe.Pointer(uintptr(storage.indicesStart) + uintptr(uint32Offset<<2))) + return uint16((w >> bitOffset) & storage.indexMask) +} + +// setPaletteIndex sets the palette index at a given x, y and z to paletteIndex. This index should point +// to a value in the PalettedStorage's Palette. +func (storage *PalettedStorage) setPaletteIndex(x, y, z byte, i uint16) { + if storage.bitsPerIndex == 0 { + return + } + offset := ((uint16(x) << 8) | (uint16(z) << 4) | uint16(y)) * storage.bitsPerIndex + uint32Offset, bitOffset := offset/storage.filledBitsPerIndex, offset%storage.filledBitsPerIndex + + ptr := (*uint32)(unsafe.Pointer(uintptr(storage.indicesStart) + uintptr(uint32Offset<<2))) + *ptr = (*ptr &^ (storage.indexMask << bitOffset)) | (uint32(i) << bitOffset) +} + +// resize changes the size of a PalettedStorage to newPaletteSize. A new PalettedStorage is constructed, +// and all values available in the current storage are set in their appropriate locations in the +// new storage. +func (storage *PalettedStorage) resize(newPaletteSize paletteSize) { + if newPaletteSize == paletteSize(storage.bitsPerIndex) { + return // Don't resize if the size is already equal. + } + // Construct a new storage and set all values in there manually. We can't easily do this in a better + // way, because all values will be at a different index with a different length. + newStorage := newPalettedStorage(make([]uint32, newPaletteSize.uint32s()), storage.palette) + for x := byte(0); x < 16; x++ { + for y := byte(0); y < 16; y++ { + for z := byte(0); z < 16; z++ { + newStorage.setPaletteIndex(x, y, z, storage.paletteIndex(x, y, z)) + } + } + } + // Set the new storage. + *storage = *newStorage +} + +// compact clears unused indexes in the palette by scanning for usages in the PalettedStorage. This is a +// relatively heavy task which should only happen right before the sub chunk holding this PalettedStorage is +// saved to disk. compact also shrinks the palette size if possible. +func (storage *PalettedStorage) compact() { + usedIndices := make([]bool, storage.palette.Len()) + for x := byte(0); x < 16; x++ { + for y := byte(0); y < 16; y++ { + for z := byte(0); z < 16; z++ { + usedIndices[storage.paletteIndex(x, y, z)] = true + } + } + } + newRuntimeIDs := make([]uint32, 0, len(usedIndices)) + conversion := make([]uint16, len(usedIndices)) + + for index, set := range usedIndices { + if set { + conversion[index] = uint16(len(newRuntimeIDs)) + newRuntimeIDs = append(newRuntimeIDs, storage.palette.values[index]) + } + } + // Construct a new storage and set all values in there manually. We can't easily do this in a better + // way, because all values will be at a different index with a different length. + size := paletteSizeFor(len(newRuntimeIDs)) + newStorage := newPalettedStorage(make([]uint32, size.uint32s()), newPalette(size, newRuntimeIDs)) + + for x := byte(0); x < 16; x++ { + for y := byte(0); y < 16; y++ { + for z := byte(0); z < 16; z++ { + // Replace all usages of the old palette indexes with the new indexes using the map we + // produced earlier. + newStorage.setPaletteIndex(x, y, z, conversion[storage.paletteIndex(x, y, z)]) + } + } + } + *storage = *newStorage +} diff --git a/internal/chunk/sub_chunk.go b/internal/chunk/sub_chunk.go new file mode 100644 index 0000000..082b5c4 --- /dev/null +++ b/internal/chunk/sub_chunk.go @@ -0,0 +1,66 @@ +package chunk + +// SubChunk is a cube of blocks located in a chunk. It has a size of 16x16x16 blocks and forms part of a stack +// that forms a Chunk. +type SubChunk struct { + air uint32 + storages []*PalettedStorage + blockLight []uint8 + skyLight []uint8 +} + +// NewSubChunk creates a new sub chunk. All sub chunks should be created through this function +func NewSubChunk(air uint32) *SubChunk { + return &SubChunk{air: air} +} + +// Empty checks if the SubChunk is considered empty. This is the case if the SubChunk has 0 block storages or if it has +// a single one that is completely filled with air. +func (sub *SubChunk) Empty() bool { + return len(sub.storages) == 0 || (len(sub.storages) == 1 && len(sub.storages[0].palette.values) == 1 && sub.storages[0].palette.values[0] == sub.air) +} + +// Layer returns a certain block storage/layer from a sub chunk. If no storage at the layer exists, the layer +// is created, as well as all layers between the current highest layer and the new highest layer. +func (sub *SubChunk) Layer(layer uint8) *PalettedStorage { + for uint8(len(sub.storages)) <= layer { + // Keep appending to storages until the requested layer is achieved. Makes working with new layers + // much easier. + sub.storages = append(sub.storages, emptyStorage(sub.air)) + } + return sub.storages[layer] +} + +// Layers returns all layers in the sub chunk. This method may also return an empty slice. +func (sub *SubChunk) Layers() []*PalettedStorage { + return sub.storages +} + +// Block returns the runtime ID of the block located at the given X, Y and Z. X, Y and Z must be in a +// range of 0-15. +func (sub *SubChunk) Block(x, y, z byte, layer uint8) uint32 { + if uint8(len(sub.storages)) <= layer { + return sub.air + } + return sub.storages[layer].At(x, y, z) +} + +// SetBlock sets the given block runtime ID at the given X, Y and Z. X, Y and Z must be in a range of 0-15. +func (sub *SubChunk) SetBlock(x, y, z byte, layer uint8, block uint32) { + sub.Layer(layer).Set(x, y, z, block) +} + +// Compact cleans the garbage from all block storages that sub chunk contains, so that they may be +// cleanly written to a database. +func (sub *SubChunk) compact() { + newStorages := make([]*PalettedStorage, 0, len(sub.storages)) + for _, storage := range sub.storages { + storage.compact() + if len(storage.palette.values) == 1 && storage.palette.values[0] == sub.air { + // If the palette has only air in it, it means the storage is empty, so we can ignore it. + continue + } + newStorages = append(newStorages, storage) + } + sub.storages = newStorages +} diff --git a/internal/item/1.12.0_item_id_to_block_id_map.json b/internal/item/1.12.0_item_id_to_block_id_map.json new file mode 100644 index 0000000..7a3ed6e --- /dev/null +++ b/internal/item/1.12.0_item_id_to_block_id_map.json @@ -0,0 +1,481 @@ +{ + "minecraft:acacia_button": "minecraft:acacia_button", + "minecraft:acacia_fence_gate": "minecraft:acacia_fence_gate", + "minecraft:acacia_pressure_plate": "minecraft:acacia_pressure_plate", + "minecraft:acacia_stairs": "minecraft:acacia_stairs", + "minecraft:acacia_standing_sign": "minecraft:acacia_standing_sign", + "minecraft:acacia_trapdoor": "minecraft:acacia_trapdoor", + "minecraft:acacia_wall_sign": "minecraft:acacia_wall_sign", + "minecraft:activator_rail": "minecraft:activator_rail", + "minecraft:andesite_stairs": "minecraft:andesite_stairs", + "minecraft:anvil": "minecraft:anvil", + "minecraft:bamboo": "minecraft:bamboo", + "minecraft:bamboo_sapling": "minecraft:bamboo_sapling", + "minecraft:barrel": "minecraft:barrel", + "minecraft:barrier": "minecraft:barrier", + "minecraft:beacon": "minecraft:beacon", + "minecraft:bedrock": "minecraft:bedrock", + "minecraft:bell": "minecraft:bell", + "minecraft:birch_button": "minecraft:birch_button", + "minecraft:birch_fence_gate": "minecraft:birch_fence_gate", + "minecraft:birch_pressure_plate": "minecraft:birch_pressure_plate", + "minecraft:birch_stairs": "minecraft:birch_stairs", + "minecraft:birch_standing_sign": "minecraft:birch_standing_sign", + "minecraft:birch_trapdoor": "minecraft:birch_trapdoor", + "minecraft:birch_wall_sign": "minecraft:birch_wall_sign", + "minecraft:black_glazed_terracotta": "minecraft:black_glazed_terracotta", + "minecraft:blast_furnace": "minecraft:blast_furnace", + "minecraft:blue_glazed_terracotta": "minecraft:blue_glazed_terracotta", + "minecraft:blue_ice": "minecraft:blue_ice", + "minecraft:bone_block": "minecraft:bone_block", + "minecraft:bookshelf": "minecraft:bookshelf", + "minecraft:brewingstandblock": "minecraft:brewing_stand", + "minecraft:brick_block": "minecraft:brick_block", + "minecraft:brick_stairs": "minecraft:brick_stairs", + "minecraft:brown_glazed_terracotta": "minecraft:brown_glazed_terracotta", + "minecraft:brown_mushroom": "minecraft:brown_mushroom", + "minecraft:brown_mushroom_block": "minecraft:brown_mushroom_block", + "minecraft:bubble_column": "minecraft:bubble_column", + "minecraft:cactus": "minecraft:cactus", + "minecraft:carpet": "minecraft:carpet", + "minecraft:carrots": "minecraft:carrots", + "minecraft:cartography_table": "minecraft:cartography_table", + "minecraft:carved_pumpkin": "minecraft:carved_pumpkin", + "minecraft:chain_command_block": "minecraft:chain_command_block", + "minecraft:chemical_heat": "minecraft:chemical_heat", + "minecraft:chemistry_table": "minecraft:chemistry_table", + "minecraft:chest": "minecraft:chest", + "minecraft:chorus_flower": "minecraft:chorus_flower", + "minecraft:chorus_plant": "minecraft:chorus_plant", + "minecraft:clay": "minecraft:clay", + "minecraft:coal_block": "minecraft:coal_block", + "minecraft:coal_ore": "minecraft:coal_ore", + "minecraft:cobblestone": "minecraft:cobblestone", + "minecraft:cobblestone_wall": "minecraft:cobblestone_wall", + "minecraft:cocoa": "minecraft:cocoa", + "minecraft:colored_torch_bp": "minecraft:colored_torch_bp", + "minecraft:colored_torch_rg": "minecraft:colored_torch_rg", + "minecraft:command_block": "minecraft:command_block", + "minecraft:composter": "minecraft:composter", + "minecraft:concrete": "minecraft:concrete", + "minecraft:concrete_powder": "minecraft:concretePowder", + "minecraft:conduit": "minecraft:conduit", + "minecraft:coral": "minecraft:coral", + "minecraft:coral_block": "minecraft:coral_block", + "minecraft:coral_fan": "minecraft:coral_fan", + "minecraft:coral_fan_dead": "minecraft:coral_fan_dead", + "minecraft:coral_fan_hang": "minecraft:coral_fan_hang", + "minecraft:coral_fan_hang2": "minecraft:coral_fan_hang2", + "minecraft:coral_fan_hang3": "minecraft:coral_fan_hang3", + "minecraft:crafting_table": "minecraft:crafting_table", + "minecraft:cyan_glazed_terracotta": "minecraft:cyan_glazed_terracotta", + "minecraft:dark_oak_button": "minecraft:dark_oak_button", + "minecraft:dark_oak_fence_gate": "minecraft:dark_oak_fence_gate", + "minecraft:dark_oak_pressure_plate": "minecraft:dark_oak_pressure_plate", + "minecraft:dark_oak_stairs": "minecraft:dark_oak_stairs", + "minecraft:dark_oak_trapdoor": "minecraft:dark_oak_trapdoor", + "minecraft:dark_prismarine_stairs": "minecraft:dark_prismarine_stairs", + "minecraft:darkoak_standing_sign": "minecraft:darkoak_standing_sign", + "minecraft:darkoak_wall_sign": "minecraft:darkoak_wall_sign", + "minecraft:daylight_detector": "minecraft:daylight_detector", + "minecraft:daylight_detector_inverted": "minecraft:daylight_detector_inverted", + "minecraft:deadbush": "minecraft:deadbush", + "minecraft:detector_rail": "minecraft:detector_rail", + "minecraft:diamond_block": "minecraft:diamond_block", + "minecraft:diamond_ore": "minecraft:diamond_ore", + "minecraft:diorite_stairs": "minecraft:diorite_stairs", + "minecraft:dirt": "minecraft:dirt", + "minecraft:dispenser": "minecraft:dispenser", + "minecraft:double_plant": "minecraft:double_plant", + "minecraft:double_stone_slab": "minecraft:stone_slab", + "minecraft:double_stone_slab2": "minecraft:stone_slab2", + "minecraft:double_stone_slab3": "minecraft:stone_slab3", + "minecraft:double_stone_slab4": "minecraft:stone_slab4", + "minecraft:double_wooden_slab": "minecraft:double_wooden_slab", + "minecraft:dragon_egg": "minecraft:dragon_egg", + "minecraft:dried_kelp_block": "minecraft:dried_kelp_block", + "minecraft:dropper": "minecraft:dropper", + "minecraft:element_0": "minecraft:element_0", + "minecraft:element_1": "minecraft:element_1", + "minecraft:element_10": "minecraft:element_10", + "minecraft:element_100": "minecraft:element_100", + "minecraft:element_101": "minecraft:element_101", + "minecraft:element_102": "minecraft:element_102", + "minecraft:element_103": "minecraft:element_103", + "minecraft:element_104": "minecraft:element_104", + "minecraft:element_105": "minecraft:element_105", + "minecraft:element_106": "minecraft:element_106", + "minecraft:element_107": "minecraft:element_107", + "minecraft:element_108": "minecraft:element_108", + "minecraft:element_109": "minecraft:element_109", + "minecraft:element_11": "minecraft:element_11", + "minecraft:element_110": "minecraft:element_110", + "minecraft:element_111": "minecraft:element_111", + "minecraft:element_112": "minecraft:element_112", + "minecraft:element_113": "minecraft:element_113", + "minecraft:element_114": "minecraft:element_114", + "minecraft:element_115": "minecraft:element_115", + "minecraft:element_116": "minecraft:element_116", + "minecraft:element_117": "minecraft:element_117", + "minecraft:element_118": "minecraft:element_118", + "minecraft:element_12": "minecraft:element_12", + "minecraft:element_13": "minecraft:element_13", + "minecraft:element_14": "minecraft:element_14", + "minecraft:element_15": "minecraft:element_15", + "minecraft:element_16": "minecraft:element_16", + "minecraft:element_17": "minecraft:element_17", + "minecraft:element_18": "minecraft:element_18", + "minecraft:element_19": "minecraft:element_19", + "minecraft:element_2": "minecraft:element_2", + "minecraft:element_20": "minecraft:element_20", + "minecraft:element_21": "minecraft:element_21", + "minecraft:element_22": "minecraft:element_22", + "minecraft:element_23": "minecraft:element_23", + "minecraft:element_24": "minecraft:element_24", + "minecraft:element_25": "minecraft:element_25", + "minecraft:element_26": "minecraft:element_26", + "minecraft:element_27": "minecraft:element_27", + "minecraft:element_28": "minecraft:element_28", + "minecraft:element_29": "minecraft:element_29", + "minecraft:element_3": "minecraft:element_3", + "minecraft:element_30": "minecraft:element_30", + "minecraft:element_31": "minecraft:element_31", + "minecraft:element_32": "minecraft:element_32", + "minecraft:element_33": "minecraft:element_33", + "minecraft:element_34": "minecraft:element_34", + "minecraft:element_35": "minecraft:element_35", + "minecraft:element_36": "minecraft:element_36", + "minecraft:element_37": "minecraft:element_37", + "minecraft:element_38": "minecraft:element_38", + "minecraft:element_39": "minecraft:element_39", + "minecraft:element_4": "minecraft:element_4", + "minecraft:element_40": "minecraft:element_40", + "minecraft:element_41": "minecraft:element_41", + "minecraft:element_42": "minecraft:element_42", + "minecraft:element_43": "minecraft:element_43", + "minecraft:element_44": "minecraft:element_44", + "minecraft:element_45": "minecraft:element_45", + "minecraft:element_46": "minecraft:element_46", + "minecraft:element_47": "minecraft:element_47", + "minecraft:element_48": "minecraft:element_48", + "minecraft:element_49": "minecraft:element_49", + "minecraft:element_5": "minecraft:element_5", + "minecraft:element_50": "minecraft:element_50", + "minecraft:element_51": "minecraft:element_51", + "minecraft:element_52": "minecraft:element_52", + "minecraft:element_53": "minecraft:element_53", + "minecraft:element_54": "minecraft:element_54", + "minecraft:element_55": "minecraft:element_55", + "minecraft:element_56": "minecraft:element_56", + "minecraft:element_57": "minecraft:element_57", + "minecraft:element_58": "minecraft:element_58", + "minecraft:element_59": "minecraft:element_59", + "minecraft:element_6": "minecraft:element_6", + "minecraft:element_60": "minecraft:element_60", + "minecraft:element_61": "minecraft:element_61", + "minecraft:element_62": "minecraft:element_62", + "minecraft:element_63": "minecraft:element_63", + "minecraft:element_64": "minecraft:element_64", + "minecraft:element_65": "minecraft:element_65", + "minecraft:element_66": "minecraft:element_66", + "minecraft:element_67": "minecraft:element_67", + "minecraft:element_68": "minecraft:element_68", + "minecraft:element_69": "minecraft:element_69", + "minecraft:element_7": "minecraft:element_7", + "minecraft:element_70": "minecraft:element_70", + "minecraft:element_71": "minecraft:element_71", + "minecraft:element_72": "minecraft:element_72", + "minecraft:element_73": "minecraft:element_73", + "minecraft:element_74": "minecraft:element_74", + "minecraft:element_75": "minecraft:element_75", + "minecraft:element_76": "minecraft:element_76", + "minecraft:element_77": "minecraft:element_77", + "minecraft:element_78": "minecraft:element_78", + "minecraft:element_79": "minecraft:element_79", + "minecraft:element_8": "minecraft:element_8", + "minecraft:element_80": "minecraft:element_80", + "minecraft:element_81": "minecraft:element_81", + "minecraft:element_82": "minecraft:element_82", + "minecraft:element_83": "minecraft:element_83", + "minecraft:element_84": "minecraft:element_84", + "minecraft:element_85": "minecraft:element_85", + "minecraft:element_86": "minecraft:element_86", + "minecraft:element_87": "minecraft:element_87", + "minecraft:element_88": "minecraft:element_88", + "minecraft:element_89": "minecraft:element_89", + "minecraft:element_9": "minecraft:element_9", + "minecraft:element_90": "minecraft:element_90", + "minecraft:element_91": "minecraft:element_91", + "minecraft:element_92": "minecraft:element_92", + "minecraft:element_93": "minecraft:element_93", + "minecraft:element_94": "minecraft:element_94", + "minecraft:element_95": "minecraft:element_95", + "minecraft:element_96": "minecraft:element_96", + "minecraft:element_97": "minecraft:element_97", + "minecraft:element_98": "minecraft:element_98", + "minecraft:element_99": "minecraft:element_99", + "minecraft:emerald_block": "minecraft:emerald_block", + "minecraft:emerald_ore": "minecraft:emerald_ore", + "minecraft:enchanting_table": "minecraft:enchanting_table", + "minecraft:end_brick_stairs": "minecraft:end_brick_stairs", + "minecraft:end_bricks": "minecraft:end_bricks", + "minecraft:end_gateway": "minecraft:end_gateway", + "minecraft:end_portal": "minecraft:end_portal", + "minecraft:end_portal_frame": "minecraft:end_portal_frame", + "minecraft:end_rod": "minecraft:end_rod", + "minecraft:end_stone": "minecraft:end_stone", + "minecraft:ender_chest": "minecraft:ender_chest", + "minecraft:farmland": "minecraft:farmland", + "minecraft:fence": "minecraft:fence", + "minecraft:fence_gate": "minecraft:fence_gate", + "minecraft:fire": "minecraft:fire", + "minecraft:fletching_table": "minecraft:fletching_table", + "minecraft:flowing_lava": "minecraft:flowing_lava", + "minecraft:flowing_water": "minecraft:flowing_water", + "minecraft:frosted_ice": "minecraft:frosted_ice", + "minecraft:furnace": "minecraft:furnace", + "minecraft:glass": "minecraft:glass", + "minecraft:glass_pane": "minecraft:glass_pane", + "minecraft:glazedterracotta.black": "minecraft:black_glazed_terracotta", + "minecraft:glazedterracotta.blue": "minecraft:blue_glazed_terracotta", + "minecraft:glazedterracotta.brown": "minecraft:brown_glazed_terracotta", + "minecraft:glazedterracotta.cyan": "minecraft:cyan_glazed_terracotta", + "minecraft:glazedterracotta.gray": "minecraft:gray_glazed_terracotta", + "minecraft:glazedterracotta.green": "minecraft:green_glazed_terracotta", + "minecraft:glazedterracotta.light_blue": "minecraft:light_blue_glazed_terracotta", + "minecraft:glazedterracotta.lime": "minecraft:lime_glazed_terracotta", + "minecraft:glazedterracotta.magenta": "minecraft:magenta_glazed_terracotta", + "minecraft:glazedterracotta.orange": "minecraft:orange_glazed_terracotta", + "minecraft:glazedterracotta.pink": "minecraft:pink_glazed_terracotta", + "minecraft:glazedterracotta.purple": "minecraft:purple_glazed_terracotta", + "minecraft:glazedterracotta.red": "minecraft:red_glazed_terracotta", + "minecraft:glazedterracotta.silver": "minecraft:silver_glazed_terracotta", + "minecraft:glazedterracotta.white": "minecraft:white_glazed_terracotta", + "minecraft:glazedterracotta.yellow": "minecraft:yellow_glazed_terracotta", + "minecraft:glowingobsidian": "minecraft:glowingobsidian", + "minecraft:glowstone": "minecraft:glowstone", + "minecraft:gold_block": "minecraft:gold_block", + "minecraft:gold_ore": "minecraft:gold_ore", + "minecraft:golden_rail": "minecraft:golden_rail", + "minecraft:granite_stairs": "minecraft:granite_stairs", + "minecraft:grass": "minecraft:grass", + "minecraft:grass_path": "minecraft:grass_path", + "minecraft:gravel": "minecraft:gravel", + "minecraft:gray_glazed_terracotta": "minecraft:gray_glazed_terracotta", + "minecraft:green_glazed_terracotta": "minecraft:green_glazed_terracotta", + "minecraft:grindstone": "minecraft:grindstone", + "minecraft:hard_glass": "minecraft:hard_glass", + "minecraft:hard_glass_pane": "minecraft:hard_glass_pane", + "minecraft:hard_stained_glass": "minecraft:hard_stained_glass", + "minecraft:hard_stained_glass_pane": "minecraft:hard_stained_glass_pane", + "minecraft:hardened_clay": "minecraft:hardened_clay", + "minecraft:hay_block": "minecraft:hay_block", + "minecraft:heavy_weighted_pressure_plate": "minecraft:heavy_weighted_pressure_plate", + "minecraft:ice": "minecraft:ice", + "minecraft:info_update": "minecraft:info_update", + "minecraft:info_update2": "minecraft:info_update2", + "minecraft:invisiblebedrock": "minecraft:invisibleBedrock", + "minecraft:iron_bars": "minecraft:iron_bars", + "minecraft:iron_block": "minecraft:iron_block", + "minecraft:iron_ore": "minecraft:iron_ore", + "minecraft:iron_trapdoor": "minecraft:iron_trapdoor", + "minecraft:item.acacia_door": "minecraft:acacia_door", + "minecraft:item.bed": "minecraft:bed", + "minecraft:item.beetroot": "minecraft:beetroot", + "minecraft:item.birch_door": "minecraft:birch_door", + "minecraft:item.cake": "minecraft:cake", + "minecraft:item.campfire": "minecraft:campfire", + "minecraft:item.cauldron": "minecraft:cauldron", + "minecraft:item.dark_oak_door": "minecraft:dark_oak_door", + "minecraft:item.flower_pot": "minecraft:flower_pot", + "minecraft:item.frame": "minecraft:frame", + "minecraft:item.hopper": "minecraft:hopper", + "minecraft:item.iron_door": "minecraft:iron_door", + "minecraft:item.jungle_door": "minecraft:jungle_door", + "minecraft:item.kelp": "minecraft:kelp", + "minecraft:item.nether_wart": "minecraft:nether_wart", + "minecraft:item.reeds": "minecraft:reeds", + "minecraft:item.skull": "minecraft:skull", + "minecraft:item.spruce_door": "minecraft:spruce_door", + "minecraft:item.wheat": "minecraft:wheat", + "minecraft:item.wooden_door": "minecraft:wooden_door", + "minecraft:jigsaw": "minecraft:jigsaw", + "minecraft:jukebox": "minecraft:jukebox", + "minecraft:jungle_button": "minecraft:jungle_button", + "minecraft:jungle_fence_gate": "minecraft:jungle_fence_gate", + "minecraft:jungle_pressure_plate": "minecraft:jungle_pressure_plate", + "minecraft:jungle_stairs": "minecraft:jungle_stairs", + "minecraft:jungle_standing_sign": "minecraft:jungle_standing_sign", + "minecraft:jungle_trapdoor": "minecraft:jungle_trapdoor", + "minecraft:jungle_wall_sign": "minecraft:jungle_wall_sign", + "minecraft:ladder": "minecraft:ladder", + "minecraft:lantern": "minecraft:lantern", + "minecraft:lapis_block": "minecraft:lapis_block", + "minecraft:lapis_ore": "minecraft:lapis_ore", + "minecraft:lava": "minecraft:lava", + "minecraft:lava_cauldron": "minecraft:lava_cauldron", + "minecraft:leaves": "minecraft:leaves", + "minecraft:leaves2": "minecraft:leaves2", + "minecraft:lectern": "minecraft:lectern", + "minecraft:lever": "minecraft:lever", + "minecraft:light_blue_glazed_terracotta": "minecraft:light_blue_glazed_terracotta", + "minecraft:light_weighted_pressure_plate": "minecraft:light_weighted_pressure_plate", + "minecraft:lime_glazed_terracotta": "minecraft:lime_glazed_terracotta", + "minecraft:lit_blast_furnace": "minecraft:lit_blast_furnace", + "minecraft:lit_furnace": "minecraft:lit_furnace", + "minecraft:lit_pumpkin": "minecraft:lit_pumpkin", + "minecraft:lit_redstone_lamp": "minecraft:lit_redstone_lamp", + "minecraft:lit_redstone_ore": "minecraft:lit_redstone_ore", + "minecraft:lit_smoker": "minecraft:lit_smoker", + "minecraft:log": "minecraft:log", + "minecraft:log2": "minecraft:log2", + "minecraft:loom": "minecraft:loom", + "minecraft:magenta_glazed_terracotta": "minecraft:magenta_glazed_terracotta", + "minecraft:magma": "minecraft:magma", + "minecraft:melon_block": "minecraft:melon_block", + "minecraft:melon_stem": "minecraft:melon_stem", + "minecraft:mob_spawner": "minecraft:mob_spawner", + "minecraft:monster_egg": "minecraft:monster_egg", + "minecraft:mossy_cobblestone": "minecraft:mossy_cobblestone", + "minecraft:mossy_cobblestone_stairs": "minecraft:mossy_cobblestone_stairs", + "minecraft:mossy_stone_brick_stairs": "minecraft:mossy_stone_brick_stairs", + "minecraft:movingblock": "minecraft:movingBlock", + "minecraft:mycelium": "minecraft:mycelium", + "minecraft:nether_brick": "minecraft:nether_brick", + "minecraft:nether_brick_fence": "minecraft:nether_brick_fence", + "minecraft:nether_brick_stairs": "minecraft:nether_brick_stairs", + "minecraft:nether_wart_block": "minecraft:nether_wart_block", + "minecraft:netherrack": "minecraft:netherrack", + "minecraft:netherreactor": "minecraft:netherreactor", + "minecraft:normal_stone_stairs": "minecraft:normal_stone_stairs", + "minecraft:noteblock": "minecraft:noteblock", + "minecraft:oak_stairs": "minecraft:oak_stairs", + "minecraft:observer": "minecraft:observer", + "minecraft:obsidian": "minecraft:obsidian", + "minecraft:orange_glazed_terracotta": "minecraft:orange_glazed_terracotta", + "minecraft:packed_ice": "minecraft:packed_ice", + "minecraft:pink_glazed_terracotta": "minecraft:pink_glazed_terracotta", + "minecraft:piston": "minecraft:piston", + "minecraft:pistonarmcollision": "minecraft:pistonArmCollision", + "minecraft:planks": "minecraft:planks", + "minecraft:podzol": "minecraft:podzol", + "minecraft:polished_andesite_stairs": "minecraft:polished_andesite_stairs", + "minecraft:polished_diorite_stairs": "minecraft:polished_diorite_stairs", + "minecraft:polished_granite_stairs": "minecraft:polished_granite_stairs", + "minecraft:portal": "minecraft:portal", + "minecraft:potatoes": "minecraft:potatoes", + "minecraft:powered_comparator": "minecraft:powered_comparator", + "minecraft:powered_repeater": "minecraft:powered_repeater", + "minecraft:prismarine": "minecraft:prismarine", + "minecraft:prismarine_bricks_stairs": "minecraft:prismarine_bricks_stairs", + "minecraft:prismarine_stairs": "minecraft:prismarine_stairs", + "minecraft:pumpkin": "minecraft:pumpkin", + "minecraft:pumpkin_stem": "minecraft:pumpkin_stem", + "minecraft:purple_glazed_terracotta": "minecraft:purple_glazed_terracotta", + "minecraft:purpur_block": "minecraft:purpur_block", + "minecraft:purpur_stairs": "minecraft:purpur_stairs", + "minecraft:quartz_block": "minecraft:quartz_block", + "minecraft:quartz_ore": "minecraft:quartz_ore", + "minecraft:quartz_stairs": "minecraft:quartz_stairs", + "minecraft:rail": "minecraft:rail", + "minecraft:real_double_stone_slab": "minecraft:double_stone_slab", + "minecraft:real_double_stone_slab2": "minecraft:double_stone_slab2", + "minecraft:real_double_stone_slab3": "minecraft:double_stone_slab3", + "minecraft:real_double_stone_slab4": "minecraft:double_stone_slab4", + "minecraft:red_flower": "minecraft:red_flower", + "minecraft:red_glazed_terracotta": "minecraft:red_glazed_terracotta", + "minecraft:red_mushroom": "minecraft:red_mushroom", + "minecraft:red_mushroom_block": "minecraft:red_mushroom_block", + "minecraft:red_nether_brick": "minecraft:red_nether_brick", + "minecraft:red_nether_brick_stairs": "minecraft:red_nether_brick_stairs", + "minecraft:red_sandstone": "minecraft:red_sandstone", + "minecraft:red_sandstone_stairs": "minecraft:red_sandstone_stairs", + "minecraft:redstone_block": "minecraft:redstone_block", + "minecraft:redstone_lamp": "minecraft:redstone_lamp", + "minecraft:redstone_ore": "minecraft:redstone_ore", + "minecraft:redstone_torch": "minecraft:redstone_torch", + "minecraft:redstone_wire": "minecraft:redstone_wire", + "minecraft:repeating_command_block": "minecraft:repeating_command_block", + "minecraft:reserved6": "minecraft:reserved6", + "minecraft:sand": "minecraft:sand", + "minecraft:sandstone": "minecraft:sandstone", + "minecraft:sandstone_stairs": "minecraft:sandstone_stairs", + "minecraft:sapling": "minecraft:sapling", + "minecraft:scaffolding": "minecraft:scaffolding", + "minecraft:sea_pickle": "minecraft:sea_pickle", + "minecraft:seagrass": "minecraft:seagrass", + "minecraft:sealantern": "minecraft:seaLantern", + "minecraft:shulker_box": "minecraft:shulker_box", + "minecraft:silver_glazed_terracotta": "minecraft:silver_glazed_terracotta", + "minecraft:slime": "minecraft:slime", + "minecraft:smithing_table": "minecraft:smithing_table", + "minecraft:smoker": "minecraft:smoker", + "minecraft:smooth_quartz_stairs": "minecraft:smooth_quartz_stairs", + "minecraft:smooth_red_sandstone_stairs": "minecraft:smooth_red_sandstone_stairs", + "minecraft:smooth_sandstone_stairs": "minecraft:smooth_sandstone_stairs", + "minecraft:smooth_stone": "minecraft:smooth_stone", + "minecraft:snow": "minecraft:snow", + "minecraft:snow_layer": "minecraft:snow_layer", + "minecraft:soul_sand": "minecraft:soul_sand", + "minecraft:sponge": "minecraft:sponge", + "minecraft:spruce_button": "minecraft:spruce_button", + "minecraft:spruce_fence_gate": "minecraft:spruce_fence_gate", + "minecraft:spruce_pressure_plate": "minecraft:spruce_pressure_plate", + "minecraft:spruce_stairs": "minecraft:spruce_stairs", + "minecraft:spruce_standing_sign": "minecraft:spruce_standing_sign", + "minecraft:spruce_trapdoor": "minecraft:spruce_trapdoor", + "minecraft:spruce_wall_sign": "minecraft:spruce_wall_sign", + "minecraft:stained_glass": "minecraft:stained_glass", + "minecraft:stained_glass_pane": "minecraft:stained_glass_pane", + "minecraft:stained_hardened_clay": "minecraft:stained_hardened_clay", + "minecraft:standing_banner": "minecraft:standing_banner", + "minecraft:standing_sign": "minecraft:standing_sign", + "minecraft:sticky_piston": "minecraft:sticky_piston", + "minecraft:stone": "minecraft:stone", + "minecraft:stone_brick_stairs": "minecraft:stone_brick_stairs", + "minecraft:stone_button": "minecraft:stone_button", + "minecraft:stone_pressure_plate": "minecraft:stone_pressure_plate", + "minecraft:stone_slab": "minecraft:stone_slab", + "minecraft:stone_slab2": "minecraft:stone_slab2", + "minecraft:stone_slab3": "minecraft:stone_slab3", + "minecraft:stone_slab4": "minecraft:stone_slab4", + "minecraft:stone_stairs": "minecraft:stone_stairs", + "minecraft:stonebrick": "minecraft:stonebrick", + "minecraft:stonecutter": "minecraft:stonecutter", + "minecraft:stonecutter_block": "minecraft:stonecutter_block", + "minecraft:stripped_acacia_log": "minecraft:stripped_acacia_log", + "minecraft:stripped_birch_log": "minecraft:stripped_birch_log", + "minecraft:stripped_dark_oak_log": "minecraft:stripped_dark_oak_log", + "minecraft:stripped_jungle_log": "minecraft:stripped_jungle_log", + "minecraft:stripped_oak_log": "minecraft:stripped_oak_log", + "minecraft:stripped_spruce_log": "minecraft:stripped_spruce_log", + "minecraft:structure_block": "minecraft:structure_block", + "minecraft:sweet_berry_bush": "minecraft:sweet_berry_bush", + "minecraft:tallgrass": "minecraft:tallgrass", + "minecraft:tnt": "minecraft:tnt", + "minecraft:torch": "minecraft:torch", + "minecraft:trapdoor": "minecraft:trapdoor", + "minecraft:trapped_chest": "minecraft:trapped_chest", + "minecraft:tripwire": "minecraft:tripWire", + "minecraft:tripwire_hook": "minecraft:tripwire_hook", + "minecraft:turtle_egg": "minecraft:turtle_egg", + "minecraft:underwater_torch": "minecraft:underwater_torch", + "minecraft:undyed_shulker_box": "minecraft:undyed_shulker_box", + "minecraft:unlit_redstone_torch": "minecraft:unlit_redstone_torch", + "minecraft:unpowered_comparator": "minecraft:unpowered_comparator", + "minecraft:unpowered_repeater": "minecraft:unpowered_repeater", + "minecraft:vine": "minecraft:vine", + "minecraft:wall_banner": "minecraft:wall_banner", + "minecraft:wall_sign": "minecraft:wall_sign", + "minecraft:water": "minecraft:water", + "minecraft:waterlily": "minecraft:waterlily", + "minecraft:web": "minecraft:web", + "minecraft:white_glazed_terracotta": "minecraft:white_glazed_terracotta", + "minecraft:wood": "minecraft:wood", + "minecraft:wooden_button": "minecraft:wooden_button", + "minecraft:wooden_pressure_plate": "minecraft:wooden_pressure_plate", + "minecraft:wooden_slab": "minecraft:wooden_slab", + "minecraft:wool": "minecraft:wool", + "minecraft:yellow_flower": "minecraft:yellow_flower", + "minecraft:yellow_glazed_terracotta": "minecraft:yellow_glazed_terracotta" +} diff --git a/internal/item/1.12.0_to_1.18.10_blockstate_map.bin b/internal/item/1.12.0_to_1.18.10_blockstate_map.bin new file mode 100644 index 0000000..fcafbb9 Binary files /dev/null and b/internal/item/1.12.0_to_1.18.10_blockstate_map.bin differ diff --git a/internal/item/registry.go b/internal/item/registry.go new file mode 100644 index 0000000..da70586 --- /dev/null +++ b/internal/item/registry.go @@ -0,0 +1,110 @@ +package item + +import ( + "bytes" + "embed" + "encoding/json" + "github.com/df-mc/worldupgrader/blockupgrader" + "github.com/sandertv/gophertunnel/minecraft/nbt" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "regexp" + "sort" + "strconv" +) + +var ( + //go:embed schemas/*.json + schemasFS embed.FS + //go:embed 1.12.0_item_id_to_block_id_map.json + rawItemToBlockIdMap []byte + //go:embed 1.12.0_to_1.18.10_blockstate_map.bin + rawblockStateMap []byte + // schemaIDs is a list of ids from all registered schemas. + schemaIDs []int + // schemas is a map of all registered item upgrade schemas. + schemas map[uint16]schema + // itemToBlockIdMap is a list of all registered item upgrade schemas. + itemToBlockIdMap map[string]string + // blockStateMap is a list of all legacy block states mapped to an upgraded version of it. + blockStateMap map[stateHash]blockupgrader.BlockState + + filenameRegex = regexp.MustCompile(`(\d{4})_[\w.]+\.json`) +) + +// stateHash is a struct that may be used as a map key for block states. +type stateHash struct { + // Name is the name of the block. It looks like 'minecraft:stone'. + Name string + // Metadata is the metadata value of the block. A lot of blocks only have 0 as data value, but some blocks + // carry specific variants or properties encoded in the metadata. + Metadata uint32 +} + +// init ... +func init() { + schemas = make(map[uint16]schema) + files, err := schemasFS.ReadDir("schemas") + if err != nil { + panic(err) + } + for _, f := range files { + if f.IsDir() { + continue + } + subMatches := filenameRegex.FindStringSubmatch(f.Name()) + if subMatches == nil { + continue + } + id, err := strconv.Atoi(subMatches[1]) + if err != nil { + continue + } + + buf, err := schemasFS.ReadFile("schemas/" + f.Name()) + if err != nil { + panic(err) + } + var s schema + if err = json.Unmarshal(buf, &s); err != nil { + panic(err) + } + schemas[uint16(id)] = s + } + schemaIDs = make([]int, 0, len(schemas)) + for k := range schemas { + schemaIDs = append(schemaIDs, int(k)) + } + sort.Sort(sort.Reverse(sort.IntSlice(schemaIDs))) + + if err = json.Unmarshal(rawItemToBlockIdMap, &itemToBlockIdMap); err != nil { + panic(err) + } + + blockStateMap = make(map[stateHash]blockupgrader.BlockState) + buf := protocol.NewReader(bytes.NewBuffer(rawblockStateMap), 0, false) + var length uint32 + buf.Varuint32(&length) + for i := uint32(0); i < length; i++ { + var legacyStringId string + buf.String(&legacyStringId) + + var pairs uint32 + buf.Varuint32(&pairs) + for y := uint32(0); y < pairs; y++ { + var meta uint32 + buf.Varuint32(&meta) + + var blockStateRaw map[string]any + buf.NBT(&blockStateRaw, nbt.LittleEndian) + latestBlockState := blockupgrader.Upgrade(blockupgrader.BlockState{ + Name: blockStateRaw["name"].(string), + Properties: blockStateRaw["states"].(map[string]any), + Version: blockStateRaw["version"].(int32), + }) + blockStateMap[stateHash{ + Name: legacyStringId, + Metadata: meta, + }] = latestBlockState + } + } +} diff --git a/internal/item/schema.go b/internal/item/schema.go new file mode 100644 index 0000000..7491f2e --- /dev/null +++ b/internal/item/schema.go @@ -0,0 +1,7 @@ +package item + +// schema represents the schema for loading item upgrade data from a JSON file. +type schema struct { + RenamedIDs map[string]string `json:"renamedIds,omitempty"` + RemappedMetas map[string]map[uint32]string `json:"remappedMetas,omitempty"` +} diff --git a/internal/item/schemas/0001_1.6_beta_to_1.6.0.json b/internal/item/schemas/0001_1.6_beta_to_1.6.0.json new file mode 100644 index 0000000..8fdd19e --- /dev/null +++ b/internal/item/schemas/0001_1.6_beta_to_1.6.0.json @@ -0,0 +1,10 @@ +{ + "renamedIds": { + "minecraft:nametag": "minecraft:name_tag", + "minecraft:prismarineshard": "minecraft:prismarine_shard", + "minecraft:stone_slab": "minecraft:double_stone_slab", + "minecraft:stone_slab2": "minecraft:double_stone_slab2", + "minecraft:stone_slab3": "minecraft:double_stone_slab3", + "minecraft:stone_slab4": "minecraft:double_stone_slab4" + } +} diff --git a/internal/item/schemas/0011_1.11.4_to_1.12.0.json b/internal/item/schemas/0011_1.11.4_to_1.12.0.json new file mode 100644 index 0000000..824bddc --- /dev/null +++ b/internal/item/schemas/0011_1.11.4_to_1.12.0.json @@ -0,0 +1,20 @@ +{ + "renamedIds": { + "minecraft:glazedterracotta.black": "minecraft:black_glazed_terracotta", + "minecraft:glazedterracotta.blue": "minecraft:blue_glazed_terracotta", + "minecraft:glazedterracotta.brown": "minecraft:brown_glazed_terracotta", + "minecraft:glazedterracotta.cyan": "minecraft:cyan_glazed_terracotta", + "minecraft:glazedterracotta.gray": "minecraft:gray_glazed_terracotta", + "minecraft:glazedterracotta.green": "minecraft:green_glazed_terracotta", + "minecraft:glazedterracotta.light_blue": "minecraft:light_blue_glazed_terracotta", + "minecraft:glazedterracotta.lime": "minecraft:lime_glazed_terracotta", + "minecraft:glazedterracotta.magenta": "minecraft:magenta_glazed_terracotta", + "minecraft:glazedterracotta.orange": "minecraft:orange_glazed_terracotta", + "minecraft:glazedterracotta.pink": "minecraft:pink_glazed_terracotta", + "minecraft:glazedterracotta.purple": "minecraft:purple_glazed_terracotta", + "minecraft:glazedterracotta.red": "minecraft:red_glazed_terracotta", + "minecraft:glazedterracotta.silver": "minecraft:silver_glazed_terracotta", + "minecraft:glazedterracotta.white": "minecraft:white_glazed_terracotta", + "minecraft:glazedterracotta.yellow": "minecraft:yellow_glazed_terracotta" + } +} diff --git a/internal/item/schemas/0021_1.16.0_to_1.16.100.json b/internal/item/schemas/0021_1.16.0_to_1.16.100.json new file mode 100644 index 0000000..ce78553 --- /dev/null +++ b/internal/item/schemas/0021_1.16.0_to_1.16.100.json @@ -0,0 +1,165 @@ +{ + "remappedMetas": { + "minecraft:banner_pattern": { + "0": "minecraft:creeper_banner_pattern", + "1": "minecraft:skull_banner_pattern", + "2": "minecraft:flower_banner_pattern", + "3": "minecraft:mojang_banner_pattern", + "4": "minecraft:field_masoned_banner_pattern", + "5": "minecraft:bordure_indented_banner_pattern", + "6": "minecraft:piglin_banner_pattern" + }, + "minecraft:boat": { + "0": "minecraft:oak_boat", + "1": "minecraft:spruce_boat", + "2": "minecraft:birch_boat", + "3": "minecraft:jungle_boat", + "4": "minecraft:acacia_boat", + "5": "minecraft:dark_oak_boat" + }, + "minecraft:bucket": { + "1": "minecraft:milk_bucket", + "10": "minecraft:lava_bucket", + "2": "minecraft:cod_bucket", + "3": "minecraft:salmon_bucket", + "4": "minecraft:tropical_fish_bucket", + "5": "minecraft:pufferfish_bucket", + "8": "minecraft:water_bucket" + }, + "minecraft:coal": { + "1": "minecraft:charcoal" + }, + "minecraft:dye": { + "0": "minecraft:ink_sac", + "1": "minecraft:red_dye", + "10": "minecraft:lime_dye", + "11": "minecraft:yellow_dye", + "12": "minecraft:light_blue_dye", + "13": "minecraft:magenta_dye", + "14": "minecraft:orange_dye", + "15": "minecraft:bone_meal", + "16": "minecraft:black_dye", + "17": "minecraft:brown_dye", + "18": "minecraft:blue_dye", + "19": "minecraft:white_dye", + "2": "minecraft:green_dye", + "3": "minecraft:cocoa_beans", + "4": "minecraft:lapis_lazuli", + "5": "minecraft:purple_dye", + "6": "minecraft:cyan_dye", + "7": "minecraft:light_gray_dye", + "8": "minecraft:gray_dye", + "9": "minecraft:pink_dye" + }, + "minecraft:spawn_egg": { + "10": "minecraft:chicken_spawn_egg", + "104": "minecraft:evoker_spawn_egg", + "105": "minecraft:vex_spawn_egg", + "108": "minecraft:pufferfish_spawn_egg", + "109": "minecraft:salmon_spawn_egg", + "11": "minecraft:cow_spawn_egg", + "110": "minecraft:drowned_spawn_egg", + "111": "minecraft:tropical_fish_spawn_egg", + "112": "minecraft:cod_spawn_egg", + "113": "minecraft:panda_spawn_egg", + "114": "minecraft:pillager_spawn_egg", + "115": "minecraft:villager_spawn_egg", + "116": "minecraft:zombie_villager_spawn_egg", + "118": "minecraft:wandering_trader_spawn_egg", + "12": "minecraft:pig_spawn_egg", + "121": "minecraft:fox_spawn_egg", + "122": "minecraft:bee_spawn_egg", + "123": "minecraft:piglin_spawn_egg", + "124": "minecraft:hoglin_spawn_egg", + "125": "minecraft:strider_spawn_egg", + "126": "minecraft:zoglin_spawn_egg", + "127": "minecraft:piglin_brute_spawn_egg", + "13": "minecraft:sheep_spawn_egg", + "14": "minecraft:wolf_spawn_egg", + "15": "minecraft:villager_spawn_egg", + "16": "minecraft:mooshroom_spawn_egg", + "17": "minecraft:squid_spawn_egg", + "18": "minecraft:rabbit_spawn_egg", + "19": "minecraft:bat_spawn_egg", + "22": "minecraft:ocelot_spawn_egg", + "23": "minecraft:horse_spawn_egg", + "24": "minecraft:donkey_spawn_egg", + "25": "minecraft:mule_spawn_egg", + "26": "minecraft:skeleton_horse_spawn_egg", + "27": "minecraft:zombie_horse_spawn_egg", + "28": "minecraft:polar_bear_spawn_egg", + "29": "minecraft:llama_spawn_egg", + "30": "minecraft:parrot_spawn_egg", + "31": "minecraft:dolphin_spawn_egg", + "32": "minecraft:zombie_spawn_egg", + "33": "minecraft:creeper_spawn_egg", + "34": "minecraft:skeleton_spawn_egg", + "35": "minecraft:spider_spawn_egg", + "36": "minecraft:zombie_pigman_spawn_egg", + "37": "minecraft:slime_spawn_egg", + "38": "minecraft:enderman_spawn_egg", + "39": "minecraft:silverfish_spawn_egg", + "40": "minecraft:cave_spider_spawn_egg", + "41": "minecraft:ghast_spawn_egg", + "42": "minecraft:magma_cube_spawn_egg", + "43": "minecraft:blaze_spawn_egg", + "44": "minecraft:zombie_villager_spawn_egg", + "45": "minecraft:witch_spawn_egg", + "46": "minecraft:stray_spawn_egg", + "47": "minecraft:husk_spawn_egg", + "48": "minecraft:wither_skeleton_spawn_egg", + "49": "minecraft:guardian_spawn_egg", + "50": "minecraft:elder_guardian_spawn_egg", + "51": "minecraft:npc_spawn_egg", + "54": "minecraft:shulker_spawn_egg", + "55": "minecraft:endermite_spawn_egg", + "56": "minecraft:agent_spawn_egg", + "57": "minecraft:vindicator_spawn_egg", + "58": "minecraft:phantom_spawn_egg", + "59": "minecraft:ravager_spawn_egg", + "74": "minecraft:turtle_spawn_egg", + "75": "minecraft:cat_spawn_egg" + } + }, + "renamedIds": { + "minecraft:appleenchanted": "minecraft:enchanted_golden_apple", + "minecraft:carrotonastick": "minecraft:carrot_on_a_stick", + "minecraft:chorus_fruit_popped": "minecraft:popped_chorus_fruit", + "minecraft:clownfish": "minecraft:tropical_fish", + "minecraft:cooked_fish": "minecraft:cooked_cod", + "minecraft:darkoak_sign": "minecraft:dark_oak_sign", + "minecraft:emptymap": "minecraft:empty_map", + "minecraft:fireball": "minecraft:fire_charge", + "minecraft:fireworks": "minecraft:firework_rocket", + "minecraft:fireworkscharge": "minecraft:firework_star", + "minecraft:fish": "minecraft:cod", + "minecraft:horsearmordiamond": "minecraft:diamond_horse_armor", + "minecraft:horsearmorgold": "minecraft:golden_horse_armor", + "minecraft:horsearmoriron": "minecraft:iron_horse_armor", + "minecraft:horsearmorleather": "minecraft:leather_horse_armor", + "minecraft:lodestonecompass": "minecraft:lodestone_compass", + "minecraft:map": "minecraft:filled_map", + "minecraft:melon": "minecraft:melon_slice", + "minecraft:muttoncooked": "minecraft:cooked_mutton", + "minecraft:muttonraw": "minecraft:mutton", + "minecraft:netherstar": "minecraft:nether_star", + "minecraft:record_11": "minecraft:music_disc_11", + "minecraft:record_13": "minecraft:music_disc_13", + "minecraft:record_blocks": "minecraft:music_disc_blocks", + "minecraft:record_cat": "minecraft:music_disc_cat", + "minecraft:record_chirp": "minecraft:music_disc_chirp", + "minecraft:record_far": "minecraft:music_disc_far", + "minecraft:record_mall": "minecraft:music_disc_mall", + "minecraft:record_mellohi": "minecraft:music_disc_mellohi", + "minecraft:record_pigstep": "minecraft:music_disc_pigstep", + "minecraft:record_stal": "minecraft:music_disc_stal", + "minecraft:record_strad": "minecraft:music_disc_strad", + "minecraft:record_wait": "minecraft:music_disc_wait", + "minecraft:record_ward": "minecraft:music_disc_ward", + "minecraft:reeds": "minecraft:sugar_cane", + "minecraft:sign": "minecraft:oak_sign", + "minecraft:speckled_melon": "minecraft:glistering_melon_slice", + "minecraft:totem": "minecraft:totem_of_undying", + "minecraft:turtle_shell_piece": "minecraft:scute" + } +} diff --git a/internal/item/schemas/0031_1.16.100_to_1.16.200.json b/internal/item/schemas/0031_1.16.100_to_1.16.200.json new file mode 100644 index 0000000..1bdda6e --- /dev/null +++ b/internal/item/schemas/0031_1.16.100_to_1.16.200.json @@ -0,0 +1,7 @@ +{ + "remappedMetas": { + "minecraft:spawn_egg": { + "128": "minecraft:goat_spawn_egg" + } + } +} diff --git a/internal/item/schemas/0041_1.16.200_to_1.17.30.json b/internal/item/schemas/0041_1.16.200_to_1.17.30.json new file mode 100644 index 0000000..84e9a4e --- /dev/null +++ b/internal/item/schemas/0041_1.16.200_to_1.17.30.json @@ -0,0 +1,12 @@ +{ + "remappedMetas": { + "minecraft:bucket": { + "11": "minecraft:powder_snow_bucket", + "12": "minecraft:axolotl_bucket" + }, + "minecraft:spawn_egg": { + "129": "minecraft:glow_squid_spawn_egg", + "130": "minecraft:axolotl_spawn_egg" + } + } +} diff --git a/internal/item/schemas/0051_1.17.40_to_1.18.0.json b/internal/item/schemas/0051_1.17.40_to_1.18.0.json new file mode 100644 index 0000000..3b4ea9b --- /dev/null +++ b/internal/item/schemas/0051_1.17.40_to_1.18.0.json @@ -0,0 +1,5 @@ +{ + "renamedIds": { + "minecraft:record_otherside": "minecraft:music_disc_otherside" + } +} diff --git a/internal/item/schemas/0061_1.18.0_to_1.18.10.json b/internal/item/schemas/0061_1.18.0_to_1.18.10.json new file mode 100644 index 0000000..5221d9a --- /dev/null +++ b/internal/item/schemas/0061_1.18.0_to_1.18.10.json @@ -0,0 +1,16 @@ +{ + "remappedMetas": { + "minecraft:banner_pattern": { + "7": "minecraft:globe_banner_pattern" + }, + "minecraft:bucket": { + "13": "minecraft:tadpole_bucket" + }, + "minecraft:spawn_egg": { + "132": "minecraft:frog_spawn_egg", + "133": "minecraft:tadpole_spawn_egg", + "134": "minecraft:allay_spawn_egg", + "135": "minecraft:firefly_spawn_egg" + } + } +} diff --git a/internal/item/schemas/0071_1.18.10_to_1.18.30.json b/internal/item/schemas/0071_1.18.10_to_1.18.30.json new file mode 100644 index 0000000..3269f83 --- /dev/null +++ b/internal/item/schemas/0071_1.18.10_to_1.18.30.json @@ -0,0 +1,23 @@ +{ + "remappedMetas": { + "minecraft:chest_boat": { + "0": "minecraft:oak_chest_boat", + "1": "minecraft:spruce_chest_boat", + "2": "minecraft:birch_chest_boat", + "3": "minecraft:jungle_chest_boat", + "4": "minecraft:acacia_chest_boat", + "5": "minecraft:dark_oak_chest_boat" + }, + "minecraft:spawn_egg": { + "131": "minecraft:warden_spawn_egg" + } + }, + "renamedIds": { + "minecraft:concretepowder": "minecraft:concrete_powder", + "minecraft:invisiblebedrock": "minecraft:invisible_bedrock", + "minecraft:movingblock": "minecraft:moving_block", + "minecraft:pistonarmcollision": "minecraft:piston_arm_collision", + "minecraft:sealantern": "minecraft:sea_lantern", + "minecraft:stickypistonarmcollision": "minecraft:sticky_piston_arm_collision" + } +} diff --git a/internal/item/schemas/0081_1.18.30_to_1.19.30.34_beta.json b/internal/item/schemas/0081_1.18.30_to_1.19.30.34_beta.json new file mode 100644 index 0000000..4c3537a --- /dev/null +++ b/internal/item/schemas/0081_1.18.30_to_1.19.30.34_beta.json @@ -0,0 +1,25 @@ +{ + "remappedMetas": { + "minecraft:boat": { + "6": "minecraft:mangrove_boat" + }, + "minecraft:chest_boat": { + "6": "minecraft:mangrove_chest_boat" + } + }, + "renamedIds": { + "minecraft:double_stone_slab": "minecraft:stone_block_slab", + "minecraft:double_stone_slab2": "minecraft:stone_block_slab2", + "minecraft:double_stone_slab3": "minecraft:stone_block_slab3", + "minecraft:double_stone_slab4": "minecraft:stone_block_slab4", + "minecraft:real_double_stone_slab": "minecraft:double_stone_block_slab", + "minecraft:real_double_stone_slab2": "minecraft:double_stone_block_slab2", + "minecraft:real_double_stone_slab3": "minecraft:double_stone_block_slab3", + "minecraft:real_double_stone_slab4": "minecraft:double_stone_block_slab4", + "minecraft:record_5": "minecraft:music_disc_5", + "minecraft:stone_slab": "minecraft:stone_block_slab", + "minecraft:stone_slab2": "minecraft:stone_block_slab2", + "minecraft:stone_slab3": "minecraft:stone_block_slab3", + "minecraft:stone_slab4": "minecraft:stone_block_slab4" + } +} \ No newline at end of file diff --git a/internal/item/schemas/0091_1.19.60_to_1.19.70.26_beta.json b/internal/item/schemas/0091_1.19.60_to_1.19.70.26_beta.json new file mode 100644 index 0000000..b674687 --- /dev/null +++ b/internal/item/schemas/0091_1.19.60_to_1.19.70.26_beta.json @@ -0,0 +1,37 @@ +{ + "remappedMetas": { + "minecraft:boat": { + "7": "minecraft:bamboo_raft" + }, + "minecraft:chest_boat": { + "7": "minecraft:bamboo_chest_raft" + }, + "minecraft:spawn_egg": { + "138": "minecraft:camel_spawn_egg", + "139": "minecraft:sniffer_spawn_egg", + "157": "minecraft:trader_llama_spawn_egg", + "20": "minecraft:iron_golem_spawn_egg", + "21": "minecraft:snow_golem_spawn_egg", + "52": "minecraft:wither_spawn_egg", + "53": "minecraft:ender_dragon_spawn_egg" + }, + "minecraft:wool": { + "0": "minecraft:white_wool", + "1": "minecraft:orange_wool", + "10": "minecraft:purple_wool", + "11": "minecraft:blue_wool", + "12": "minecraft:brown_wool", + "13": "minecraft:green_wool", + "14": "minecraft:red_wool", + "15": "minecraft:black_wool", + "2": "minecraft:magenta_wool", + "3": "minecraft:light_blue_wool", + "4": "minecraft:yellow_wool", + "5": "minecraft:lime_wool", + "6": "minecraft:pink_wool", + "7": "minecraft:gray_wool", + "8": "minecraft:light_gray_wool", + "9": "minecraft:cyan_wool" + } + } +} \ No newline at end of file diff --git a/internal/item/schemas/0101_1.19.70_to_1.19.80.24_beta.json b/internal/item/schemas/0101_1.19.70_to_1.19.80.24_beta.json new file mode 100644 index 0000000..f79b82b --- /dev/null +++ b/internal/item/schemas/0101_1.19.70_to_1.19.80.24_beta.json @@ -0,0 +1,36 @@ +{ + "remappedMetas": { + "minecraft:boat": { + "8": "minecraft:cherry_boat" + }, + "minecraft:chest_boat": { + "8": "minecraft:cherry_chest_boat" + }, + "minecraft:fence": { + "0": "minecraft:oak_fence", + "1": "minecraft:spruce_fence", + "2": "minecraft:birch_fence", + "3": "minecraft:jungle_fence", + "4": "minecraft:acacia_fence", + "5": "minecraft:dark_oak_fence" + }, + "minecraft:log": { + "0": "minecraft:oak_log", + "1": "minecraft:spruce_log", + "10": "minecraft:birch_log", + "11": "minecraft:jungle_log", + "2": "minecraft:birch_log", + "3": "minecraft:jungle_log", + "5": "minecraft:spruce_log", + "6": "minecraft:birch_log", + "7": "minecraft:jungle_log", + "9": "minecraft:spruce_log" + }, + "minecraft:log2": { + "0": "minecraft:acacia_log", + "1": "minecraft:dark_oak_log", + "5": "minecraft:dark_oak_log", + "9": "minecraft:dark_oak_log" + } + } +} \ No newline at end of file diff --git a/internal/item/schemas/0111_1.19.80_to_1.20.0.23_beta.json b/internal/item/schemas/0111_1.19.80_to_1.20.0.23_beta.json new file mode 100644 index 0000000..5668a17 --- /dev/null +++ b/internal/item/schemas/0111_1.19.80_to_1.20.0.23_beta.json @@ -0,0 +1,37 @@ +{ + "remappedMetas": { + "minecraft:carpet": { + "0": "minecraft:white_carpet", + "1": "minecraft:orange_carpet", + "10": "minecraft:purple_carpet", + "11": "minecraft:blue_carpet", + "12": "minecraft:brown_carpet", + "13": "minecraft:green_carpet", + "14": "minecraft:red_carpet", + "15": "minecraft:black_carpet", + "2": "minecraft:magenta_carpet", + "3": "minecraft:light_blue_carpet", + "4": "minecraft:yellow_carpet", + "5": "minecraft:lime_carpet", + "6": "minecraft:pink_carpet", + "7": "minecraft:gray_carpet", + "8": "minecraft:light_gray_carpet", + "9": "minecraft:cyan_carpet" + }, + "minecraft:coral": { + "0": "minecraft:tube_coral", + "1": "minecraft:brain_coral", + "10": "minecraft:dead_bubble_coral", + "11": "minecraft:dead_fire_coral", + "12": "minecraft:dead_horn_coral", + "2": "minecraft:bubble_coral", + "3": "minecraft:fire_coral", + "4": "minecraft:horn_coral", + "8": "minecraft:dead_tube_coral", + "9": "minecraft:dead_brain_coral" + } + }, + "renamedIds": { + "minecraft:record_relic": "minecraft:music_disc_relic" + } +} \ No newline at end of file diff --git a/internal/item/schemas/0121_1.20.0.23_beta_to_1.20.10.24_beta.json b/internal/item/schemas/0121_1.20.0.23_beta_to_1.20.10.24_beta.json new file mode 100644 index 0000000..2d7a6db --- /dev/null +++ b/internal/item/schemas/0121_1.20.0.23_beta_to_1.20.10.24_beta.json @@ -0,0 +1,40 @@ +{ + "remappedMetas": { + "minecraft:concrete": { + "0": "minecraft:white_concrete", + "1": "minecraft:orange_concrete", + "10": "minecraft:purple_concrete", + "11": "minecraft:blue_concrete", + "12": "minecraft:brown_concrete", + "13": "minecraft:green_concrete", + "14": "minecraft:red_concrete", + "15": "minecraft:black_concrete", + "2": "minecraft:magenta_concrete", + "3": "minecraft:light_blue_concrete", + "4": "minecraft:yellow_concrete", + "5": "minecraft:lime_concrete", + "6": "minecraft:pink_concrete", + "7": "minecraft:gray_concrete", + "8": "minecraft:light_gray_concrete", + "9": "minecraft:cyan_concrete" + }, + "minecraft:shulker_box": { + "0": "minecraft:white_shulker_box", + "1": "minecraft:orange_shulker_box", + "10": "minecraft:purple_shulker_box", + "11": "minecraft:blue_shulker_box", + "12": "minecraft:brown_shulker_box", + "13": "minecraft:green_shulker_box", + "14": "minecraft:red_shulker_box", + "15": "minecraft:black_shulker_box", + "2": "minecraft:magenta_shulker_box", + "3": "minecraft:light_blue_shulker_box", + "4": "minecraft:yellow_shulker_box", + "5": "minecraft:lime_shulker_box", + "6": "minecraft:pink_shulker_box", + "7": "minecraft:gray_shulker_box", + "8": "minecraft:light_gray_shulker_box", + "9": "minecraft:cyan_shulker_box" + } + } +} \ No newline at end of file diff --git a/internal/item/schemas/0131_1.20.10.24_beta_to_1.20.20.23_beta.json b/internal/item/schemas/0131_1.20.10.24_beta_to_1.20.20.23_beta.json new file mode 100644 index 0000000..eadfe8e --- /dev/null +++ b/internal/item/schemas/0131_1.20.10.24_beta_to_1.20.20.23_beta.json @@ -0,0 +1,40 @@ +{ + "remappedMetas": { + "minecraft:stained_glass": { + "0": "minecraft:white_stained_glass", + "1": "minecraft:orange_stained_glass", + "10": "minecraft:purple_stained_glass", + "11": "minecraft:blue_stained_glass", + "12": "minecraft:brown_stained_glass", + "13": "minecraft:green_stained_glass", + "14": "minecraft:red_stained_glass", + "15": "minecraft:black_stained_glass", + "2": "minecraft:magenta_stained_glass", + "3": "minecraft:light_blue_stained_glass", + "4": "minecraft:yellow_stained_glass", + "5": "minecraft:lime_stained_glass", + "6": "minecraft:pink_stained_glass", + "7": "minecraft:gray_stained_glass", + "8": "minecraft:light_gray_stained_glass", + "9": "minecraft:cyan_stained_glass" + }, + "minecraft:stained_glass_pane": { + "0": "minecraft:white_stained_glass_pane", + "1": "minecraft:orange_stained_glass_pane", + "10": "minecraft:purple_stained_glass_pane", + "11": "minecraft:blue_stained_glass_pane", + "12": "minecraft:brown_stained_glass_pane", + "13": "minecraft:green_stained_glass_pane", + "14": "minecraft:red_stained_glass_pane", + "15": "minecraft:black_stained_glass_pane", + "2": "minecraft:magenta_stained_glass_pane", + "3": "minecraft:light_blue_stained_glass_pane", + "4": "minecraft:yellow_stained_glass_pane", + "5": "minecraft:lime_stained_glass_pane", + "6": "minecraft:pink_stained_glass_pane", + "7": "minecraft:gray_stained_glass_pane", + "8": "minecraft:light_gray_stained_glass_pane", + "9": "minecraft:cyan_stained_glass_pane" + } + } +} diff --git a/internal/item/schemas/0141_1.20.20.23_beta_to_1.20.30.22_beta.json b/internal/item/schemas/0141_1.20.20.23_beta_to_1.20.30.22_beta.json new file mode 100644 index 0000000..2c3a27d --- /dev/null +++ b/internal/item/schemas/0141_1.20.20.23_beta_to_1.20.30.22_beta.json @@ -0,0 +1,40 @@ +{ + "remappedMetas": { + "minecraft:concrete_powder": { + "0": "minecraft:white_concrete_powder", + "1": "minecraft:orange_concrete_powder", + "10": "minecraft:purple_concrete_powder", + "11": "minecraft:blue_concrete_powder", + "12": "minecraft:brown_concrete_powder", + "13": "minecraft:green_concrete_powder", + "14": "minecraft:red_concrete_powder", + "15": "minecraft:black_concrete_powder", + "2": "minecraft:magenta_concrete_powder", + "3": "minecraft:light_blue_concrete_powder", + "4": "minecraft:yellow_concrete_powder", + "5": "minecraft:lime_concrete_powder", + "6": "minecraft:pink_concrete_powder", + "7": "minecraft:gray_concrete_powder", + "8": "minecraft:light_gray_concrete_powder", + "9": "minecraft:cyan_concrete_powder" + }, + "minecraft:stained_hardened_clay": { + "0": "minecraft:white_terracotta", + "1": "minecraft:orange_terracotta", + "10": "minecraft:purple_terracotta", + "11": "minecraft:blue_terracotta", + "12": "minecraft:brown_terracotta", + "13": "minecraft:green_terracotta", + "14": "minecraft:red_terracotta", + "15": "minecraft:black_terracotta", + "2": "minecraft:magenta_terracotta", + "3": "minecraft:light_blue_terracotta", + "4": "minecraft:yellow_terracotta", + "5": "minecraft:lime_terracotta", + "6": "minecraft:pink_terracotta", + "7": "minecraft:gray_terracotta", + "8": "minecraft:light_gray_terracotta", + "9": "minecraft:cyan_terracotta" + } + } +} diff --git a/internal/item/schemas/0151_1.20.30.22_beta_to_1.20.50.23_beta.json b/internal/item/schemas/0151_1.20.30.22_beta_to_1.20.50.23_beta.json new file mode 100644 index 0000000..30e368f --- /dev/null +++ b/internal/item/schemas/0151_1.20.30.22_beta_to_1.20.50.23_beta.json @@ -0,0 +1,20 @@ +{ + "remappedMetas": { + "minecraft:planks": { + "0": "minecraft:oak_planks", + "1": "minecraft:spruce_planks", + "2": "minecraft:birch_planks", + "3": "minecraft:jungle_planks", + "4": "minecraft:acacia_planks", + "5": "minecraft:dark_oak_planks" + }, + "minecraft:stone": { + "1": "minecraft:granite", + "2": "minecraft:polished_granite", + "3": "minecraft:diorite", + "4": "minecraft:polished_diorite", + "5": "minecraft:andesite", + "6": "minecraft:polished_andesite" + } + } +} \ No newline at end of file diff --git a/internal/item/schemas/0161_1.20.50.23_beta_to_1.20.60.26_beta.json b/internal/item/schemas/0161_1.20.50.23_beta_to_1.20.60.26_beta.json new file mode 100644 index 0000000..31f762c --- /dev/null +++ b/internal/item/schemas/0161_1.20.50.23_beta_to_1.20.60.26_beta.json @@ -0,0 +1,47 @@ +{ + "remappedMetas": { + "minecraft:hard_stained_glass": { + "0": "minecraft:hard_white_stained_glass", + "1": "minecraft:hard_orange_stained_glass", + "10": "minecraft:hard_purple_stained_glass", + "11": "minecraft:hard_blue_stained_glass", + "12": "minecraft:hard_brown_stained_glass", + "13": "minecraft:hard_green_stained_glass", + "14": "minecraft:hard_red_stained_glass", + "15": "minecraft:hard_black_stained_glass", + "2": "minecraft:hard_magenta_stained_glass", + "3": "minecraft:hard_light_blue_stained_glass", + "4": "minecraft:hard_yellow_stained_glass", + "5": "minecraft:hard_lime_stained_glass", + "6": "minecraft:hard_pink_stained_glass", + "7": "minecraft:hard_gray_stained_glass", + "8": "minecraft:hard_light_gray_stained_glass", + "9": "minecraft:hard_cyan_stained_glass" + }, + "minecraft:hard_stained_glass_pane": { + "0": "minecraft:hard_white_stained_glass_pane", + "1": "minecraft:hard_orange_stained_glass_pane", + "10": "minecraft:hard_purple_stained_glass_pane", + "11": "minecraft:hard_blue_stained_glass_pane", + "12": "minecraft:hard_brown_stained_glass_pane", + "13": "minecraft:hard_green_stained_glass_pane", + "14": "minecraft:hard_red_stained_glass_pane", + "15": "minecraft:hard_black_stained_glass_pane", + "2": "minecraft:hard_magenta_stained_glass_pane", + "3": "minecraft:hard_light_blue_stained_glass_pane", + "4": "minecraft:hard_yellow_stained_glass_pane", + "5": "minecraft:hard_lime_stained_glass_pane", + "6": "minecraft:hard_pink_stained_glass_pane", + "7": "minecraft:hard_gray_stained_glass_pane", + "8": "minecraft:hard_light_gray_stained_glass_pane", + "9": "minecraft:hard_cyan_stained_glass_pane" + }, + "minecraft:spawn_egg": { + "140": "minecraft:breeze_spawn_egg", + "142": "minecraft:armadillo_spawn_egg" + } + }, + "renamedIds": { + "minecraft:scute": "minecraft:turtle_scute" + } +} \ No newline at end of file diff --git a/internal/item/schemas/0171_1.20.60.26_beta_to_1.20.70.24_beta.json b/internal/item/schemas/0171_1.20.60.26_beta_to_1.20.70.24_beta.json new file mode 100644 index 0000000..453199e --- /dev/null +++ b/internal/item/schemas/0171_1.20.60.26_beta_to_1.20.70.24_beta.json @@ -0,0 +1,42 @@ +{ + "remappedMetas": { + "minecraft:leaves": { + "0": "minecraft:oak_leaves", + "1": "minecraft:spruce_leaves", + "2": "minecraft:birch_leaves", + "3": "minecraft:jungle_leaves" + }, + "minecraft:leaves2": { + "0": "minecraft:acacia_leaves", + "1": "minecraft:dark_oak_leaves" + }, + "minecraft:spawn_egg": { + "144": "minecraft:bogged_spawn_egg" + }, + "minecraft:wood": { + "0": "minecraft:oak_wood", + "1": "minecraft:spruce_wood", + "10": "minecraft:stripped_birch_wood", + "11": "minecraft:stripped_jungle_wood", + "12": "minecraft:stripped_acacia_wood", + "13": "minecraft:stripped_dark_oak_wood", + "2": "minecraft:birch_wood", + "3": "minecraft:jungle_wood", + "4": "minecraft:acacia_wood", + "5": "minecraft:dark_oak_wood", + "8": "minecraft:stripped_oak_wood", + "9": "minecraft:stripped_spruce_wood" + }, + "minecraft:wooden_slab": { + "0": "minecraft:oak_slab", + "1": "minecraft:spruce_slab", + "2": "minecraft:birch_slab", + "3": "minecraft:jungle_slab", + "4": "minecraft:acacia_slab", + "5": "minecraft:dark_oak_slab" + } + }, + "renamedIds": { + "minecraft:grass": "minecraft:grass_block" + } +} \ No newline at end of file diff --git a/internal/item/schemas/0181_1.20.70.24_beta_to_1.20.80.24_beta.json b/internal/item/schemas/0181_1.20.70.24_beta_to_1.20.80.24_beta.json new file mode 100644 index 0000000..fb05350 --- /dev/null +++ b/internal/item/schemas/0181_1.20.70.24_beta_to_1.20.80.24_beta.json @@ -0,0 +1,39 @@ +{ + "remappedMetas": { + "minecraft:coral_fan": { + "0": "minecraft:tube_coral_fan", + "1": "minecraft:brain_coral_fan", + "2": "minecraft:bubble_coral_fan", + "3": "minecraft:fire_coral_fan", + "4": "minecraft:horn_coral_fan" + }, + "minecraft:coral_fan_dead": { + "0": "minecraft:dead_tube_coral_fan", + "1": "minecraft:dead_brain_coral_fan", + "2": "minecraft:dead_bubble_coral_fan", + "3": "minecraft:dead_fire_coral_fan", + "4": "minecraft:dead_horn_coral_fan" + }, + "minecraft:red_flower": { + "0": "minecraft:poppy", + "1": "minecraft:blue_orchid", + "10": "minecraft:lily_of_the_valley", + "2": "minecraft:allium", + "3": "minecraft:azure_bluet", + "4": "minecraft:red_tulip", + "5": "minecraft:orange_tulip", + "6": "minecraft:white_tulip", + "7": "minecraft:pink_tulip", + "8": "minecraft:oxeye_daisy", + "9": "minecraft:cornflower" + }, + "minecraft:sapling": { + "0": "minecraft:oak_sapling", + "1": "minecraft:spruce_sapling", + "2": "minecraft:birch_sapling", + "3": "minecraft:jungle_sapling", + "4": "minecraft:acacia_sapling", + "5": "minecraft:dark_oak_sapling" + } + } +} \ No newline at end of file diff --git a/internal/item/schemas/0191_1.20.80.24_beta_to_1.21.0.25_beta.json b/internal/item/schemas/0191_1.20.80.24_beta_to_1.21.0.25_beta.json new file mode 100644 index 0000000..9372668 --- /dev/null +++ b/internal/item/schemas/0191_1.20.80.24_beta_to_1.21.0.25_beta.json @@ -0,0 +1,44 @@ +{ + "remappedMetas": { + "minecraft:coral_block": { + "0": "minecraft:tube_coral_block", + "1": "minecraft:brain_coral_block", + "10": "minecraft:dead_bubble_coral_block", + "11": "minecraft:dead_fire_coral_block", + "12": "minecraft:dead_horn_coral_block", + "2": "minecraft:bubble_coral_block", + "3": "minecraft:fire_coral_block", + "4": "minecraft:horn_coral_block", + "8": "minecraft:dead_tube_coral_block", + "9": "minecraft:dead_brain_coral_block" + }, + "minecraft:double_plant": { + "0": "minecraft:sunflower", + "1": "minecraft:lilac", + "2": "minecraft:tall_grass", + "3": "minecraft:large_fern", + "4": "minecraft:rose_bush", + "5": "minecraft:peony" + }, + "minecraft:stone_block_slab": { + "0": "minecraft:smooth_stone_slab", + "1": "minecraft:sandstone_slab", + "2": "minecraft:petrified_oak_slab", + "3": "minecraft:cobblestone_slab", + "4": "minecraft:brick_slab", + "5": "minecraft:stone_brick_slab", + "6": "minecraft:quartz_slab", + "7": "minecraft:nether_brick_slab" + }, + "minecraft:tallgrass": { + "0": "minecraft:short_grass", + "2": "minecraft:fern", + "3": "minecraft:fern" + } + }, + "renamedIds": { + "minecraft:record_creator": "minecraft:music_disc_creator", + "minecraft:record_creator_music_box": "minecraft:music_disc_creator_music_box", + "minecraft:record_precipice": "minecraft:music_disc_precipice" + } +} \ No newline at end of file diff --git a/internal/item/schemas/0201_1.21.0.25_beta_to_1.21.20.24_beta.json b/internal/item/schemas/0201_1.21.0.25_beta_to_1.21.20.24_beta.json new file mode 100644 index 0000000..d160bb5 --- /dev/null +++ b/internal/item/schemas/0201_1.21.0.25_beta_to_1.21.20.24_beta.json @@ -0,0 +1,138 @@ +{ + "remappedMetas": { + "minecraft:anvil": { + "10": "minecraft:damaged_anvil", + "11": "minecraft:damaged_anvil", + "4": "minecraft:chipped_anvil", + "5": "minecraft:chipped_anvil", + "6": "minecraft:chipped_anvil", + "7": "minecraft:chipped_anvil", + "8": "minecraft:damaged_anvil", + "9": "minecraft:damaged_anvil" + }, + "minecraft:dirt": { + "1": "minecraft:coarse_dirt" + }, + "minecraft:double_stone_block_slab": { + "0": "minecraft:smooth_stone_double_slab", + "1": "minecraft:sandstone_double_slab", + "2": "minecraft:petrified_oak_double_slab", + "3": "minecraft:cobblestone_double_slab", + "4": "minecraft:brick_double_slab", + "5": "minecraft:stone_brick_double_slab", + "6": "minecraft:quartz_double_slab", + "7": "minecraft:nether_brick_double_slab" + }, + "minecraft:double_stone_block_slab2": { + "0": "minecraft:red_sandstone_double_slab", + "1": "minecraft:purpur_double_slab", + "2": "minecraft:prismarine_double_slab", + "3": "minecraft:dark_prismarine_double_slab", + "4": "minecraft:prismarine_brick_double_slab", + "5": "minecraft:mossy_cobblestone_double_slab", + "6": "minecraft:smooth_sandstone_double_slab", + "7": "minecraft:red_nether_brick_double_slab" + }, + "minecraft:double_stone_block_slab3": { + "0": "minecraft:end_stone_brick_double_slab", + "1": "minecraft:smooth_red_sandstone_double_slab", + "2": "minecraft:polished_andesite_double_slab", + "3": "minecraft:andesite_double_slab", + "4": "minecraft:diorite_double_slab", + "5": "minecraft:polished_diorite_double_slab", + "6": "minecraft:granite_double_slab", + "7": "minecraft:polished_granite_double_slab" + }, + "minecraft:double_stone_block_slab4": { + "0": "minecraft:mossy_stone_brick_double_slab", + "1": "minecraft:smooth_quartz_double_slab", + "2": "minecraft:normal_stone_double_slab", + "3": "minecraft:cut_sandstone_double_slab", + "4": "minecraft:cut_red_sandstone_double_slab" + }, + "minecraft:light_block": { + "0": "minecraft:light_block_0", + "1": "minecraft:light_block_1", + "10": "minecraft:light_block_10", + "11": "minecraft:light_block_11", + "12": "minecraft:light_block_12", + "13": "minecraft:light_block_13", + "14": "minecraft:light_block_14", + "15": "minecraft:light_block_15", + "2": "minecraft:light_block_2", + "3": "minecraft:light_block_3", + "4": "minecraft:light_block_4", + "5": "minecraft:light_block_5", + "6": "minecraft:light_block_6", + "7": "minecraft:light_block_7", + "8": "minecraft:light_block_8", + "9": "minecraft:light_block_9" + }, + "minecraft:monster_egg": { + "0": "minecraft:infested_stone", + "1": "minecraft:infested_cobblestone", + "2": "minecraft:infested_stone_bricks", + "3": "minecraft:infested_mossy_stone_bricks", + "4": "minecraft:infested_cracked_stone_bricks", + "5": "minecraft:infested_chiseled_stone_bricks" + }, + "minecraft:prismarine": { + "1": "minecraft:dark_prismarine", + "2": "minecraft:prismarine_bricks" + }, + "minecraft:quartz_block": { + "1": "minecraft:chiseled_quartz_block", + "2": "minecraft:quartz_pillar", + "3": "minecraft:smooth_quartz" + }, + "minecraft:red_sandstone": { + "1": "minecraft:chiseled_red_sandstone", + "2": "minecraft:cut_red_sandstone", + "3": "minecraft:smooth_red_sandstone" + }, + "minecraft:sand": { + "1": "minecraft:red_sand" + }, + "minecraft:sandstone": { + "1": "minecraft:chiseled_sandstone", + "2": "minecraft:cut_sandstone", + "3": "minecraft:smooth_sandstone" + }, + "minecraft:stone_block_slab2": { + "0": "minecraft:red_sandstone_slab", + "1": "minecraft:purpur_slab", + "2": "minecraft:prismarine_slab", + "3": "minecraft:dark_prismarine_slab", + "4": "minecraft:prismarine_brick_slab", + "5": "minecraft:mossy_cobblestone_slab", + "6": "minecraft:smooth_sandstone_slab", + "7": "minecraft:red_nether_brick_slab" + }, + "minecraft:stone_block_slab3": { + "0": "minecraft:end_stone_brick_slab", + "1": "minecraft:smooth_red_sandstone_slab", + "2": "minecraft:polished_andesite_slab", + "3": "minecraft:andesite_slab", + "4": "minecraft:diorite_slab", + "5": "minecraft:polished_diorite_slab", + "6": "minecraft:granite_slab", + "7": "minecraft:polished_granite_slab" + }, + "minecraft:stone_block_slab4": { + "0": "minecraft:mossy_stone_brick_slab", + "1": "minecraft:smooth_quartz_slab", + "2": "minecraft:normal_stone_slab", + "3": "minecraft:cut_sandstone_slab", + "4": "minecraft:cut_red_sandstone_slab" + }, + "minecraft:stonebrick": { + "0": "minecraft:stone_bricks", + "1": "minecraft:mossy_stone_bricks", + "2": "minecraft:cracked_stone_bricks", + "3": "minecraft:chiseled_stone_bricks" + } + }, + "renamedIds": { + "minecraft:yellow_flower": "minecraft:dandelion" + } +} \ No newline at end of file diff --git a/internal/item/schemas/0211_1.21.20.24_beta_to_1.21.30.24_beta.json b/internal/item/schemas/0211_1.21.20.24_beta_to_1.21.30.24_beta.json new file mode 100644 index 0000000..450a016 --- /dev/null +++ b/internal/item/schemas/0211_1.21.20.24_beta_to_1.21.30.24_beta.json @@ -0,0 +1,52 @@ +{ + "remappedMetas": { + "minecraft:chemistry_table": { + "0": "minecraft:compound_creator" + }, + "minecraft:cobblestone_wall": { + "1": "minecraft:mossy_cobblestone_wall", + "10": "minecraft:end_stone_brick_wall", + "11": "minecraft:prismarine_wall", + "12": "minecraft:red_sandstone_wall", + "13": "minecraft:red_nether_brick_wall", + "2": "minecraft:granite_wall", + "3": "minecraft:diorite_wall", + "4": "minecraft:andesite_wall", + "5": "minecraft:sandstone_wall", + "6": "minecraft:brick_wall", + "7": "minecraft:stone_brick_wall", + "8": "minecraft:mossy_stone_brick_wall", + "9": "minecraft:nether_brick_wall" + }, + "minecraft:colored_torch_bp": { + "0": "minecraft:colored_torch_blue", + "10": "minecraft:colored_torch_purple", + "11": "minecraft:colored_torch_purple", + "12": "minecraft:colored_torch_purple", + "13": "minecraft:colored_torch_purple", + "14": "minecraft:colored_torch_purple", + "15": "minecraft:colored_torch_purple", + "8": "minecraft:colored_torch_purple", + "9": "minecraft:colored_torch_purple" + }, + "minecraft:colored_torch_rg": { + "0": "minecraft:colored_torch_red", + "10": "minecraft:colored_torch_green", + "11": "minecraft:colored_torch_green", + "12": "minecraft:colored_torch_green", + "13": "minecraft:colored_torch_green", + "14": "minecraft:colored_torch_green", + "15": "minecraft:colored_torch_green", + "8": "minecraft:colored_torch_green", + "9": "minecraft:colored_torch_green" + }, + "minecraft:purpur_block": { + "1": "minecraft:deprecated_purpur_block_1", + "2": "minecraft:purpur_pillar", + "3": "minecraft:deprecated_purpur_block_2" + }, + "minecraft:sponge": { + "1": "minecraft:wet_sponge" + } + } +} \ No newline at end of file diff --git a/internal/item/schemas/0221_1.21.30.24_beta_to_1.21.40.25.json b/internal/item/schemas/0221_1.21.30.24_beta_to_1.21.40.25.json new file mode 100644 index 0000000..4e1c059 --- /dev/null +++ b/internal/item/schemas/0221_1.21.30.24_beta_to_1.21.40.25.json @@ -0,0 +1,13 @@ +{ + "remappedMetas": { + "minecraft:skull": { + "0": "minecraft:skeleton_skull", + "1": "minecraft:wither_skeleton_skull", + "2": "minecraft:zombie_head", + "3": "minecraft:player_head", + "4": "minecraft:creeper_head", + "5": "minecraft:dragon_head", + "6": "minecraft:piglin_head" + } + } +} \ No newline at end of file diff --git a/internal/item/upgrader.go b/internal/item/upgrader.go new file mode 100644 index 0000000..c3ece41 --- /dev/null +++ b/internal/item/upgrader.go @@ -0,0 +1,109 @@ +package item + +import ( + "github.com/df-mc/worldupgrader/blockupgrader" +) + +// Item ... +type Item struct { + Name string + Metadata uint32 + Version uint16 +} + +// Upgrade upgrades the given item using the registered item upgrade schemas. +func Upgrade(item Item, ver uint16) Item { + version := item.Version + for id, s := range schemas { + if version > id || id > ver { + continue + } + + name := item.Name + metadata := item.Metadata + nameRenamed := false + metadataRemapped := false + + if metadataCombinations, ok := s.RemappedMetas[name]; ok { + name, metadataRemapped = metadataCombinations[item.Metadata] + metadata = 0 + } else if name, nameRenamed = s.RenamedIDs[item.Name]; !nameRenamed { + name = item.Name + } + + if nameRenamed || metadataRemapped { + item = Item{ + Name: name, + Metadata: metadata, + Version: id, + } + } + } + return item +} + +// Downgrade downgrades the given item using the registered item upgrade schemas. +func Downgrade(item Item, ver uint16) Item { + for i, id := range schemaIDs { + s := schemas[uint16(id)] + if uint16(id) > item.Version { + continue + } + + name := item.Name + metadata := item.Metadata + nameRenamed := false + metadataRemapped := false + + for oldName, newName := range s.RenamedIDs { + if newName == name { + name = oldName + nameRenamed = true + } + } + + if !nameRenamed { + for oldName, m := range s.RemappedMetas { + for meta, newName := range m { + if newName == name { + name = oldName + metadata = meta + nameRenamed = true + metadataRemapped = true + } + } + if metadataRemapped { + break + } + } + } + + if ver > item.Version || i == len(schemaIDs)-1 { + break + } + + return Downgrade(Item{ + Name: name, + Metadata: metadata, + Version: uint16(schemaIDs[i+1]), + }, ver) + } + return item +} + +func BlockStateFromItemName(itemName string, metadata uint32) (blockupgrader.BlockState, bool) { + blockId, ok := itemToBlockIdMap[itemName] + if !ok { + return blockupgrader.BlockState{}, false + } + + blockState, ok := blockStateMap[stateHash{ + Name: blockId, + Metadata: metadata, + }] + return blockState, ok +} + +func BlockStateFromItem(item Item) (blockupgrader.BlockState, bool) { + return BlockStateFromItemName(item.Name, item.Metadata) +} diff --git a/internal/iterator.go b/internal/iterator.go new file mode 100644 index 0000000..5645635 --- /dev/null +++ b/internal/iterator.go @@ -0,0 +1,41 @@ +package internal + +type Iterator[T any] struct { + index int + values []T +} + +func NewIterator[T any](values []T) *Iterator[T] { + return &Iterator[T]{values: values} +} + +func (i *Iterator[T]) HasNext() bool { + if i.index < len(i.values) { + return true + } + return false +} + +func (i *Iterator[T]) HasPrevious() bool { + if i.index > 0 { + return true + } + return false +} + +func (i *Iterator[T]) Next() T { + if i.HasNext() { + value := i.values[i.index] + i.index++ + return value + } + panic("no more elements") +} + +func (i *Iterator[T]) Previous() T { + if i.HasPrevious() { + i.index-- + return i.values[i.index] + } + panic("no more elements") +} diff --git a/legacyver/bitset.go b/legacyver/bitset.go new file mode 100644 index 0000000..2ce8bbd --- /dev/null +++ b/legacyver/bitset.go @@ -0,0 +1,22 @@ +package legacyver + +import "github.com/sandertv/gophertunnel/minecraft/protocol" + +func fitBitset(b protocol.Bitset, size int) protocol.Bitset { + if b.Len() != size { + ret := protocol.NewBitset(size) + + copySize := b.Len() + if copySize > size { + copySize = size + } + + for i := 0; i < copySize; i++ { + if b.Load(i) { + ret.Set(i) + } + } + return ret + } + return b +} diff --git a/legacyver/block_states_748.nbt b/legacyver/block_states_748.nbt new file mode 100644 index 0000000..ff4d757 Binary files /dev/null and b/legacyver/block_states_748.nbt differ diff --git a/legacyver/block_states_766.nbt b/legacyver/block_states_766.nbt new file mode 100644 index 0000000..556c9ed Binary files /dev/null and b/legacyver/block_states_766.nbt differ diff --git a/legacyver/block_translator.go b/legacyver/block_translator.go new file mode 100644 index 0000000..78624b2 --- /dev/null +++ b/legacyver/block_translator.go @@ -0,0 +1,340 @@ +package legacyver + +import ( + "bytes" + _ "embed" + "github.com/akmalfairuz/legacy-version/internal/chunk" + "github.com/akmalfairuz/legacy-version/mapping" + "github.com/df-mc/dragonfly/server/block/cube" + "github.com/df-mc/dragonfly/server/world" + "github.com/sandertv/gophertunnel/minecraft" + "github.com/sandertv/gophertunnel/minecraft/nbt" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "github.com/sandertv/gophertunnel/minecraft/protocol/packet" +) + +const ( + BlockVersionLatest int32 = (1 << 24) | (21 << 16) | (50 << 8) | 29 +) + +var ( + //go:embed block_states_766.nbt + latestBlockStateData []byte + + // latestBlockMapping is the BlockMapping used for translating blocks between versions. + latestBlockMapping = mapping.NewBlockMapping(latestBlockStateData) + // LatestNetworkPersistentEncoding is the Encoding used for sending a Chunk over network. It uses NBT, unlike NetworkEncoding. + LatestNetworkPersistentEncoding = chunk.NewNetworkPersistentEncoding(latestBlockMapping, BlockVersionLatest) + // LatestBlockPaletteEncoding is the paletteEncoding used for encoding a palette of block states encoded as NBT. + LatestBlockPaletteEncoding = chunk.NewBlockPaletteEncoding(latestBlockMapping, BlockVersionLatest) +) + +type BlockTranslator interface { + // DowngradeBlockPackets downgrades the input block packets to legacy block packets. + DowngradeBlockPackets([]packet.Packet, *minecraft.Conn) (result []packet.Packet) + // UpgradeBlockPackets upgrades the input block packets to the latest block packets. + UpgradeBlockPackets([]packet.Packet, *minecraft.Conn) (result []packet.Packet) +} + +type DefaultBlockTranslator struct { + mapping mapping.Block + latest mapping.Block + pse chunk.Encoding + pe chunk.PaletteEncoding + oldFormat bool +} + +func NewBlockTranslator(mapping mapping.Block, latestMapping mapping.Block, pse chunk.Encoding, pe chunk.PaletteEncoding, oldFormat bool) *DefaultBlockTranslator { + return &DefaultBlockTranslator{mapping: mapping, latest: latestMapping, pse: pse, pe: pe, oldFormat: oldFormat} +} + +func (t *DefaultBlockTranslator) DowngradeBlockPackets(pks []packet.Packet, conn *minecraft.Conn) (result []packet.Packet) { + for _, pk := range pks { + switch pk := pk.(type) { + case *packet.LevelChunk: + count := int(pk.SubChunkCount) + if count == protocol.SubChunkRequestModeLimitless || count == protocol.SubChunkRequestModeLimited { + break + } + + buf := bytes.NewBuffer(pk.RawPayload) + writeBuf := bytes.NewBuffer(nil) + if !pk.CacheEnabled { + c, err := chunk.NetworkDecode(t.latest.Air(), buf, count, false, world.Overworld.Range(), LatestNetworkPersistentEncoding, LatestBlockPaletteEncoding) + if err != nil { + //fmt.Println(err) + break + } + c = t.DowngradeChunk(c) + + payload, err := chunk.NetworkEncode(t.mapping.Air(), c, t.oldFormat, t.pe) + if err != nil { + //fmt.Println(err) + break + } + writeBuf.Write(payload) + pk.SubChunkCount = uint32(len(c.Sub())) + } + safeBytes := buf.Bytes() + + countBorder, err := buf.ReadByte() + if err != nil { + pk.RawPayload = append(writeBuf.Bytes(), safeBytes...) + break + } + borderBytes := make([]byte, countBorder) + if _, err = buf.Read(borderBytes); err != nil { + pk.RawPayload = append(writeBuf.Bytes(), safeBytes...) + break + } + writeBuf.WriteByte(countBorder) + writeBuf.Write(borderBytes) + + enc := nbt.NewEncoderWithEncoding(writeBuf, nbt.NetworkLittleEndian) + dec := nbt.NewDecoderWithEncoding(buf, nbt.NetworkLittleEndian) + for { + var decNbt map[string]any + if err = dec.Decode(&decNbt); err != nil { + break + } + t.mapping.DowngradeBlockActorData(decNbt) + + if err = enc.Encode(decNbt); err != nil { + break + } + } + pk.RawPayload = append(writeBuf.Bytes(), buf.Bytes()...) + case *packet.SubChunk: + r := world.Overworld.Range() + if t.oldFormat { + r = cube.Range{0, 255} + } + + for i, entry := range pk.SubChunkEntries { + if entry.Result == protocol.SubChunkResultSuccess { + buf := bytes.NewBuffer(entry.RawPayload) + writeBuf := bytes.NewBuffer(nil) + if !pk.CacheEnabled && !conn.ClientCacheEnabled() { + ind := byte(i) + subChunk, err := chunk.DecodeSubChunk(t.latest.Air(), r, buf, &ind, chunk.NetworkEncoding, LatestNetworkPersistentEncoding, LatestBlockPaletteEncoding) + if err != nil { + //fmt.Println(err) + continue + } + t.DowngradeSubChunk(subChunk) + writeBuf.Write(chunk.EncodeSubChunk(subChunk, chunk.NetworkEncoding, t.pe, chunk.SubChunkVersion9, r, int(ind))) + } + + enc := nbt.NewEncoderWithEncoding(writeBuf, nbt.NetworkLittleEndian) + dec := nbt.NewDecoderWithEncoding(buf, nbt.NetworkLittleEndian) + for { + var decNbt map[string]any + if err := dec.Decode(&decNbt); err != nil { + break + } + t.mapping.DowngradeBlockActorData(decNbt) + + if err := enc.Encode(decNbt); err != nil { + break + } + } + + entry.RawPayload = append(writeBuf.Bytes(), buf.Bytes()...) + pk.SubChunkEntries[i] = entry + } + } + case *packet.ClientCacheMissResponse: + r := world.Overworld.Range() + if t.oldFormat { + r = cube.Range{0, 255} + } + + for i, blob := range pk.Blobs { + buf := bytes.NewBuffer(blob.Payload) + ind := byte(0) + subChunk, err := chunk.DecodeSubChunk(t.latest.Air(), r, buf, &ind, chunk.NetworkEncoding, LatestNetworkPersistentEncoding, LatestBlockPaletteEncoding) + if err != nil { + // Has a possibility to be a biome, ignore then + continue + } + t.DowngradeSubChunk(subChunk) + + blob.Payload = append(chunk.EncodeSubChunk(subChunk, chunk.NetworkEncoding, t.pe, chunk.SubChunkVersion9, r, int(ind)), buf.Bytes()...) + pk.Blobs[i] = blob + } + case *packet.UpdateSubChunkBlocks: + for i, block := range pk.Blocks { + block.BlockRuntimeID = t.DowngradeBlockRuntimeID(block.BlockRuntimeID) + pk.Blocks[i] = block + } + for i, block := range pk.Extra { + block.BlockRuntimeID = t.DowngradeBlockRuntimeID(block.BlockRuntimeID) + pk.Extra[i] = block + } + case *packet.UpdateBlock: + pk.NewBlockRuntimeID = t.DowngradeBlockRuntimeID(pk.NewBlockRuntimeID) + case *packet.UpdateBlockSynced: + pk.NewBlockRuntimeID = t.DowngradeBlockRuntimeID(pk.NewBlockRuntimeID) + case *packet.InventoryTransaction: + if transactionData, ok := pk.TransactionData.(*protocol.UseItemTransactionData); ok { + transactionData.BlockRuntimeID = t.DowngradeBlockRuntimeID(transactionData.BlockRuntimeID) + pk.TransactionData = transactionData + } + case *packet.LevelEvent: + switch pk.EventType { + case packet.LevelEventParticleLegacyEvent | 20: // terrain + fallthrough + case packet.LevelEventParticlesDestroyBlock: + fallthrough + case packet.LevelEventParticlesDestroyBlockNoSound: + pk.EventData = int32(t.DowngradeBlockRuntimeID(uint32(pk.EventData))) + case packet.LevelEventParticlesCrackBlock: + face := pk.EventData >> 24 + rid := t.DowngradeBlockRuntimeID(uint32(pk.EventData & 0xffff)) + pk.EventData = int32(rid) | (face << 24) + } + case *packet.LevelSoundEvent: + switch pk.SoundType { + case packet.SoundEventBreak: + fallthrough + case packet.SoundEventPlace: + fallthrough + case packet.SoundEventHit: + fallthrough + case packet.SoundEventLand: + fallthrough + case packet.SoundEventItemUseOn: + pk.ExtraData = int32(t.DowngradeBlockRuntimeID(uint32(pk.ExtraData))) + } + case *packet.AddActor: + if pk.EntityType == "minecraft:falling_block" { + pk.EntityMetadata = t.downgradeEntityMetadata(pk.EntityMetadata) + } + case *packet.SetActorData: + pk.EntityMetadata = t.downgradeEntityMetadata(pk.EntityMetadata) + case *packet.StartGame: + t.latest.Adjust(pk.Blocks) + t.mapping.Adjust(pk.Blocks) + case *packet.ResourcePackStack: + var packs []protocol.StackResourcePack + for _, pack := range pk.TexturePacks { + if pack.UUID == "0fba4063-dba1-4281-9b89-ff9390653530" { + continue + } + packs = append(packs, pack) + } + pk.TexturePacks = packs + } + result = append(result, pk) + } + return result +} + +func (t *DefaultBlockTranslator) UpgradeBlockPackets(pks []packet.Packet, conn *minecraft.Conn) (result []packet.Packet) { + for _, pk := range pks { + switch pk := pk.(type) { + case *packet.InventoryTransaction: + if transactionData, ok := pk.TransactionData.(*protocol.UseItemTransactionData); ok { + transactionData.BlockRuntimeID = t.UpgradeBlockRuntimeID(transactionData.BlockRuntimeID) + pk.TransactionData = transactionData + } + case *packet.SetActorData: + pk.EntityMetadata = t.upgradeEntityMetadata(pk.EntityMetadata) + } + result = append(result, pk) + } + return result +} + +func (t *DefaultBlockTranslator) DowngradeBlockRuntimeID(input uint32) uint32 { + if t.latest == t.mapping { + return input + } + state, ok := t.latest.RuntimeIDToState(input) + if !ok { + return t.mapping.Air() + } + runtimeID, ok := t.mapping.StateToRuntimeID(state) + if !ok { + return t.mapping.Air() + } + return runtimeID +} + +func (t *DefaultBlockTranslator) DowngradeChunk(input *chunk.Chunk) *chunk.Chunk { + if t.latest == t.mapping { + return input + } + + start := 0 + r := world.Overworld.Range() + if t.oldFormat { + start = 4 + r = cube.Range{0, 255} + } + downgraded := chunk.New(t.mapping.Air(), r) + + i := 0 + // First downgrade the blocks. + for _, sub := range input.Sub()[start : len(input.Sub())-start] { + t.DowngradeSubChunk(sub) + downgraded.Sub()[i] = sub + i += 1 + } + i = 0 + // Then downgrade the biome ids. + for _, sub := range input.BiomeSub()[start : len(input.BiomeSub())-start] { + // todo + sub.Palette().Replace(func(v uint32) uint32 { + return 0 // at least the client doesn't crash now + }) + downgraded.BiomeSub()[i] = sub + i += 1 + } + + return downgraded +} + +func (t *DefaultBlockTranslator) DowngradeSubChunk(input *chunk.SubChunk) { + if t.latest == t.mapping { + return + } + for _, storage := range input.Layers() { + storage.Palette().Replace(t.DowngradeBlockRuntimeID) + } +} + +func (t *DefaultBlockTranslator) downgradeEntityMetadata(metadata map[uint32]any) map[uint32]any { + if t.latest == t.mapping { + return metadata + } + if latestRID, ok := metadata[protocol.EntityDataKeyVariant]; ok { + metadata[protocol.EntityDataKeyVariant] = int32(t.DowngradeBlockRuntimeID(uint32(latestRID.(int32)))) + } + return metadata +} + +func (t *DefaultBlockTranslator) UpgradeBlockRuntimeID(input uint32) uint32 { + if t.latest == t.mapping { + return input + } + state, ok := t.mapping.RuntimeIDToState(input) + if !ok { + return t.latest.Air() + } + runtimeID, ok := t.latest.StateToRuntimeID(state) + if !ok { + return t.latest.Air() + } + return runtimeID +} + +func (t *DefaultBlockTranslator) upgradeEntityMetadata(metadata map[uint32]any) map[uint32]any { + if t.latest == t.mapping { + return metadata + } + if latestRID, ok := metadata[protocol.EntityDataKeyVariant]; ok { + metadata[protocol.EntityDataKeyVariant] = int32(t.UpgradeBlockRuntimeID(uint32(latestRID.(int32)))) + } + return metadata +} diff --git a/legacyver/item_runtime_ids_748.nbt b/legacyver/item_runtime_ids_748.nbt new file mode 100644 index 0000000..e1eb29e Binary files /dev/null and b/legacyver/item_runtime_ids_748.nbt differ diff --git a/legacyver/item_runtime_ids_766.nbt b/legacyver/item_runtime_ids_766.nbt new file mode 100644 index 0000000..10fa3de Binary files /dev/null and b/legacyver/item_runtime_ids_766.nbt differ diff --git a/legacyver/item_translator.go b/legacyver/item_translator.go new file mode 100644 index 0000000..812c0f2 --- /dev/null +++ b/legacyver/item_translator.go @@ -0,0 +1,767 @@ +package legacyver + +import ( + "fmt" + "github.com/akmalfairuz/legacy-version/internal/item" + "github.com/akmalfairuz/legacy-version/mapping" + "github.com/akmalfairuz/legacy-version/packbuilder" + "github.com/df-mc/dragonfly/server/world" + "github.com/samber/lo" + "github.com/sandertv/gophertunnel/minecraft" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "github.com/sandertv/gophertunnel/minecraft/protocol/packet" +) + +type ItemTranslator interface { + // DowngradeItemType downgrades the input item type to a legacy item type. + DowngradeItemType(input protocol.ItemType) protocol.ItemType + // DowngradeItemStack downgrades the input item stack to a legacy item stack. + DowngradeItemStack(input protocol.ItemStack) protocol.ItemStack + // DowngradeItemInstance downgrades the input item instance to a legacy item instance. + DowngradeItemInstance(input protocol.ItemInstance) protocol.ItemInstance + // DowngradeItemDescriptor downgrades the input item descriptor to a legacy item descriptor. + DowngradeItemDescriptor(input protocol.ItemDescriptor) protocol.ItemDescriptor + // DowngradeItemDescriptorCount downgrades the input item descriptor (with count) to a legacy item descriptor (with count). + DowngradeItemDescriptorCount(input protocol.ItemDescriptorCount) protocol.ItemDescriptorCount + DowngradeItemPackets(pks []packet.Packet, conn *minecraft.Conn) []packet.Packet + // UpgradeItemType upgrades the input item type to the latest item type. + UpgradeItemType(input protocol.ItemType) protocol.ItemType + // UpgradeItemStack upgrades the input item stack to the latest item stack. + UpgradeItemStack(input protocol.ItemStack) protocol.ItemStack + // UpgradeItemInstance upgrades the input item instance to the latest item instance. + UpgradeItemInstance(input protocol.ItemInstance) protocol.ItemInstance + // UpgradeItemDescriptor upgrades the input item descriptor to the latest item descriptor. + UpgradeItemDescriptor(input protocol.ItemDescriptor) protocol.ItemDescriptor + // UpgradeItemDescriptorCount upgrades the input item descriptor (with count) to the latest item descriptor (with count). + UpgradeItemDescriptorCount(input protocol.ItemDescriptorCount) protocol.ItemDescriptorCount + UpgradeItemPackets(pks []packet.Packet, conn *minecraft.Conn) []packet.Packet + // Register registers a custom item entry. + Register(item world.CustomItem, replacement string) + // CustomItems lists all custom items used as substitutes, with the runtime id as the key + CustomItems() map[int32]world.CustomItem +} + +type DefaultItemTranslator struct { + mapping mapping.Item + latest mapping.Item + blockMapping mapping.Block + blockMappingLatest mapping.Block + ridToCustomItem map[int32]world.CustomItem + originalToCustom map[int32]int32 + customToOriginal map[int32]int32 +} + +func NewItemTranslator(mapping mapping.Item, latestMapping mapping.Item, blockMapping mapping.Block, blockMappingLatest mapping.Block) *DefaultItemTranslator { + return &DefaultItemTranslator{mapping: mapping, latest: latestMapping, blockMapping: blockMapping, blockMappingLatest: blockMappingLatest, + ridToCustomItem: make(map[int32]world.CustomItem), originalToCustom: make(map[int32]int32), customToOriginal: make(map[int32]int32)} +} + +func (t *DefaultItemTranslator) DowngradeItemType(input protocol.ItemType) protocol.ItemType { + if t.latest == t.mapping { + return input + } + if input.NetworkID == t.latest.Air() || input.NetworkID == 0 { + return protocol.ItemType{ + NetworkID: t.mapping.Air(), + } + } + networkID := input.NetworkID + metadata := input.MetadataValue + + var ok bool + if networkID, ok = t.originalToCustom[input.NetworkID]; !ok { + name, _ := t.latest.ItemRuntimeIDToName(input.NetworkID) + i := item.Downgrade(item.Item{ + Name: name, + Metadata: input.MetadataValue, + Version: t.latest.ItemVersion(), + }, t.mapping.ItemVersion()) + metadata = i.Metadata + + if i.Name == "minecraft:netherstar" { + i.Name = "minecraft:nether_star" + } + + networkID, ok = t.mapping.ItemNameToRuntimeID(i.Name) + if !ok { + networkID, _ = t.mapping.ItemNameToRuntimeID("minecraft:info_update") + } + } + + return protocol.ItemType{ + NetworkID: networkID, + MetadataValue: metadata, + } +} + +func (t *DefaultItemTranslator) DowngradeItemStack(input protocol.ItemStack) protocol.ItemStack { + if t.latest == t.mapping { + return input + } + input.ItemType = t.DowngradeItemType(input.ItemType) + + blockRuntimeId := uint32(0) + if input.NetworkID != t.mapping.Air() { + name, _ := t.mapping.ItemRuntimeIDToName(input.NetworkID) + if latestBlockState, ok := item.BlockStateFromItemName(name, input.MetadataValue); ok { + var found bool + if blockRuntimeId, found = t.blockMapping.StateToRuntimeID(latestBlockState); !found { + blockRuntimeId = t.blockMapping.Air() + } + } + } + return protocol.ItemStack{ + ItemType: input.ItemType, + BlockRuntimeID: int32(blockRuntimeId), + Count: input.Count, + NBTData: input.NBTData, + CanBePlacedOn: input.CanBePlacedOn, + CanBreak: input.CanBreak, + HasNetworkID: input.HasNetworkID, + } +} + +func (t *DefaultItemTranslator) DowngradeItemInstance(input protocol.ItemInstance) protocol.ItemInstance { + if t.latest == t.mapping { + return input + } + input.Stack = t.DowngradeItemStack(input.Stack) + return input +} + +func (t *DefaultItemTranslator) DowngradeItemDescriptor(input protocol.ItemDescriptor) protocol.ItemDescriptor { + if t.latest == t.mapping { + return input + } + switch descriptor := input.(type) { + case *protocol.InvalidItemDescriptor: + return input + case *protocol.DefaultItemDescriptor: + itemType := t.DowngradeItemType(protocol.ItemType{NetworkID: int32(descriptor.NetworkID), MetadataValue: uint32(descriptor.MetadataValue)}) + descriptor.NetworkID, descriptor.MetadataValue = int16(itemType.NetworkID), int16(itemType.MetadataValue) + return descriptor + case *protocol.MoLangItemDescriptor: + return input + case *protocol.ItemTagItemDescriptor: + return input + case *protocol.DeferredItemDescriptor: + rid, ok := t.latest.ItemNameToRuntimeID(descriptor.Name) + descriptor.Name = "minecraft:air" + if !ok { + descriptor.MetadataValue = 0 + return descriptor + } + itemType := t.DowngradeItemType(protocol.ItemType{NetworkID: rid, MetadataValue: uint32(descriptor.MetadataValue)}) + descriptor.MetadataValue = int16(itemType.MetadataValue) + if name, ok := t.mapping.ItemRuntimeIDToName(itemType.NetworkID); ok { + descriptor.Name = name + } + return descriptor + case *protocol.ComplexAliasItemDescriptor: + rid, ok := t.latest.ItemNameToRuntimeID(descriptor.Name) + descriptor.Name = "minecraft:air" + if !ok { + return descriptor + } + itemType := t.DowngradeItemType(protocol.ItemType{NetworkID: rid}) + if name, ok := t.mapping.ItemRuntimeIDToName(itemType.NetworkID); ok { + descriptor.Name = name + } + return descriptor + } + panic("unknown item descriptor") +} + +func (t *DefaultItemTranslator) DowngradeItemDescriptorCount(input protocol.ItemDescriptorCount) protocol.ItemDescriptorCount { + if t.latest == t.mapping { + return input + } + input.Descriptor = t.DowngradeItemDescriptor(input.Descriptor) + return input +} + +func (t *DefaultItemTranslator) UpgradeItemType(input protocol.ItemType) protocol.ItemType { + if t.latest == t.mapping { + return input + } + if input.NetworkID == t.mapping.Air() || input.NetworkID == 0 { + return protocol.ItemType{ + NetworkID: t.latest.Air(), + } + } + networkID := input.NetworkID + metadata := input.MetadataValue + + var ok bool + if networkID, ok = t.customToOriginal[input.NetworkID]; !ok { + name, _ := t.mapping.ItemRuntimeIDToName(input.NetworkID) + i := item.Upgrade(item.Item{ + Name: name, + Metadata: input.MetadataValue, + Version: t.mapping.ItemVersion(), + }, t.latest.ItemVersion()) + networkID, ok = t.latest.ItemNameToRuntimeID(i.Name) + if !ok { + networkID, _ = t.latest.ItemNameToRuntimeID("minecraft:info_update") + } + } + + return protocol.ItemType{ + NetworkID: networkID, + MetadataValue: metadata, + } +} + +func (t *DefaultItemTranslator) UpgradeItemStack(input protocol.ItemStack) protocol.ItemStack { + if t.latest == t.mapping { + return input + } + input.ItemType = t.UpgradeItemType(input.ItemType) + + blockRuntimeId := uint32(0) + if input.NetworkID != t.latest.Air() { + name, _ := t.latest.ItemRuntimeIDToName(input.NetworkID) + if latestBlockState, ok := item.BlockStateFromItemName(name, input.MetadataValue); ok { + blockRuntimeId, _ = t.blockMappingLatest.StateToRuntimeID(latestBlockState) + } + } + return protocol.ItemStack{ + ItemType: input.ItemType, + BlockRuntimeID: int32(blockRuntimeId), + Count: input.Count, + NBTData: input.NBTData, + CanBePlacedOn: input.CanBePlacedOn, + CanBreak: input.CanBreak, + HasNetworkID: input.HasNetworkID, + } +} + +func (t *DefaultItemTranslator) UpgradeItemInstance(input protocol.ItemInstance) protocol.ItemInstance { + if t.latest == t.mapping { + return input + } + input.Stack = t.UpgradeItemStack(input.Stack) + return input +} + +func (t *DefaultItemTranslator) UpgradeItemDescriptor(input protocol.ItemDescriptor) protocol.ItemDescriptor { + if t.latest == t.mapping { + return input + } + switch descriptor := input.(type) { + case *protocol.InvalidItemDescriptor: + return input + case *protocol.DefaultItemDescriptor: + itemType := t.UpgradeItemType(protocol.ItemType{NetworkID: int32(descriptor.NetworkID), MetadataValue: uint32(descriptor.MetadataValue)}) + descriptor.NetworkID, descriptor.MetadataValue = int16(itemType.NetworkID), int16(itemType.MetadataValue) + return descriptor + case *protocol.MoLangItemDescriptor: + return input + case *protocol.ItemTagItemDescriptor: + return input + case *protocol.DeferredItemDescriptor: + rid, ok := t.mapping.ItemNameToRuntimeID(descriptor.Name) + descriptor.Name = "minecraft:air" + if !ok { + descriptor.MetadataValue = 0 + return descriptor + } + itemType := t.UpgradeItemType(protocol.ItemType{NetworkID: rid, MetadataValue: uint32(descriptor.MetadataValue)}) + descriptor.MetadataValue = int16(itemType.MetadataValue) + if name, ok := t.latest.ItemRuntimeIDToName(itemType.NetworkID); ok { + descriptor.Name = name + } + return descriptor + case *protocol.ComplexAliasItemDescriptor: + rid, ok := t.mapping.ItemNameToRuntimeID(descriptor.Name) + descriptor.Name = "minecraft:air" + if !ok { + return descriptor + } + itemType := t.UpgradeItemType(protocol.ItemType{NetworkID: rid}) + if name, ok := t.latest.ItemRuntimeIDToName(itemType.NetworkID); ok { + descriptor.Name = name + } + return descriptor + } + panic("unknown item descriptor") +} + +func (t *DefaultItemTranslator) UpgradeItemDescriptorCount(input protocol.ItemDescriptorCount) protocol.ItemDescriptorCount { + if t.latest == t.mapping { + return input + } + input.Descriptor = t.UpgradeItemDescriptor(input.Descriptor) + return input +} + +func (t *DefaultItemTranslator) DowngradeItemPackets(pks []packet.Packet, _ *minecraft.Conn) (result []packet.Packet) { + for _, pk := range pks { + switch pk := pk.(type) { + case *packet.MobEquipment: + pk.NewItem = t.DowngradeItemInstance(pk.NewItem) + case *packet.MobArmourEquipment: + pk.Helmet = t.DowngradeItemInstance(pk.Helmet) + pk.Chestplate = t.DowngradeItemInstance(pk.Chestplate) + pk.Leggings = t.DowngradeItemInstance(pk.Leggings) + pk.Boots = t.DowngradeItemInstance(pk.Boots) + pk.Body = t.DowngradeItemInstance(pk.Body) + case *packet.ActorEvent: + if pk.EventType == packet.ActorEventFeed { + value := pk.EventData + itemType := t.DowngradeItemType(protocol.ItemType{NetworkID: value >> 16, MetadataValue: uint32(value & 0xf)}) + pk.EventData = (itemType.NetworkID << 16) | int32(itemType.MetadataValue) + } + case *packet.AddItemActor: + pk.Item = t.DowngradeItemInstance(pk.Item) + case *packet.AddPlayer: + pk.HeldItem = t.DowngradeItemInstance(pk.HeldItem) + case *packet.InventorySlot: + pk.NewItem = t.DowngradeItemInstance(pk.NewItem) + case *packet.InventoryContent: + pk.Content = lo.Map(pk.Content, func(item protocol.ItemInstance, _ int) protocol.ItemInstance { + return t.DowngradeItemInstance(item) + }) + case *packet.ItemStackRequest: + for i, request := range pk.Requests { + for i2, action := range request.Actions { + if act, ok := action.(*protocol.CraftResultsDeprecatedStackRequestAction); ok { + act.ResultItems = lo.Map(act.ResultItems, func(item protocol.ItemStack, _ int) protocol.ItemStack { + return t.DowngradeItemStack(item) + }) + pk.Requests[i].Actions[i2] = act + } + } + } + case *packet.CraftingData: + for i, recipe := range pk.Recipes { + switch recipe := recipe.(type) { + case *protocol.ShapelessRecipe: + for i2, input := range recipe.Input { + recipe.Input[i2] = t.DowngradeItemDescriptorCount(input) + } + for i2, stack := range recipe.Output { + recipe.Output[i2] = t.DowngradeItemStack(stack) + } + pk.Recipes[i] = recipe + case *protocol.ShapedRecipe: + for i2, input := range recipe.Input { + recipe.Input[i2] = t.DowngradeItemDescriptorCount(input) + } + for i2, stack := range recipe.Output { + recipe.Output[i2] = t.DowngradeItemStack(stack) + } + pk.Recipes[i] = recipe + case *protocol.FurnaceRecipe: + recipe.InputType = t.DowngradeItemType(recipe.InputType) + recipe.Output = t.DowngradeItemStack(recipe.Output) + pk.Recipes[i] = recipe + case *protocol.FurnaceDataRecipe: + recipe.InputType = t.DowngradeItemType(recipe.InputType) + recipe.Output = t.DowngradeItemStack(recipe.Output) + pk.Recipes[i] = recipe + case *protocol.ShulkerBoxRecipe: + for i2, input := range recipe.Input { + recipe.Input[i2] = t.DowngradeItemDescriptorCount(input) + } + for i2, stack := range recipe.Output { + recipe.Output[i2] = t.DowngradeItemStack(stack) + } + pk.Recipes[i] = recipe + case *protocol.ShapelessChemistryRecipe: + for i2, input := range recipe.Input { + recipe.Input[i2] = t.DowngradeItemDescriptorCount(input) + } + for i2, stack := range recipe.Output { + recipe.Output[i2] = t.DowngradeItemStack(stack) + } + pk.Recipes[i] = recipe + case *protocol.ShapedChemistryRecipe: + for i2, input := range recipe.Input { + recipe.Input[i2] = t.DowngradeItemDescriptorCount(input) + } + for i2, stack := range recipe.Output { + recipe.Output[i2] = t.DowngradeItemStack(stack) + } + pk.Recipes[i] = recipe + case *protocol.SmithingTransformRecipe: + recipe.Template = t.DowngradeItemDescriptorCount(recipe.Template) + recipe.Base = t.DowngradeItemDescriptorCount(recipe.Base) + recipe.Addition = t.DowngradeItemDescriptorCount(recipe.Addition) + recipe.Result = t.DowngradeItemStack(recipe.Result) + pk.Recipes[i] = recipe + case *protocol.SmithingTrimRecipe: + recipe.Template = t.DowngradeItemDescriptorCount(recipe.Template) + recipe.Base = t.DowngradeItemDescriptorCount(recipe.Base) + recipe.Addition = t.DowngradeItemDescriptorCount(recipe.Addition) + } + } + for i, recipe := range pk.PotionRecipes { + itemType := t.DowngradeItemType(protocol.ItemType{NetworkID: recipe.InputPotionID, MetadataValue: uint32(recipe.InputPotionMetadata)}) + recipe.InputPotionID, recipe.InputPotionMetadata = itemType.NetworkID, int32(itemType.MetadataValue) + itemType = t.DowngradeItemType(protocol.ItemType{NetworkID: recipe.ReagentItemID, MetadataValue: uint32(recipe.ReagentItemMetadata)}) + recipe.ReagentItemID, recipe.ReagentItemMetadata = itemType.NetworkID, int32(itemType.MetadataValue) + itemType = t.DowngradeItemType(protocol.ItemType{NetworkID: recipe.OutputPotionID, MetadataValue: uint32(recipe.OutputPotionMetadata)}) + recipe.OutputPotionID, recipe.OutputPotionMetadata = itemType.NetworkID, int32(itemType.MetadataValue) + pk.PotionRecipes[i] = recipe + } + for i, recipe := range pk.PotionContainerChangeRecipes { + itemType := t.DowngradeItemType(protocol.ItemType{NetworkID: recipe.InputItemID}) + recipe.InputItemID = itemType.NetworkID + itemType = t.DowngradeItemType(protocol.ItemType{NetworkID: recipe.ReagentItemID}) + recipe.ReagentItemID = itemType.NetworkID + itemType = t.DowngradeItemType(protocol.ItemType{NetworkID: recipe.OutputItemID}) + recipe.OutputItemID = itemType.NetworkID + pk.PotionContainerChangeRecipes[i] = recipe + } + for i, recipe := range pk.MaterialReducers { + recipe.InputItem = t.DowngradeItemType(recipe.InputItem) + for i2, output := range recipe.Outputs { + itemType := t.DowngradeItemType(protocol.ItemType{NetworkID: output.NetworkID}) + output.NetworkID = itemType.NetworkID + recipe.Outputs[i2] = output + } + pk.MaterialReducers[i] = recipe + } + //case *packet.CraftingEvent: + // pk.Input = lo.Map(pk.Input, func(item protocol.ItemInstance, _ int) protocol.ItemInstance { + // return t.DowngradeItemInstance(item) + // }) + // pk.Output = lo.Map(pk.Output, func(item protocol.ItemInstance, _ int) protocol.ItemInstance { + // return t.DowngradeItemInstance(item) + // }) + case *packet.PlayerAuthInput: + for i, action := range pk.ItemStackRequest.Actions { + if act, ok := action.(*protocol.CraftResultsDeprecatedStackRequestAction); ok { + act.ResultItems = lo.Map(act.ResultItems, func(item protocol.ItemStack, _ int) protocol.ItemStack { + return t.DowngradeItemStack(item) + }) + pk.ItemStackRequest.Actions[i] = act + } + } + for i, action := range pk.ItemInteractionData.Actions { + action.OldItem = t.DowngradeItemInstance(action.OldItem) + action.NewItem = t.DowngradeItemInstance(action.NewItem) + pk.ItemInteractionData.Actions[i] = action + } + pk.ItemInteractionData.HeldItem = t.DowngradeItemInstance(pk.ItemInteractionData.HeldItem) + case *packet.CreativeContent: + for i, creativeItem := range pk.Items { + creativeItem.Item = t.DowngradeItemStack(creativeItem.Item) + + pk.Items[i] = creativeItem + } + case *packet.InventoryTransaction: + for i, action := range pk.Actions { + action.OldItem = t.DowngradeItemInstance(action.OldItem) + action.NewItem = t.DowngradeItemInstance(action.NewItem) + pk.Actions[i] = action + } + switch transactionData := pk.TransactionData.(type) { + case *protocol.UseItemTransactionData: + transactionData.HeldItem = t.DowngradeItemInstance(transactionData.HeldItem) + for i, action := range transactionData.Actions { + action.OldItem = t.DowngradeItemInstance(action.OldItem) + action.NewItem = t.DowngradeItemInstance(action.NewItem) + transactionData.Actions[i] = action + } + case *protocol.UseItemOnEntityTransactionData: + transactionData.HeldItem = t.DowngradeItemInstance(transactionData.HeldItem) + case *protocol.ReleaseItemTransactionData: + transactionData.HeldItem = t.DowngradeItemInstance(transactionData.HeldItem) + } + case *packet.LevelEvent: + if pk.EventType == packet.LevelEventParticleLegacyEvent|14 { // egg crack + itemType := t.DowngradeItemType(protocol.ItemType{ + NetworkID: pk.EventData >> 16, + MetadataValue: uint32(pk.EventData & 0xf), + }) + pk.EventData = (itemType.NetworkID << 16) | int32(itemType.MetadataValue) + } + case *packet.StartGame: + for i, entry := range pk.Items { + if !entry.ComponentBased { + itemType := t.DowngradeItemType(protocol.ItemType{ + NetworkID: int32(entry.RuntimeID), + MetadataValue: 0, + }) + if itemType.NetworkID == t.mapping.Air() { + removeIndex(pk.Items, i) + continue + } + entry.RuntimeID = int16(itemType.NetworkID) + + var ok bool + if entry.Name, ok = t.mapping.ItemRuntimeIDToName(itemType.NetworkID); !ok { + panic(itemType) + } + } else { + t.latest.RegisterEntry(entry.Name) + entry.RuntimeID = int16(t.mapping.RegisterEntry(entry.Name)) + } + pk.Items[i] = entry + } + for rid, i := range t.CustomItems() { + name, _ := i.EncodeItem() + pk.Items = append(pk.Items, protocol.ItemEntry{ + Name: name, + RuntimeID: int16(rid), + ComponentBased: true, + }) + } + case *packet.ItemComponent: + for _, i := range t.CustomItems() { + name, _ := i.EncodeItem() + pk.Items = append(pk.Items, protocol.ItemComponentEntry{ + Name: name, + Data: packbuilder.Components(i), + }) + } + } + result = append(result, pk) + } + return result +} + +func (t *DefaultItemTranslator) UpgradeItemPackets(pks []packet.Packet, _ *minecraft.Conn) (result []packet.Packet) { + for _, pk := range pks { + switch pk := pk.(type) { + case *packet.MobEquipment: + pk.NewItem = t.UpgradeItemInstance(pk.NewItem) + case *packet.MobArmourEquipment: + pk.Helmet = t.UpgradeItemInstance(pk.Helmet) + pk.Chestplate = t.UpgradeItemInstance(pk.Chestplate) + pk.Leggings = t.UpgradeItemInstance(pk.Leggings) + pk.Boots = t.UpgradeItemInstance(pk.Boots) + pk.Body = t.UpgradeItemInstance(pk.Body) + case *packet.AddItemActor: + pk.Item = t.UpgradeItemInstance(pk.Item) + case *packet.AddPlayer: + pk.HeldItem = t.UpgradeItemInstance(pk.HeldItem) + case *packet.InventorySlot: + pk.NewItem = t.UpgradeItemInstance(pk.NewItem) + case *packet.InventoryContent: + pk.Content = lo.Map(pk.Content, func(item protocol.ItemInstance, _ int) protocol.ItemInstance { + return t.UpgradeItemInstance(item) + }) + case *packet.ItemStackRequest: + for i, request := range pk.Requests { + for i2, action := range request.Actions { + if act, ok := action.(*protocol.CraftResultsDeprecatedStackRequestAction); ok { + act.ResultItems = lo.Map(act.ResultItems, func(item protocol.ItemStack, _ int) protocol.ItemStack { + return t.UpgradeItemStack(item) + }) + pk.Requests[i].Actions[i2] = act + } + } + } + case *packet.CraftingData: + for i, recipe := range pk.Recipes { + switch recipe := recipe.(type) { + case *protocol.ShapelessRecipe: + for i2, input := range recipe.Input { + recipe.Input[i2] = t.UpgradeItemDescriptorCount(input) + } + for i2, stack := range recipe.Output { + recipe.Output[i2] = t.UpgradeItemStack(stack) + } + pk.Recipes[i] = recipe + case *protocol.ShapedRecipe: + for i2, input := range recipe.Input { + recipe.Input[i2] = t.UpgradeItemDescriptorCount(input) + } + for i2, stack := range recipe.Output { + recipe.Output[i2] = t.UpgradeItemStack(stack) + } + pk.Recipes[i] = recipe + case *protocol.FurnaceRecipe: + recipe.InputType = t.UpgradeItemType(recipe.InputType) + recipe.Output = t.UpgradeItemStack(recipe.Output) + pk.Recipes[i] = recipe + case *protocol.FurnaceDataRecipe: + recipe.InputType = t.UpgradeItemType(recipe.InputType) + recipe.Output = t.UpgradeItemStack(recipe.Output) + pk.Recipes[i] = recipe + case *protocol.ShulkerBoxRecipe: + for i2, input := range recipe.Input { + recipe.Input[i2] = t.UpgradeItemDescriptorCount(input) + } + for i2, stack := range recipe.Output { + recipe.Output[i2] = t.UpgradeItemStack(stack) + } + pk.Recipes[i] = recipe + case *protocol.ShapelessChemistryRecipe: + for i2, input := range recipe.Input { + recipe.Input[i2] = t.UpgradeItemDescriptorCount(input) + } + for i2, stack := range recipe.Output { + recipe.Output[i2] = t.UpgradeItemStack(stack) + } + pk.Recipes[i] = recipe + case *protocol.ShapedChemistryRecipe: + for i2, input := range recipe.Input { + recipe.Input[i2] = t.UpgradeItemDescriptorCount(input) + } + for i2, stack := range recipe.Output { + recipe.Output[i2] = t.UpgradeItemStack(stack) + } + pk.Recipes[i] = recipe + case *protocol.SmithingTransformRecipe: + recipe.Template = t.UpgradeItemDescriptorCount(recipe.Template) + recipe.Base = t.UpgradeItemDescriptorCount(recipe.Base) + recipe.Addition = t.UpgradeItemDescriptorCount(recipe.Addition) + recipe.Result = t.UpgradeItemStack(recipe.Result) + pk.Recipes[i] = recipe + case *protocol.SmithingTrimRecipe: + recipe.Template = t.UpgradeItemDescriptorCount(recipe.Template) + recipe.Base = t.UpgradeItemDescriptorCount(recipe.Base) + recipe.Addition = t.UpgradeItemDescriptorCount(recipe.Addition) + } + } + for i, recipe := range pk.PotionRecipes { + itemType := t.UpgradeItemType(protocol.ItemType{NetworkID: recipe.InputPotionID, MetadataValue: uint32(recipe.InputPotionMetadata)}) + recipe.InputPotionID, recipe.InputPotionMetadata = itemType.NetworkID, int32(itemType.MetadataValue) + itemType = t.UpgradeItemType(protocol.ItemType{NetworkID: recipe.ReagentItemID, MetadataValue: uint32(recipe.ReagentItemMetadata)}) + recipe.ReagentItemID, recipe.ReagentItemMetadata = itemType.NetworkID, int32(itemType.MetadataValue) + itemType = t.UpgradeItemType(protocol.ItemType{NetworkID: recipe.OutputPotionID, MetadataValue: uint32(recipe.OutputPotionMetadata)}) + recipe.OutputPotionID, recipe.OutputPotionMetadata = itemType.NetworkID, int32(itemType.MetadataValue) + pk.PotionRecipes[i] = recipe + } + for i, recipe := range pk.PotionContainerChangeRecipes { + itemType := t.UpgradeItemType(protocol.ItemType{NetworkID: recipe.InputItemID}) + recipe.InputItemID = itemType.NetworkID + itemType = t.UpgradeItemType(protocol.ItemType{NetworkID: recipe.ReagentItemID}) + recipe.ReagentItemID = itemType.NetworkID + itemType = t.UpgradeItemType(protocol.ItemType{NetworkID: recipe.OutputItemID}) + recipe.OutputItemID = itemType.NetworkID + pk.PotionContainerChangeRecipes[i] = recipe + } + for i, recipe := range pk.MaterialReducers { + recipe.InputItem = t.UpgradeItemType(recipe.InputItem) + for i2, output := range recipe.Outputs { + itemType := t.UpgradeItemType(protocol.ItemType{NetworkID: output.NetworkID}) + output.NetworkID = itemType.NetworkID + recipe.Outputs[i2] = output + } + pk.MaterialReducers[i] = recipe + } + //case *packet.CraftingEvent: + // pk.Input = lo.Map(pk.Input, func(item protocol.ItemInstance, _ int) protocol.ItemInstance { + // return t.UpgradeItemInstance(item) + // }) + // pk.Output = lo.Map(pk.Output, func(item protocol.ItemInstance, _ int) protocol.ItemInstance { + // return t.UpgradeItemInstance(item) + // }) + case *packet.PlayerAuthInput: + for i, action := range pk.ItemStackRequest.Actions { + if act, ok := action.(*protocol.CraftResultsDeprecatedStackRequestAction); ok { + act.ResultItems = lo.Map(act.ResultItems, func(item protocol.ItemStack, _ int) protocol.ItemStack { + return t.UpgradeItemStack(item) + }) + pk.ItemStackRequest.Actions[i] = act + } + } + for i, action := range pk.ItemInteractionData.Actions { + action.OldItem = t.UpgradeItemInstance(action.OldItem) + action.NewItem = t.UpgradeItemInstance(action.NewItem) + pk.ItemInteractionData.Actions[i] = action + } + pk.ItemInteractionData.HeldItem = t.UpgradeItemInstance(pk.ItemInteractionData.HeldItem) + case *packet.CreativeContent: + for i, creativeItem := range pk.Items { + creativeItem.Item = t.UpgradeItemStack(creativeItem.Item) + pk.Items[i] = creativeItem + } + case *packet.InventoryTransaction: + for i, action := range pk.Actions { + action.OldItem = t.UpgradeItemInstance(action.OldItem) + action.NewItem = t.UpgradeItemInstance(action.NewItem) + pk.Actions[i] = action + } + switch transactionData := pk.TransactionData.(type) { + case *protocol.UseItemTransactionData: + transactionData.HeldItem = t.UpgradeItemInstance(transactionData.HeldItem) + for i, action := range transactionData.Actions { + action.OldItem = t.UpgradeItemInstance(action.OldItem) + action.NewItem = t.UpgradeItemInstance(action.NewItem) + transactionData.Actions[i] = action + } + case *protocol.UseItemOnEntityTransactionData: + transactionData.HeldItem = t.UpgradeItemInstance(transactionData.HeldItem) + case *protocol.ReleaseItemTransactionData: + transactionData.HeldItem = t.UpgradeItemInstance(transactionData.HeldItem) + } + case *packet.LevelEvent: + if pk.EventType == packet.LevelEventParticleLegacyEvent|14 { // egg crack + itemType := t.UpgradeItemType(protocol.ItemType{ + NetworkID: pk.EventData >> 16, + MetadataValue: uint32(pk.EventData & 0xf), + }) + pk.EventData = (itemType.NetworkID << 16) | int32(itemType.MetadataValue) + } + case *packet.StartGame: + for i, entry := range pk.Items { + if !entry.ComponentBased { + itemType := t.UpgradeItemType(protocol.ItemType{ + NetworkID: int32(entry.RuntimeID), + MetadataValue: 0, + }) + entry.RuntimeID = int16(itemType.NetworkID) + + var ok bool + if entry.Name, ok = t.latest.ItemRuntimeIDToName(itemType.NetworkID); !ok { + panic(itemType) + } + } else { + t.latest.RegisterEntry(entry.Name) + entry.RuntimeID = int16(t.mapping.RegisterEntry(entry.Name)) + } + pk.Items[i] = entry + } + for rid, i := range t.CustomItems() { + name, _ := i.EncodeItem() + pk.Items = append(pk.Items, protocol.ItemEntry{ + Name: name, + RuntimeID: int16(rid), + ComponentBased: true, + }) + } + case *packet.ItemComponent: + for _, i := range t.CustomItems() { + name, _ := i.EncodeItem() + pk.Items = append(pk.Items, protocol.ItemComponentEntry{ + Name: name, + Data: packbuilder.Components(i), + }) + } + } + result = append(result, pk) + } + return result +} + +func (t *DefaultItemTranslator) Register(item world.CustomItem, replacement string) { + name, _ := item.EncodeItem() + originalRid, ok := t.latest.ItemNameToRuntimeID(replacement) + if !ok { + panic(fmt.Errorf("%v not found in latest items", replacement)) + } + if _, ok := t.originalToCustom[originalRid]; ok { + panic(fmt.Errorf("%v is already mapped", replacement)) + } + + nextRID := t.mapping.RegisterEntry(name) + t.ridToCustomItem[nextRID] = item + t.originalToCustom[originalRid] = nextRID + t.customToOriginal[nextRID] = originalRid +} + +func (t *DefaultItemTranslator) CustomItems() map[int32]world.CustomItem { + return t.ridToCustomItem +} + +func removeIndex[T any](s []T, index int) []T { + ret := make([]T, 0) + ret = append(ret, s[:index]...) + return append(ret, s[index+1:]...) +} diff --git a/legacyver/legacypacket/item_stack_response.go b/legacyver/legacypacket/item_stack_response.go new file mode 100644 index 0000000..254798b --- /dev/null +++ b/legacyver/legacypacket/item_stack_response.go @@ -0,0 +1,27 @@ +package legacypacket + +import ( + "github.com/akmalfairuz/legacy-version/legacyver/proto" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "github.com/sandertv/gophertunnel/minecraft/protocol/packet" +) + +// ItemStackResponse is sent by the server in response to an ItemStackRequest packet from the client. This +// packet is used to either approve or reject ItemStackRequests from the client. If a request is approved, the +// client will simply continue as normal. If rejected, the client will undo the actions so that the inventory +// should be in sync with the server again. +type ItemStackResponse struct { + // Responses is a list of responses to ItemStackRequests sent by the client before. Responses either + // approve or reject a request from the client. + // Vanilla limits the size of this slice to 4096. + Responses []proto.ItemStackResponse +} + +// ID ... +func (*ItemStackResponse) ID() uint32 { + return packet.IDItemStackResponse +} + +func (pk *ItemStackResponse) Marshal(io protocol.IO) { + protocol.Slice(io, &pk.Responses) +} diff --git a/legacyver/legacypacket/packet.go b/legacyver/legacypacket/packet.go new file mode 100644 index 0000000..612a433 --- /dev/null +++ b/legacyver/legacypacket/packet.go @@ -0,0 +1 @@ +package legacypacket diff --git a/legacyver/legacypacket/player_auth_input.go b/legacyver/legacypacket/player_auth_input.go new file mode 100644 index 0000000..75ac970 --- /dev/null +++ b/legacyver/legacypacket/player_auth_input.go @@ -0,0 +1,210 @@ +package legacypacket + +import ( + "github.com/akmalfairuz/legacy-version/legacyver/proto" + "github.com/go-gl/mathgl/mgl32" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "github.com/sandertv/gophertunnel/minecraft/protocol/packet" +) + +const PlayerAuthInputBitsetSize = 65 + +const ( + InputFlagAscend = iota + InputFlagDescend + InputFlagNorthJump + InputFlagJumpDown + InputFlagSprintDown + InputFlagChangeHeight + InputFlagJumping + InputFlagAutoJumpingInWater + InputFlagSneaking + InputFlagSneakDown + InputFlagUp + InputFlagDown + InputFlagLeft + InputFlagRight + InputFlagUpLeft + InputFlagUpRight + InputFlagWantUp + InputFlagWantDown + InputFlagWantDownSlow + InputFlagWantUpSlow + InputFlagSprinting + InputFlagAscendBlock + InputFlagDescendBlock + InputFlagSneakToggleDown + InputFlagPersistSneak + InputFlagStartSprinting + InputFlagStopSprinting + InputFlagStartSneaking + InputFlagStopSneaking + InputFlagStartSwimming + InputFlagStopSwimming + InputFlagStartJumping + InputFlagStartGliding + InputFlagStopGliding + InputFlagPerformItemInteraction + InputFlagPerformBlockActions + InputFlagPerformItemStackRequest + InputFlagHandledTeleport + InputFlagEmoting + InputFlagMissedSwing + InputFlagStartCrawling + InputFlagStopCrawling + InputFlagStartFlying + InputFlagStopFlying + InputFlagClientAckServerData + InputFlagClientPredictedVehicle + InputFlagPaddlingLeft + InputFlagPaddlingRight + InputFlagBlockBreakingDelayEnabled + InputFlagHorizontalCollision + InputFlagVerticalCollision + InputFlagDownLeft + InputFlagDownRight + InputFlagStartUsingItem + InputFlagCameraRelativeMovementEnabled + InputFlagRotControlledByMoveDirection + InputFlagStartSpinAttack + InputFlagStopSpinAttack + InputFlagIsHotbarTouchOnly + InputFlagJumpReleasedRaw + InputFlagJumpPressedRaw + InputFlagJumpCurrentRaw + InputFlagSneakReleasedRaw + InputFlagSneakPressedRaw + InputFlagSneakCurrentRaw +) + +const ( + InputModeMouse = iota + 1 + InputModeTouch + InputModeGamePad + InputModeMotionController +) + +const ( + PlayModeNormal = iota + PlayModeTeaser + PlayModeScreen + PlayModeViewer + PlayModeReality + PlayModePlacement + PlayModeLivingRoom + PlayModeExitLevel + PlayModeExitLevelLivingRoom + PlayModeNumModes +) + +const ( + InteractionModelTouch = iota + InteractionModelCrosshair + InteractionModelClassic +) + +// PlayerAuthInput is sent by the client to allow for server authoritative movement. It is used to synchronise +// the player input with the position server-side. +// The client sends this packet when the ServerAuthoritativeMovementMode field in the StartGame packet is set +// to true, instead of the MovePlayer packet. The client will send this packet once every tick. +type PlayerAuthInput struct { + // Pitch and Yaw hold the rotation that the player reports it has. + Pitch, Yaw float32 + // Position holds the position that the player reports it has. + Position mgl32.Vec3 + // MoveVector is a Vec2 that specifies the direction in which the player moved, as a combination of X/Z + // values which are created using the WASD/controller stick state. + MoveVector mgl32.Vec2 + // HeadYaw is the horizontal rotation of the head that the player reports it has. + HeadYaw float32 + // InputData is a combination of bit flags that together specify the way the player moved last tick. It + // is a combination of the flags above. + InputData protocol.Bitset + // InputMode specifies the way that the client inputs data to the screen. It is one of the constants that + // may be found above. + InputMode uint32 + // PlayMode specifies the way that the player is playing. The values it holds, which are rather random, + // may be found above. + PlayMode uint32 + // InteractionModel is a constant representing the interaction model the player is using. It is one of the + // constants that may be found above. + InteractionModel uint32 + // InteractPitch and interactYaw is the rotation the player is looking that they intend to use for + // interactions. This is only different to Pitch and Yaw in cases such as VR or when custom cameras + // being used. + InteractPitch, InteractYaw float32 + // Tick is the server tick at which the packet was sent. It is used in relation to + // CorrectPlayerMovePrediction. + Tick uint64 + // Delta was the delta between the old and the new position. There isn't any practical use for this field + // as it can be calculated by the server itself. + Delta mgl32.Vec3 + // ItemInteractionData is the transaction data if the InputData includes an item interaction. + ItemInteractionData protocol.UseItemTransactionData + // ItemStackRequest is sent by the client to change an item in their inventory. + ItemStackRequest protocol.ItemStackRequest + // BlockActions is a slice of block actions that the client has interacted with. + BlockActions []protocol.PlayerBlockAction + // VehicleRotation is the rotation of the vehicle that the player is in, if any. + VehicleRotation mgl32.Vec2 + // ClientPredictedVehicle is the unique ID of the vehicle that the client predicts the player to be in. + ClientPredictedVehicle int64 + // AnalogueMoveVector is a Vec2 that specifies the direction in which the player moved, as a combination + // of X/Z values which are created using an analogue input. + AnalogueMoveVector mgl32.Vec2 + // CameraOrientation is the vector that represents the camera's forward direction which can be used to + // transform movement to be camera relative. + CameraOrientation mgl32.Vec3 + // RawMoveVector is the value of MoveVector before it is affected by input permissions, sneaking/fly + // speeds and isn't normalised for analogue inputs. + RawMoveVector mgl32.Vec2 +} + +// ID ... +func (pk *PlayerAuthInput) ID() uint32 { + return packet.IDPlayerAuthInput +} + +func (pk *PlayerAuthInput) Marshal(io protocol.IO) { + io.Float32(&pk.Pitch) + io.Float32(&pk.Yaw) + io.Vec3(&pk.Position) + io.Vec2(&pk.MoveVector) + io.Float32(&pk.HeadYaw) + if proto.IsProtoGTE(io, proto.ID766) { + io.Bitset(&pk.InputData, PlayerAuthInputBitsetSize) + } else { + io.Bitset(&pk.InputData, 64) + } + io.Varuint32(&pk.InputMode) + io.Varuint32(&pk.PlayMode) + io.Varuint32(&pk.InteractionModel) + io.Float32(&pk.InteractPitch) + io.Float32(&pk.InteractYaw) + io.Varuint64(&pk.Tick) + io.Vec3(&pk.Delta) + + if pk.InputData.Load(InputFlagPerformItemInteraction) { + io.PlayerInventoryAction(&pk.ItemInteractionData) + } + + if pk.InputData.Load(InputFlagPerformItemStackRequest) { + protocol.Single(io, &pk.ItemStackRequest) + } + + if pk.InputData.Load(InputFlagPerformBlockActions) { + protocol.SliceVarint32Length(io, &pk.BlockActions) + } + + if pk.InputData.Load(InputFlagClientPredictedVehicle) { + io.Vec2(&pk.VehicleRotation) + io.Varint64(&pk.ClientPredictedVehicle) + } + + io.Vec2(&pk.AnalogueMoveVector) + io.Vec3(&pk.CameraOrientation) + + if proto.IsProtoGTE(io, proto.ID766) { + io.Vec2(&pk.RawMoveVector) + } +} diff --git a/legacyver/legacypacket/resource_packs_info.go b/legacyver/legacypacket/resource_packs_info.go new file mode 100644 index 0000000..d68aa4d --- /dev/null +++ b/legacyver/legacypacket/resource_packs_info.go @@ -0,0 +1,50 @@ +package legacypacket + +import ( + "github.com/akmalfairuz/legacy-version/legacyver/proto" + "github.com/google/uuid" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "github.com/sandertv/gophertunnel/minecraft/protocol/packet" +) + +// ResourcePacksInfo is sent by the server to inform the client on what resource packs the server has. It +// sends a list of the resource packs it has and basic information on them like the version and description. +type ResourcePacksInfo struct { + // TexturePackRequired specifies if the client must accept the texture packs the server has in order to + // join the server. If set to true, the client gets the option to either download the resource packs and + // join, or quit entirely. Behaviour packs never have to be downloaded. + TexturePackRequired bool + // HasAddons specifies if any of the resource packs contain addons in them. If set to true, only clients + // that support addons will be able to download them. + HasAddons bool + // HasScripts specifies if any of the resource packs contain scripts in them. If set to true, only clients + // that support scripts will be able to download them. + HasScripts bool + // WorldTemplateUUID is the UUID of the template that has been used to generate the world. Templates can + // be downloaded from the marketplace or installed via '.mctemplate' files. If the world was not generated + // from a template, this field is empty. + WorldTemplateUUID uuid.UUID + // WorldTemplateVersion is the version of the world template that has been used to generate the world. If + // the world was not generated from a template, this field is empty. + WorldTemplateVersion string + // TexturePacks is a list of texture packs that the client needs to download before joining the server. + // The order of these texture packs is not relevant in this packet. It is however important in the + // ResourcePackStack packet. + TexturePacks []proto.TexturePackInfo +} + +// ID ... +func (*ResourcePacksInfo) ID() uint32 { + return packet.IDResourcePacksInfo +} + +func (pk *ResourcePacksInfo) Marshal(io protocol.IO) { + io.Bool(&pk.TexturePackRequired) + io.Bool(&pk.HasAddons) + io.Bool(&pk.HasScripts) + if proto.IsProtoGTE(io, proto.ID766) { + io.UUID(&pk.WorldTemplateUUID) + io.String(&pk.WorldTemplateVersion) + } + protocol.SliceUint16Length(io, &pk.TexturePacks) +} diff --git a/legacyver/proto/id.go b/legacyver/proto/id.go new file mode 100644 index 0000000..ebdb140 --- /dev/null +++ b/legacyver/proto/id.go @@ -0,0 +1,32 @@ +package proto + +import "github.com/sandertv/gophertunnel/minecraft/protocol" + +const ( + ID766 = 766 + ID748 = 748 + ID729 = 729 + ID712 = 712 + ID686 = 686 + ID685 = 685 +) + +func IsProtoGTE(io protocol.IO, proto int32) bool { + return io.(IO).ProtocolID() >= proto +} + +func IsProtoLTE(io protocol.IO, proto int32) bool { + return io.(IO).ProtocolID() <= proto +} + +func IsProtoLT(io protocol.IO, proto int32) bool { + return io.(IO).ProtocolID() < proto +} + +func IsProtoGT(io protocol.IO, proto int32) bool { + return io.(IO).ProtocolID() > proto +} + +func FetchProtoID(io protocol.IO) int32 { + return io.(IO).ProtocolID() +} diff --git a/legacyver/proto/io.go b/legacyver/proto/io.go new file mode 100644 index 0000000..3304494 --- /dev/null +++ b/legacyver/proto/io.go @@ -0,0 +1,53 @@ +package proto + +import ( + "github.com/sandertv/gophertunnel/minecraft/protocol" +) + +type IO interface { + protocol.IO + + SetProtocolID(protocolID int32) + ProtocolID() int32 +} + +type Reader struct { + *protocol.Reader + + protocolID int32 +} + +func NewReader(r *protocol.Reader, protocolID int32) *Reader { + return &Reader{ + Reader: r, + protocolID: protocolID, + } +} + +func (r *Reader) SetProtocolID(protocolID int32) { r.protocolID = protocolID } +func (r *Reader) ProtocolID() int32 { return r.protocolID } +func (r *Reader) Reads() bool { return true } + +type Writer struct { + *protocol.Writer + + protocolID int32 +} + +func NewWriter(w *protocol.Writer, protocolID int32) *Writer { + return &Writer{w, protocolID} +} + +func (w *Writer) SetProtocolID(protocolID int32) { w.protocolID = protocolID } +func (w *Writer) ProtocolID() int32 { return w.protocolID } +func (w *Writer) Reads() bool { return false } + +func IsReader(r protocol.IO) bool { + _, ok := r.(*Reader) + return ok +} + +func IsWriter(w protocol.IO) bool { + _, ok := w.(*Writer) + return ok +} diff --git a/legacyver/proto/item_stack.go b/legacyver/proto/item_stack.go new file mode 100644 index 0000000..0f1b294 --- /dev/null +++ b/legacyver/proto/item_stack.go @@ -0,0 +1,652 @@ +package proto + +import ( + "github.com/sandertv/gophertunnel/minecraft/protocol" +) + +const ( + FilterCauseServerChatPublic = iota + FilterCauseServerChatWhisper + FilterCauseSignText + FilterCauseAnvilText + FilterCauseBookAndQuillText + FilterCauseCommandBlockText + FilterCauseBlockActorDataText + FilterCauseJoinEventText + FilterCauseLeaveEventText + FilterCauseSlashCommandChat + FilterCauseCartographyText + FilterCauseKickCommand + FilterCauseTitleCommand + FilterCauseSummonCommand +) + +// ItemStackRequest represents a single request present in an ItemStackRequest packet sent by the client to +// change an item in an inventory. +// Item stack requests are either approved or rejected by the server using the ItemStackResponse packet. +type ItemStackRequest struct { + // RequestID is a unique ID for the request. This ID is used by the server to send a response for this + // specific request in the ItemStackResponse packet. + RequestID int32 + // Actions is a list of actions performed by the client. The actual type of the actions depends on which + // ID was present, and is one of the concrete types below. + Actions []protocol.StackRequestAction + // FilterStrings is a list of filter strings involved in the request. This is typically filled with one string + // when an anvil or cartography is used. + FilterStrings []string + // FilterCause represents the cause of any potential filtering. This is one of the constants above. + FilterCause int32 +} + +// Marshal encodes/decodes an ItemStackRequest. +func (x *ItemStackRequest) Marshal(r protocol.IO) { + r.Varint32(&x.RequestID) + protocol.FuncSlice(r, &x.Actions, r.StackRequestAction) + protocol.FuncSlice(r, &x.FilterStrings, r.String) + r.Int32(&x.FilterCause) +} + +// lookupStackRequestActionType looks up the ID of a StackRequestAction. +func lookupStackRequestActionType(x StackRequestAction, id *uint8) bool { + switch x.(type) { + case *TakeStackRequestAction: + *id = StackRequestActionTake + case *PlaceStackRequestAction: + *id = StackRequestActionPlace + case *SwapStackRequestAction: + *id = StackRequestActionSwap + case *DropStackRequestAction: + *id = StackRequestActionDrop + case *DestroyStackRequestAction: + *id = StackRequestActionDestroy + case *ConsumeStackRequestAction: + *id = StackRequestActionConsume + case *CreateStackRequestAction: + *id = StackRequestActionCreate + case *LabTableCombineStackRequestAction: + *id = StackRequestActionLabTableCombine + case *BeaconPaymentStackRequestAction: + *id = StackRequestActionBeaconPayment + case *MineBlockStackRequestAction: + *id = StackRequestActionMineBlock + case *CraftRecipeStackRequestAction: + *id = StackRequestActionCraftRecipe + case *AutoCraftRecipeStackRequestAction: + *id = StackRequestActionCraftRecipeAuto + case *CraftCreativeStackRequestAction: + *id = StackRequestActionCraftCreative + case *CraftRecipeOptionalStackRequestAction: + *id = StackRequestActionCraftRecipeOptional + case *CraftGrindstoneRecipeStackRequestAction: + *id = StackRequestActionCraftGrindstone + case *CraftLoomRecipeStackRequestAction: + *id = StackRequestActionCraftLoom + case *CraftNonImplementedStackRequestAction: + *id = StackRequestActionCraftNonImplementedDeprecated + case *CraftResultsDeprecatedStackRequestAction: + *id = StackRequestActionCraftResultsDeprecated + default: + return false + } + return true +} + +// lookupStackRequestAction looks up the StackRequestAction matching an ID. +func lookupStackRequestAction(id uint8, x *StackRequestAction) bool { + switch id { + case StackRequestActionTake: + *x = &TakeStackRequestAction{} + case StackRequestActionPlace: + *x = &PlaceStackRequestAction{} + case StackRequestActionSwap: + *x = &SwapStackRequestAction{} + case StackRequestActionDrop: + *x = &DropStackRequestAction{} + case StackRequestActionDestroy: + *x = &DestroyStackRequestAction{} + case StackRequestActionConsume: + *x = &ConsumeStackRequestAction{} + case StackRequestActionCreate: + *x = &CreateStackRequestAction{} + case StackRequestActionPlaceInContainer: + *x = &PlaceInContainerStackRequestAction{} + case StackRequestActionTakeOutContainer: + *x = &TakeOutContainerStackRequestAction{} + case StackRequestActionLabTableCombine: + *x = &LabTableCombineStackRequestAction{} + case StackRequestActionBeaconPayment: + *x = &BeaconPaymentStackRequestAction{} + case StackRequestActionMineBlock: + *x = &MineBlockStackRequestAction{} + case StackRequestActionCraftRecipe: + *x = &CraftRecipeStackRequestAction{} + case StackRequestActionCraftRecipeAuto: + *x = &AutoCraftRecipeStackRequestAction{} + case StackRequestActionCraftCreative: + *x = &CraftCreativeStackRequestAction{} + case StackRequestActionCraftRecipeOptional: + *x = &CraftRecipeOptionalStackRequestAction{} + case StackRequestActionCraftGrindstone: + *x = &CraftGrindstoneRecipeStackRequestAction{} + case StackRequestActionCraftLoom: + *x = &CraftLoomRecipeStackRequestAction{} + case StackRequestActionCraftNonImplementedDeprecated: + *x = &CraftNonImplementedStackRequestAction{} + case StackRequestActionCraftResultsDeprecated: + *x = &CraftResultsDeprecatedStackRequestAction{} + default: + return false + } + return true +} + +const ( + ItemStackResponseStatusOK = iota + ItemStackResponseStatusError + ItemStackResponseStatusInvalidRequestActionType + ItemStackResponseStatusActionRequestNotAllowed + ItemStackResponseStatusScreenHandlerEndRequestFailed + ItemStackResponseStatusItemRequestActionHandlerCommitFailed + ItemStackResponseStatusInvalidRequestCraftActionType + ItemStackResponseStatusInvalidCraftRequest + ItemStackResponseStatusInvalidCraftRequestScreen + ItemStackResponseStatusInvalidCraftResult + ItemStackResponseStatusInvalidCraftResultIndex + ItemStackResponseStatusInvalidCraftResultItem + ItemStackResponseStatusInvalidItemNetId + ItemStackResponseStatusMissingCreatedOutputContainer + ItemStackResponseStatusFailedToSetCreatedItemOutputSlot + ItemStackResponseStatusRequestAlreadyInProgress + ItemStackResponseStatusFailedToInitSparseContainer + ItemStackResponseStatusResultTransferFailed + ItemStackResponseStatusExpectedItemSlotNotFullyConsumed + ItemStackResponseStatusExpectedAnywhereItemNotFullyConsumed + ItemStackResponseStatusItemAlreadyConsumedFromSlot + ItemStackResponseStatusConsumedTooMuchFromSlot + ItemStackResponseStatusMismatchSlotExpectedConsumedItem + ItemStackResponseStatusMismatchSlotExpectedConsumedItemNetIdVariant + ItemStackResponseStatusFailedToMatchExpectedSlotConsumedItem + ItemStackResponseStatusFailedToMatchExpectedAllowedAnywhereConsumedItem + ItemStackResponseStatusConsumedItemOutOfAllowedSlotRange + ItemStackResponseStatusConsumedItemNotAllowed + ItemStackResponseStatusPlayerNotInCreativeMode + ItemStackResponseStatusInvalidExperimentalRecipeRequest + ItemStackResponseStatusFailedToCraftCreative + ItemStackResponseStatusFailedToGetLevelRecipe + ItemStackResponseStatusFailedToFindRecipeByNetId + ItemStackResponseStatusMismatchedCraftingSize + ItemStackResponseStatusMissingInputSparseContainer + ItemStackResponseStatusMismatchedRecipeForInputGridItems + ItemStackResponseStatusEmptyCraftResults + ItemStackResponseStatusFailedToEnchant + ItemStackResponseStatusMissingInputItem + ItemStackResponseStatusInsufficientPlayerLevelToEnchant + ItemStackResponseStatusMissingMaterialItem + ItemStackResponseStatusMissingActor + ItemStackResponseStatusUnknownPrimaryEffect + ItemStackResponseStatusPrimaryEffectOutOfRange + ItemStackResponseStatusPrimaryEffectUnavailable + ItemStackResponseStatusSecondaryEffectOutOfRange + ItemStackResponseStatusSecondaryEffectUnavailable + ItemStackResponseStatusDstContainerEqualToCreatedOutputContainer + ItemStackResponseStatusDstContainerAndSlotEqualToSrcContainerAndSlot + ItemStackResponseStatusFailedToValidateSrcSlot + ItemStackResponseStatusFailedToValidateDstSlot + ItemStackResponseStatusInvalidAdjustedAmount + ItemStackResponseStatusInvalidItemSetType + ItemStackResponseStatusInvalidTransferAmount + ItemStackResponseStatusCannotSwapItem + ItemStackResponseStatusCannotPlaceItem + ItemStackResponseStatusUnhandledItemSetType + ItemStackResponseStatusInvalidRemovedAmount + ItemStackResponseStatusInvalidRegion + ItemStackResponseStatusCannotDropItem + ItemStackResponseStatusCannotDestroyItem + ItemStackResponseStatusInvalidSourceContainer + ItemStackResponseStatusItemNotConsumed + ItemStackResponseStatusInvalidNumCrafts + ItemStackResponseStatusInvalidCraftResultStackSize + ItemStackResponseStatusCannotRemoveItem + ItemStackResponseStatusCannotConsumeItem + ItemStackResponseStatusScreenStackError +) + +// ItemStackResponse is a response to an individual ItemStackRequest. +type ItemStackResponse struct { + // Status specifies if the request with the RequestID below was successful. If this is the case, the + // ContainerInfo below will have information on what slots ended up changing. If not, the container info + // will be empty. + // A non-0 status means an error occurred and will result in the action being reverted. + Status uint8 + // RequestID is the unique ID of the request that this response is in reaction to. If rejected, the client + // will undo the actions from the request with this ID. + RequestID int32 + // ContainerInfo holds information on the containers that had their contents changed as a result of the + // request. + ContainerInfo []StackResponseContainerInfo +} + +func (x *ItemStackResponse) ToLatest() protocol.ItemStackResponse { + ret := protocol.ItemStackResponse{ + Status: x.Status, + RequestID: x.RequestID, + ContainerInfo: make([]protocol.StackResponseContainerInfo, len(x.ContainerInfo)), + } + for i, v := range x.ContainerInfo { + ret.ContainerInfo[i] = protocol.StackResponseContainerInfo{ + Container: v.Container, + SlotInfo: make([]protocol.StackResponseSlotInfo, len(v.SlotInfo)), + } + for j, w := range v.SlotInfo { + ret.ContainerInfo[i].SlotInfo[j] = protocol.StackResponseSlotInfo{ + Slot: w.Slot, + HotbarSlot: w.HotbarSlot, + Count: w.Count, + StackNetworkID: w.StackNetworkID, + CustomName: w.CustomName, + FilteredCustomName: w.FilteredCustomName, + DurabilityCorrection: w.DurabilityCorrection, + } + } + } + return ret +} + +// Marshal encodes/decodes an ItemStackResponse. +func (x *ItemStackResponse) Marshal(r protocol.IO) { + r.Uint8(&x.Status) + r.Varint32(&x.RequestID) + if x.Status == ItemStackResponseStatusOK { + protocol.Slice(r, &x.ContainerInfo) + } +} + +// StackResponseContainerInfo holds information on what slots in a container have what item stack in them. +type StackResponseContainerInfo struct { + // Container is the FullContainerName that describes the container that the slots that follow are in. For + // the main inventory, the ContainerID seems to be 0x1b. Fur the cursor, this value seems to be 0x3a. For + // the crafting grid, this value seems to be 0x0d. + Container protocol.FullContainerName + // SlotInfo holds information on what item stack should be present in specific slots in the container. + SlotInfo []StackResponseSlotInfo +} + +// Marshal encodes/decodes a StackResponseContainerInfo. +func (x *StackResponseContainerInfo) Marshal(r protocol.IO) { + protocol.Single(r, &x.Container) + protocol.Slice(r, &x.SlotInfo) +} + +// StackResponseSlotInfo holds information on what item stack should be present in a specific slot. +type StackResponseSlotInfo struct { + // Slot and HotbarSlot seem to be the same value every time: The slot that was actually changed. I'm not + // sure if these slots ever differ. + Slot, HotbarSlot byte + // Count is the total count of the item stack. This count will be shown client-side after the response is + // sent to the client. + Count byte + // StackNetworkID is the network ID of the new stack at a specific slot. + StackNetworkID int32 + // CustomName is the custom name of the item stack. It is used in relation to text filtering. + CustomName string + // FilteredCustomName is a filtered version of CustomName with all the profanity removed. The client will + // use this over CustomName if this field is not empty and they have the "Filter Profanity" setting enabled. + FilteredCustomName string + // DurabilityCorrection is the current durability of the item stack. This durability will be shown + // client-side after the response is sent to the client. + DurabilityCorrection int32 +} + +// Marshal encodes/decodes a StackResponseSlotInfo. +func (x *StackResponseSlotInfo) Marshal(r protocol.IO) { + r.Uint8(&x.Slot) + r.Uint8(&x.HotbarSlot) + r.Uint8(&x.Count) + r.Varint32(&x.StackNetworkID) + if x.Slot != x.HotbarSlot { + r.InvalidValue(x.HotbarSlot, "hotbar slot", "hot bar slot must be equal to normal slot") + } + r.String(&x.CustomName) + if IsProtoGTE(r, ID766) { + r.String(&x.FilteredCustomName) + } + r.Varint32(&x.DurabilityCorrection) +} + +// StackRequestAction represents a single action related to the inventory present in an ItemStackRequest. +// The action is one of the concrete types below, each of which are indicative of a different action by the +// client, such as moving an item around the inventory or placing a block. It is an alias of Marshaler. +type StackRequestAction interface { + protocol.Marshaler +} + +const ( + StackRequestActionTake = iota + StackRequestActionPlace + StackRequestActionSwap + StackRequestActionDrop + StackRequestActionDestroy + StackRequestActionConsume + StackRequestActionCreate + StackRequestActionPlaceInContainer + StackRequestActionTakeOutContainer + StackRequestActionLabTableCombine + StackRequestActionBeaconPayment + StackRequestActionMineBlock + StackRequestActionCraftRecipe + StackRequestActionCraftRecipeAuto + StackRequestActionCraftCreative + StackRequestActionCraftRecipeOptional + StackRequestActionCraftGrindstone + StackRequestActionCraftLoom + StackRequestActionCraftNonImplementedDeprecated + StackRequestActionCraftResultsDeprecated +) + +// transferStackRequestAction is the structure shared by StackRequestActions that transfer items from one +// slot into another. +type transferStackRequestAction struct { + // Count is the count of the item in the source slot that was taken towards the destination slot. + Count byte + // Source and Destination point to the source slot from which Count of the item stack were taken and the + // destination slot to which this item was moved. + Source, Destination StackRequestSlotInfo +} + +// Marshal ... +func (a *transferStackRequestAction) Marshal(r protocol.IO) { + r.Uint8(&a.Count) + StackReqSlotInfo(r, &a.Source) + StackReqSlotInfo(r, &a.Destination) +} + +// TakeStackRequestAction is sent by the client to the server to take x amount of items from one slot in a +// container to the cursor. +type TakeStackRequestAction struct { + transferStackRequestAction +} + +// PlaceStackRequestAction is sent by the client to the server to place x amount of items from one slot into +// another slot, such as when shift clicking an item in the inventory to move it around or when moving an item +// in the cursor into a slot. +type PlaceStackRequestAction struct { + transferStackRequestAction +} + +// SwapStackRequestAction is sent by the client to swap the item in its cursor with an item present in another +// container. The two item stacks swap places. +type SwapStackRequestAction struct { + // Source and Destination point to the source slot from which Count of the item stack were taken and the + // destination slot to which this item was moved. + Source, Destination StackRequestSlotInfo +} + +// Marshal ... +func (a *SwapStackRequestAction) Marshal(r protocol.IO) { + StackReqSlotInfo(r, &a.Source) + StackReqSlotInfo(r, &a.Destination) +} + +// DropStackRequestAction is sent by the client when it drops an item out of the inventory when it has its +// inventory opened. This action is not sent when a player drops an item out of the hotbar using the Q button +// (or the equivalent on mobile). The InventoryTransaction packet is still used for that action, regardless of +// whether the item stack network IDs are used or not. +type DropStackRequestAction struct { + // Count is the count of the item in the source slot that was taken towards the destination slot. + Count byte + // Source is the source slot from which items were dropped to the ground. + Source StackRequestSlotInfo + // Randomly seems to be set to false in most cases. I'm not entirely sure what this does, but this is what + // vanilla calls this field. + Randomly bool +} + +// Marshal ... +func (a *DropStackRequestAction) Marshal(r protocol.IO) { + r.Uint8(&a.Count) + StackReqSlotInfo(r, &a.Source) + r.Bool(&a.Randomly) +} + +// DestroyStackRequestAction is sent by the client when it destroys an item in creative mode by moving it +// back into the creative inventory. +type DestroyStackRequestAction struct { + // Count is the count of the item in the source slot that was destroyed. + Count byte + // Source is the source slot from which items came that were destroyed by moving them into the creative + // inventory. + Source StackRequestSlotInfo +} + +// Marshal ... +func (a *DestroyStackRequestAction) Marshal(r protocol.IO) { + r.Uint8(&a.Count) + StackReqSlotInfo(r, &a.Source) +} + +// ConsumeStackRequestAction is sent by the client when it uses an item to craft another item. The original +// item is 'consumed'. +type ConsumeStackRequestAction struct { + DestroyStackRequestAction +} + +// CreateStackRequestAction is sent by the client when an item is created through being used as part of a +// recipe. For example, when milk is used to craft a cake, the buckets are leftover. The buckets are moved to +// the slot sent by the client here. +// Note that before this is sent, an action for consuming all items in the crafting table/grid is sent. Items +// that are not fully consumed when used for a recipe should not be destroyed there, but instead, should be +// turned into their respective resulting items. +type CreateStackRequestAction struct { + // ResultsSlot is the slot in the inventory in which the results of the crafting ingredients are to be + // placed. + ResultsSlot byte +} + +// Marshal ... +func (a *CreateStackRequestAction) Marshal(r protocol.IO) { + r.Uint8(&a.ResultsSlot) +} + +// PlaceInContainerStackRequestAction currently has no known purpose. +type PlaceInContainerStackRequestAction struct { + transferStackRequestAction +} + +// TakeOutContainerStackRequestAction currently has no known purpose. +type TakeOutContainerStackRequestAction struct { + transferStackRequestAction +} + +// LabTableCombineStackRequestAction is sent by the client when it uses a lab table to combine item stacks. +type LabTableCombineStackRequestAction struct{} + +// Marshal ... +func (a *LabTableCombineStackRequestAction) Marshal(protocol.IO) {} + +// BeaconPaymentStackRequestAction is sent by the client when it submits an item to enable effects from a +// beacon. These items will have been moved into the beacon item slot in advance. +type BeaconPaymentStackRequestAction struct { + // PrimaryEffect and SecondaryEffect are the effects that were selected from the beacon. + PrimaryEffect, SecondaryEffect int32 +} + +// Marshal ... +func (a *BeaconPaymentStackRequestAction) Marshal(r protocol.IO) { + r.Varint32(&a.PrimaryEffect) + r.Varint32(&a.SecondaryEffect) +} + +// MineBlockStackRequestAction is sent by the client when it breaks a block. +type MineBlockStackRequestAction struct { + // HotbarSlot is the slot held by the player while mining a block. + HotbarSlot int32 + // PredictedDurability is the durability of the item that the client assumes to be present at the time. + PredictedDurability int32 + // StackNetworkID is the unique stack ID that the client assumes to be present at the time. The server + // must check if these IDs match. If they do not match, servers should reject the stack request that the + // action holding this info was in. + StackNetworkID int32 +} + +// Marshal ... +func (a *MineBlockStackRequestAction) Marshal(r protocol.IO) { + r.Varint32(&a.HotbarSlot) + r.Varint32(&a.PredictedDurability) + r.Varint32(&a.StackNetworkID) +} + +// CraftRecipeStackRequestAction is sent by the client the moment it begins crafting an item. This is the +// first action sent, before the Consume and Create item stack request actions. +// This action is also sent when an item is enchanted. Enchanting should be treated mostly the same way as +// crafting, where the old item is consumed. +type CraftRecipeStackRequestAction struct { + // RecipeNetworkID is the network ID of the recipe that is about to be crafted. This network ID matches + // one of the recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as + // of 1.16. + RecipeNetworkID uint32 + // NumberOfCrafts is how many times the recipe was crafted. This field appears to be boilerplate and + // has no effect. + NumberOfCrafts byte +} + +// Marshal ... +func (a *CraftRecipeStackRequestAction) Marshal(r protocol.IO) { + r.Varuint32(&a.RecipeNetworkID) + r.Uint8(&a.NumberOfCrafts) +} + +// AutoCraftRecipeStackRequestAction is sent by the client similarly to the CraftRecipeStackRequestAction. The +// only difference is that the recipe is automatically created and crafted by shift clicking the recipe book. +type AutoCraftRecipeStackRequestAction struct { + // RecipeNetworkID is the network ID of the recipe that is about to be crafted. This network ID matches + // one of the recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as + // of 1.16. + RecipeNetworkID uint32 + // NumberOfCrafts is how many times the recipe was crafted. This field is just a duplicate of TimesCrafted. + NumberOfCrafts byte + // TimesCrafted is how many times the recipe was crafted. + TimesCrafted byte + // Ingredients is a slice of ItemDescriptorCount that contains the ingredients that were used to craft the recipe. + // It is not exactly clear what this is used for, but it is sent by the vanilla client. + Ingredients []protocol.ItemDescriptorCount +} + +// Marshal ... +func (a *AutoCraftRecipeStackRequestAction) Marshal(r protocol.IO) { + r.Varuint32(&a.RecipeNetworkID) + r.Uint8(&a.NumberOfCrafts) + r.Uint8(&a.TimesCrafted) + protocol.FuncSlice(r, &a.Ingredients, r.ItemDescriptorCount) +} + +// CraftCreativeStackRequestAction is sent by the client when it takes an item out fo the creative inventory. +// The item is thus not really crafted, but instantly created. +type CraftCreativeStackRequestAction struct { + // CreativeItemNetworkID is the network ID of the creative item that is being created. This is one of the + // creative item network IDs sent in the CreativeContent packet. + CreativeItemNetworkID uint32 + // NumberOfCrafts is how many times the recipe was crafted. This field appears to be boilerplate and + // has no effect. + NumberOfCrafts byte +} + +// Marshal ... +func (a *CraftCreativeStackRequestAction) Marshal(r protocol.IO) { + r.Varuint32(&a.CreativeItemNetworkID) + r.Uint8(&a.NumberOfCrafts) +} + +// CraftRecipeOptionalStackRequestAction is sent when using an anvil. When this action is sent, the +// FilterStrings field in the respective stack request is non-empty and contains the name of the item created +// using the anvil or cartography table. +type CraftRecipeOptionalStackRequestAction struct { + // RecipeNetworkID is the network ID of the multi-recipe that is about to be crafted. This network ID matches + // one of the multi-recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as + // of 1.16. + RecipeNetworkID uint32 + // FilterStringIndex is the index of a filter string sent in a ItemStackRequest. + FilterStringIndex int32 +} + +// Marshal ... +func (c *CraftRecipeOptionalStackRequestAction) Marshal(r protocol.IO) { + r.Varuint32(&c.RecipeNetworkID) + r.Int32(&c.FilterStringIndex) +} + +// CraftGrindstoneRecipeStackRequestAction is sent when a grindstone recipe is crafted. It contains the RecipeNetworkID +// to identify the recipe crafted, and the cost for crafting the recipe. +type CraftGrindstoneRecipeStackRequestAction struct { + // RecipeNetworkID is the network ID of the recipe that is about to be crafted. This network ID matches + // one of the recipes sent in the CraftingData packet, where each of the recipes have a RecipeNetworkID as + // of 1.16. + RecipeNetworkID uint32 + // NumberOfCrafts is how many times the recipe was crafted. This field appears to be boilerplate and + // has no effect. + NumberOfCrafts byte + // Cost is the cost of the recipe that was crafted. + Cost int32 +} + +// Marshal ... +func (c *CraftGrindstoneRecipeStackRequestAction) Marshal(r protocol.IO) { + r.Varuint32(&c.RecipeNetworkID) + r.Uint8(&c.NumberOfCrafts) + r.Varint32(&c.Cost) +} + +// CraftLoomRecipeStackRequestAction is sent when a loom recipe is crafted. It simply contains the +// pattern identifier to figure out what pattern is meant to be applied to the item. +type CraftLoomRecipeStackRequestAction struct { + // Pattern is the pattern identifier for the loom recipe. + Pattern string + // TimesCrafted is how many times the recipe was crafted. + TimesCrafted byte +} + +// Marshal ... +func (c *CraftLoomRecipeStackRequestAction) Marshal(r protocol.IO) { + r.String(&c.Pattern) + r.Uint8(&c.TimesCrafted) +} + +// CraftNonImplementedStackRequestAction is an action sent for inventory actions that aren't yet implemented +// in the new system. These include, for example, anvils. +type CraftNonImplementedStackRequestAction struct{} + +// Marshal ... +func (*CraftNonImplementedStackRequestAction) Marshal(protocol.IO) {} + +// CraftResultsDeprecatedStackRequestAction is an additional, deprecated packet sent by the client after +// crafting. It holds the final results and the amount of times the recipe was crafted. It shouldn't be used. +// This action is also sent when an item is enchanted. Enchanting should be treated mostly the same way as +// crafting, where the old item is consumed. +type CraftResultsDeprecatedStackRequestAction struct { + ResultItems []protocol.ItemStack + TimesCrafted byte +} + +// Marshal ... +func (a *CraftResultsDeprecatedStackRequestAction) Marshal(r protocol.IO) { + protocol.FuncSlice(r, &a.ResultItems, r.Item) + r.Uint8(&a.TimesCrafted) +} + +// StackRequestSlotInfo holds information on a specific slot client-side. +type StackRequestSlotInfo struct { + // Container is the FullContainerName that describes the container that the slot is in. + Container protocol.FullContainerName + // Slot is the index of the slot within the container with the ContainerID above. + Slot byte + // StackNetworkID is the unique stack ID that the client assumes to be present in this slot. The server + // must check if these IDs match. If they do not match, servers should reject the stack request that the + // action holding this info was in. + StackNetworkID int32 +} + +// StackReqSlotInfo reads/writes a StackRequestSlotInfo x using IO r. +func StackReqSlotInfo(r protocol.IO, x *StackRequestSlotInfo) { + protocol.Single(r, &x.Container) + r.Uint8(&x.Slot) + r.Varint32(&x.StackNetworkID) +} diff --git a/legacyver/proto/resource_pack.go b/legacyver/proto/resource_pack.go new file mode 100644 index 0000000..b626f67 --- /dev/null +++ b/legacyver/proto/resource_pack.go @@ -0,0 +1,79 @@ +package proto + +import ( + "github.com/google/uuid" + "github.com/sandertv/gophertunnel/minecraft/protocol" +) + +// TexturePackInfo represents a texture pack's info sent over network. It holds information about the +// texture pack such as its name, description and version. +type TexturePackInfo struct { + // UUID is the UUID of the texture pack. Each texture pack downloaded must have a different UUID in + // order for the client to be able to handle them properly. + UUID uuid.UUID + // Version is the version of the texture pack. The client will cache texture packs sent by the server as + // long as they carry the same version. Sending a texture pack with a different version than previously + // will force the client to re-download it. + Version string + // Size is the total size in bytes that the texture pack occupies. This is the size of the compressed + // archive (zip) of the texture pack. + Size uint64 + // ContentKey is the key used to decrypt the behaviour pack if it is encrypted. This is generally the case + // for marketplace texture packs. + ContentKey string + // SubPackName ... + SubPackName string + // ContentIdentity is another UUID for the resource pack, and is generally set for marketplace texture + // packs. It is also required for client-side validations when the resource pack is encrypted. + ContentIdentity string + // HasScripts specifies if the texture packs has any scripts in it. A client will only download the + // behaviour pack if it supports scripts, which, up to 1.11, only includes Windows 10. + HasScripts bool + // AddonPack specifies if the texture pack is from an addon. + AddonPack bool + // RTXEnabled specifies if the texture pack uses the raytracing technology introduced in 1.16.200. + RTXEnabled bool + // DownloadURL is a URL that the client can use to download the pack instead of the server sending it in + // chunks, which it will continue to do if this field is left empty. + DownloadURL string +} + +func (x *TexturePackInfo) ToLatest() protocol.TexturePackInfo { + return protocol.TexturePackInfo{ + UUID: x.UUID, + Version: x.Version, + Size: x.Size, + ContentKey: x.ContentKey, + SubPackName: x.SubPackName, + ContentIdentity: x.ContentIdentity, + HasScripts: x.HasScripts, + AddonPack: x.AddonPack, + RTXEnabled: x.RTXEnabled, + DownloadURL: x.DownloadURL, + } +} + +// Marshal encodes/decodes a TexturePackInfo. +func (x *TexturePackInfo) Marshal(r protocol.IO) { + if IsProtoGTE(r, ID766) { + r.UUID(&x.UUID) + } else { + if IsReader(r) { + uuidStr := "" + r.String(&uuidStr) + x.UUID = uuid.MustParse(uuidStr) + } else { + uuidStr := x.UUID.String() + r.String(&uuidStr) + } + } + r.String(&x.Version) + r.Uint64(&x.Size) + r.String(&x.ContentKey) + r.String(&x.SubPackName) + r.String(&x.ContentIdentity) + r.Bool(&x.HasScripts) + r.Bool(&x.AddonPack) + r.Bool(&x.RTXEnabled) + r.String(&x.DownloadURL) +} diff --git a/legacyver/proto/type.go b/legacyver/proto/type.go new file mode 100644 index 0000000..880a295 --- /dev/null +++ b/legacyver/proto/type.go @@ -0,0 +1,5 @@ +package proto + +type legacyType struct { + ProtocolID int32 +} diff --git a/legacyver/protocol.go b/legacyver/protocol.go new file mode 100644 index 0000000..421968f --- /dev/null +++ b/legacyver/protocol.go @@ -0,0 +1,215 @@ +package legacyver + +import ( + "github.com/akmalfairuz/legacy-version/legacyver/legacypacket" + "github.com/akmalfairuz/legacy-version/legacyver/proto" + "github.com/sandertv/gophertunnel/minecraft" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "github.com/sandertv/gophertunnel/minecraft/protocol/packet" +) + +var ( + packetPoolClient packet.Pool + packetPoolServer packet.Pool +) + +func init() { + packetPoolClient = packet.NewClientPool() + packetPoolServer = packet.NewServerPool() + + packetPoolServer[packet.IDItemStackResponse] = func() packet.Packet { return &legacypacket.ItemStackResponse{} } + packetPoolServer[packet.IDResourcePacksInfo] = func() packet.Packet { return &legacypacket.ResourcePacksInfo{} } + + packetPoolClient[packet.IDPlayerAuthInput] = func() packet.Packet { return &legacypacket.PlayerAuthInput{} } +} + +type Protocol struct { + ver string + id int32 + + blockTranslator BlockTranslator + itemTranslator ItemTranslator +} + +func (p *Protocol) Ver() string { + return p.ver +} + +func (p *Protocol) ID() int32 { + return p.id +} + +func (p *Protocol) Packets(listener bool) packet.Pool { + if listener { + return packetPoolClient + } + return packetPoolServer +} + +func (p *Protocol) NewReader(r minecraft.ByteReader, shieldID int32, enableLimits bool) protocol.IO { + return proto.NewReader(protocol.NewReader(r, shieldID, enableLimits), p.id) +} + +func (p *Protocol) NewWriter(w minecraft.ByteWriter, shieldID int32) protocol.IO { + return proto.NewWriter(protocol.NewWriter(w, shieldID), p.id) +} + +func (p *Protocol) ConvertToLatest(pk packet.Packet, conn *minecraft.Conn) []packet.Packet { + return p.blockTranslator.UpgradeBlockPackets( + p.itemTranslator.UpgradeItemPackets(p.upgradePackets([]packet.Packet{pk}, conn), conn), + conn) +} + +func (p *Protocol) ConvertFromLatest(pk packet.Packet, conn *minecraft.Conn) []packet.Packet { + return p.downgradePackets(p.blockTranslator.DowngradeBlockPackets( + p.itemTranslator.DowngradeItemPackets([]packet.Packet{pk}, conn), + conn), conn) +} + +func (p *Protocol) downgradePackets(pks []packet.Packet, conn *minecraft.Conn) []packet.Packet { + for pkIndex, pk := range pks { + switch pk := pk.(type) { + case *packet.StartGame: + pk.GameVersion = p.ver + pk.BaseGameVersion = p.ver + case *packet.PlayerAuthInput: + inputData := pk.InputData + if p.ID() < proto.ID766 { + inputData = fitBitset(inputData, 64) + } + pks[pkIndex] = &legacypacket.PlayerAuthInput{ + Pitch: pk.Pitch, + Yaw: pk.Yaw, + Position: pk.Position, + MoveVector: pk.MoveVector, + HeadYaw: pk.HeadYaw, + InputData: inputData, + InputMode: pk.InputMode, + PlayMode: pk.PlayMode, + InteractionModel: pk.InteractionModel, + InteractPitch: pk.InteractPitch, + InteractYaw: pk.InteractYaw, + Tick: pk.Tick, + Delta: pk.Delta, + ItemInteractionData: pk.ItemInteractionData, + ItemStackRequest: pk.ItemStackRequest, + BlockActions: pk.BlockActions, + VehicleRotation: pk.VehicleRotation, + ClientPredictedVehicle: pk.ClientPredictedVehicle, + AnalogueMoveVector: pk.AnalogueMoveVector, + CameraOrientation: pk.CameraOrientation, + RawMoveVector: pk.RawMoveVector, + } + case *packet.ItemStackResponse: + responses := make([]proto.ItemStackResponse, len(pk.Responses)) + for i, r := range pk.Responses { + containerInfo := make([]proto.StackResponseContainerInfo, len(r.ContainerInfo)) + for j, c := range r.ContainerInfo { + slotInfo := make([]proto.StackResponseSlotInfo, len(c.SlotInfo)) + for k, s := range c.SlotInfo { + slotInfo[k] = proto.StackResponseSlotInfo{ + Slot: s.Slot, + HotbarSlot: s.HotbarSlot, + Count: s.Count, + StackNetworkID: s.StackNetworkID, + CustomName: s.CustomName, + FilteredCustomName: s.FilteredCustomName, + DurabilityCorrection: s.DurabilityCorrection, + } + } + containerInfo[j] = proto.StackResponseContainerInfo{ + Container: c.Container, + SlotInfo: slotInfo, + } + } + + responses[i] = proto.ItemStackResponse{ + Status: r.Status, + RequestID: r.RequestID, + ContainerInfo: containerInfo, + } + } + pks[pkIndex] = &legacypacket.ItemStackResponse{Responses: responses} + case *packet.ResourcePacksInfo: + texturePacks := make([]proto.TexturePackInfo, len(pk.TexturePacks)) + for i, t := range pk.TexturePacks { + texturePacks[i] = proto.TexturePackInfo{ + UUID: t.UUID, + Version: t.Version, + Size: t.Size, + ContentKey: t.ContentKey, + SubPackName: t.SubPackName, + ContentIdentity: t.ContentIdentity, + HasScripts: t.HasScripts, + AddonPack: t.AddonPack, + RTXEnabled: t.RTXEnabled, + DownloadURL: t.DownloadURL, + } + } + pks[pkIndex] = &legacypacket.ResourcePacksInfo{ + TexturePackRequired: pk.TexturePackRequired, + HasAddons: pk.HasAddons, + HasScripts: pk.HasScripts, + WorldTemplateUUID: pk.WorldTemplateUUID, + WorldTemplateVersion: pk.WorldTemplateVersion, + TexturePacks: texturePacks, + } + } + } + + return pks +} + +func (p *Protocol) upgradePackets(pks []packet.Packet, conn *minecraft.Conn) []packet.Packet { + for pkIndex, pk := range pks { + switch pk := pk.(type) { + case *packet.StartGame: + pk.GameVersion = p.ver + pk.BaseGameVersion = p.ver + case *legacypacket.PlayerAuthInput: + pks[pkIndex] = &packet.PlayerAuthInput{ + Pitch: pk.Pitch, + Yaw: pk.Yaw, + Position: pk.Position, + MoveVector: pk.MoveVector, + HeadYaw: pk.HeadYaw, + InputData: fitBitset(pk.InputData, packet.PlayerAuthInputBitsetSize), + InputMode: pk.InputMode, + PlayMode: pk.PlayMode, + InteractionModel: pk.InteractionModel, + InteractPitch: pk.InteractPitch, + InteractYaw: pk.InteractYaw, + Tick: pk.Tick, + Delta: pk.Delta, + ItemInteractionData: pk.ItemInteractionData, + ItemStackRequest: pk.ItemStackRequest, + BlockActions: pk.BlockActions, + VehicleRotation: pk.VehicleRotation, + ClientPredictedVehicle: pk.ClientPredictedVehicle, + AnalogueMoveVector: pk.AnalogueMoveVector, + CameraOrientation: pk.CameraOrientation, + RawMoveVector: pk.RawMoveVector, + } + case *legacypacket.ItemStackResponse: + responses := make([]protocol.ItemStackResponse, len(pk.Responses)) + for i, r := range pk.Responses { + responses[i] = r.ToLatest() + } + pks[pkIndex] = &packet.ItemStackResponse{Responses: responses} + case *legacypacket.ResourcePacksInfo: + texturePacks := make([]protocol.TexturePackInfo, len(pk.TexturePacks)) + for i, t := range pk.TexturePacks { + texturePacks[i] = t.ToLatest() + } + pks[pkIndex] = &packet.ResourcePacksInfo{ + TexturePackRequired: pk.TexturePackRequired, + HasAddons: pk.HasAddons, + HasScripts: pk.HasScripts, + WorldTemplateUUID: pk.WorldTemplateUUID, + WorldTemplateVersion: pk.WorldTemplateVersion, + TexturePacks: texturePacks, + } + } + } + return pks +} diff --git a/legacyver/required_item_list_748.json b/legacyver/required_item_list_748.json new file mode 100644 index 0000000..5d02118 --- /dev/null +++ b/legacyver/required_item_list_748.json @@ -0,0 +1,6998 @@ +{ + "minecraft:acacia_boat": { + "runtime_id": 405, + "component_based": false + }, + "minecraft:acacia_button": { + "runtime_id": -140, + "component_based": false + }, + "minecraft:acacia_chest_boat": { + "runtime_id": 679, + "component_based": false + }, + "minecraft:acacia_door": { + "runtime_id": 589, + "component_based": false + }, + "minecraft:acacia_double_slab": { + "runtime_id": -812, + "component_based": false + }, + "minecraft:acacia_fence": { + "runtime_id": -575, + "component_based": false + }, + "minecraft:acacia_fence_gate": { + "runtime_id": 187, + "component_based": false + }, + "minecraft:acacia_hanging_sign": { + "runtime_id": -504, + "component_based": false + }, + "minecraft:acacia_leaves": { + "runtime_id": 161, + "component_based": false + }, + "minecraft:acacia_log": { + "runtime_id": 162, + "component_based": false + }, + "minecraft:acacia_planks": { + "runtime_id": -742, + "component_based": false + }, + "minecraft:acacia_pressure_plate": { + "runtime_id": -150, + "component_based": false + }, + "minecraft:acacia_sapling": { + "runtime_id": -828, + "component_based": false + }, + "minecraft:acacia_sign": { + "runtime_id": 612, + "component_based": false + }, + "minecraft:acacia_slab": { + "runtime_id": -807, + "component_based": false + }, + "minecraft:acacia_stairs": { + "runtime_id": 163, + "component_based": false + }, + "minecraft:acacia_standing_sign": { + "runtime_id": -190, + "component_based": false + }, + "minecraft:acacia_trapdoor": { + "runtime_id": -145, + "component_based": false + }, + "minecraft:acacia_wall_sign": { + "runtime_id": -191, + "component_based": false + }, + "minecraft:acacia_wood": { + "runtime_id": -817, + "component_based": false + }, + "minecraft:activator_rail": { + "runtime_id": 126, + "component_based": false + }, + "minecraft:agent_spawn_egg": { + "runtime_id": 515, + "component_based": false + }, + "minecraft:air": { + "runtime_id": -158, + "component_based": false + }, + "minecraft:allay_spawn_egg": { + "runtime_id": 668, + "component_based": false + }, + "minecraft:allium": { + "runtime_id": -831, + "component_based": false + }, + "minecraft:allow": { + "runtime_id": 210, + "component_based": false + }, + "minecraft:amethyst_block": { + "runtime_id": -327, + "component_based": false + }, + "minecraft:amethyst_cluster": { + "runtime_id": -329, + "component_based": false + }, + "minecraft:amethyst_shard": { + "runtime_id": 661, + "component_based": false + }, + "minecraft:ancient_debris": { + "runtime_id": -271, + "component_based": false + }, + "minecraft:andesite": { + "runtime_id": -594, + "component_based": false + }, + "minecraft:andesite_double_slab": { + "runtime_id": -920, + "component_based": false + }, + "minecraft:andesite_slab": { + "runtime_id": -893, + "component_based": false + }, + "minecraft:andesite_stairs": { + "runtime_id": -171, + "component_based": false + }, + "minecraft:andesite_wall": { + "runtime_id": -974, + "component_based": false + }, + "minecraft:angler_pottery_sherd": { + "runtime_id": 693, + "component_based": false + }, + "minecraft:anvil": { + "runtime_id": 145, + "component_based": false + }, + "minecraft:apple": { + "runtime_id": 278, + "component_based": true + }, + "minecraft:archer_pottery_sherd": { + "runtime_id": 694, + "component_based": false + }, + "minecraft:armadillo_scute": { + "runtime_id": 740, + "component_based": false + }, + "minecraft:armadillo_spawn_egg": { + "runtime_id": 739, + "component_based": false + }, + "minecraft:armor_stand": { + "runtime_id": 585, + "component_based": false + }, + "minecraft:arms_up_pottery_sherd": { + "runtime_id": 695, + "component_based": false + }, + "minecraft:arrow": { + "runtime_id": 325, + "component_based": true + }, + "minecraft:axolotl_bucket": { + "runtime_id": 394, + "component_based": false + }, + "minecraft:axolotl_spawn_egg": { + "runtime_id": 530, + "component_based": false + }, + "minecraft:azalea": { + "runtime_id": -337, + "component_based": false + }, + "minecraft:azalea_leaves": { + "runtime_id": -324, + "component_based": false + }, + "minecraft:azalea_leaves_flowered": { + "runtime_id": -325, + "component_based": false + }, + "minecraft:azure_bluet": { + "runtime_id": -832, + "component_based": false + }, + "minecraft:baked_potato": { + "runtime_id": 303, + "component_based": false + }, + "minecraft:balloon": { + "runtime_id": 635, + "component_based": false + }, + "minecraft:bamboo": { + "runtime_id": -163, + "component_based": false + }, + "minecraft:bamboo_block": { + "runtime_id": -527, + "component_based": false + }, + "minecraft:bamboo_button": { + "runtime_id": -511, + "component_based": false + }, + "minecraft:bamboo_chest_raft": { + "runtime_id": 691, + "component_based": false + }, + "minecraft:bamboo_door": { + "runtime_id": -517, + "component_based": false + }, + "minecraft:bamboo_double_slab": { + "runtime_id": -521, + "component_based": false + }, + "minecraft:bamboo_fence": { + "runtime_id": -515, + "component_based": false + }, + "minecraft:bamboo_fence_gate": { + "runtime_id": -516, + "component_based": false + }, + "minecraft:bamboo_hanging_sign": { + "runtime_id": -522, + "component_based": false + }, + "minecraft:bamboo_mosaic": { + "runtime_id": -509, + "component_based": false + }, + "minecraft:bamboo_mosaic_double_slab": { + "runtime_id": -525, + "component_based": false + }, + "minecraft:bamboo_mosaic_slab": { + "runtime_id": -524, + "component_based": false + }, + "minecraft:bamboo_mosaic_stairs": { + "runtime_id": -523, + "component_based": false + }, + "minecraft:bamboo_planks": { + "runtime_id": -510, + "component_based": false + }, + "minecraft:bamboo_pressure_plate": { + "runtime_id": -514, + "component_based": false + }, + "minecraft:bamboo_raft": { + "runtime_id": 690, + "component_based": false + }, + "minecraft:bamboo_sapling": { + "runtime_id": -164, + "component_based": false + }, + "minecraft:bamboo_sign": { + "runtime_id": 689, + "component_based": false + }, + "minecraft:bamboo_slab": { + "runtime_id": -513, + "component_based": false + }, + "minecraft:bamboo_stairs": { + "runtime_id": -512, + "component_based": false + }, + "minecraft:bamboo_standing_sign": { + "runtime_id": -518, + "component_based": false + }, + "minecraft:bamboo_trapdoor": { + "runtime_id": -520, + "component_based": false + }, + "minecraft:bamboo_wall_sign": { + "runtime_id": -519, + "component_based": false + }, + "minecraft:banner": { + "runtime_id": 600, + "component_based": false + }, + "minecraft:banner_pattern": { + "runtime_id": 788, + "component_based": false + }, + "minecraft:barrel": { + "runtime_id": -203, + "component_based": false + }, + "minecraft:barrier": { + "runtime_id": -161, + "component_based": false + }, + "minecraft:basalt": { + "runtime_id": -234, + "component_based": false + }, + "minecraft:bat_spawn_egg": { + "runtime_id": 480, + "component_based": false + }, + "minecraft:beacon": { + "runtime_id": 138, + "component_based": false + }, + "minecraft:bed": { + "runtime_id": 444, + "component_based": false + }, + "minecraft:bedrock": { + "runtime_id": 7, + "component_based": false + }, + "minecraft:bee_nest": { + "runtime_id": -218, + "component_based": false + }, + "minecraft:bee_spawn_egg": { + "runtime_id": 522, + "component_based": false + }, + "minecraft:beef": { + "runtime_id": 295, + "component_based": false + }, + "minecraft:beehive": { + "runtime_id": -219, + "component_based": false + }, + "minecraft:beetroot": { + "runtime_id": 307, + "component_based": false + }, + "minecraft:beetroot_seeds": { + "runtime_id": 317, + "component_based": false + }, + "minecraft:beetroot_soup": { + "runtime_id": 308, + "component_based": false + }, + "minecraft:bell": { + "runtime_id": -206, + "component_based": false + }, + "minecraft:big_dripleaf": { + "runtime_id": -323, + "component_based": false + }, + "minecraft:birch_boat": { + "runtime_id": 402, + "component_based": false + }, + "minecraft:birch_button": { + "runtime_id": -141, + "component_based": false + }, + "minecraft:birch_chest_boat": { + "runtime_id": 676, + "component_based": false + }, + "minecraft:birch_door": { + "runtime_id": 587, + "component_based": false + }, + "minecraft:birch_double_slab": { + "runtime_id": -810, + "component_based": false + }, + "minecraft:birch_fence": { + "runtime_id": -576, + "component_based": false + }, + "minecraft:birch_fence_gate": { + "runtime_id": 184, + "component_based": false + }, + "minecraft:birch_hanging_sign": { + "runtime_id": -502, + "component_based": false + }, + "minecraft:birch_leaves": { + "runtime_id": -801, + "component_based": false + }, + "minecraft:birch_log": { + "runtime_id": -570, + "component_based": false + }, + "minecraft:birch_planks": { + "runtime_id": -740, + "component_based": false + }, + "minecraft:birch_pressure_plate": { + "runtime_id": -151, + "component_based": false + }, + "minecraft:birch_sapling": { + "runtime_id": -826, + "component_based": false + }, + "minecraft:birch_sign": { + "runtime_id": 610, + "component_based": false + }, + "minecraft:birch_slab": { + "runtime_id": -805, + "component_based": false + }, + "minecraft:birch_stairs": { + "runtime_id": 135, + "component_based": false + }, + "minecraft:birch_standing_sign": { + "runtime_id": -186, + "component_based": false + }, + "minecraft:birch_trapdoor": { + "runtime_id": -146, + "component_based": false + }, + "minecraft:birch_wall_sign": { + "runtime_id": -187, + "component_based": false + }, + "minecraft:birch_wood": { + "runtime_id": -815, + "component_based": false + }, + "minecraft:black_bundle": { + "runtime_id": 259, + "component_based": true + }, + "minecraft:black_candle": { + "runtime_id": -428, + "component_based": false + }, + "minecraft:black_candle_cake": { + "runtime_id": -445, + "component_based": false + }, + "minecraft:black_carpet": { + "runtime_id": -611, + "component_based": false + }, + "minecraft:black_concrete": { + "runtime_id": -642, + "component_based": false + }, + "minecraft:black_concrete_powder": { + "runtime_id": -723, + "component_based": false + }, + "minecraft:black_dye": { + "runtime_id": 421, + "component_based": false + }, + "minecraft:black_glazed_terracotta": { + "runtime_id": 235, + "component_based": false + }, + "minecraft:black_shulker_box": { + "runtime_id": -627, + "component_based": false + }, + "minecraft:black_stained_glass": { + "runtime_id": -687, + "component_based": false + }, + "minecraft:black_stained_glass_pane": { + "runtime_id": -657, + "component_based": false + }, + "minecraft:black_terracotta": { + "runtime_id": -738, + "component_based": false + }, + "minecraft:black_wool": { + "runtime_id": -554, + "component_based": false + }, + "minecraft:blackstone": { + "runtime_id": -273, + "component_based": false + }, + "minecraft:blackstone_double_slab": { + "runtime_id": -283, + "component_based": false + }, + "minecraft:blackstone_slab": { + "runtime_id": -282, + "component_based": false + }, + "minecraft:blackstone_stairs": { + "runtime_id": -276, + "component_based": false + }, + "minecraft:blackstone_wall": { + "runtime_id": -277, + "component_based": false + }, + "minecraft:blade_pottery_sherd": { + "runtime_id": 696, + "component_based": false + }, + "minecraft:blast_furnace": { + "runtime_id": -196, + "component_based": false + }, + "minecraft:blaze_powder": { + "runtime_id": 456, + "component_based": false + }, + "minecraft:blaze_rod": { + "runtime_id": 449, + "component_based": false + }, + "minecraft:blaze_spawn_egg": { + "runtime_id": 483, + "component_based": false + }, + "minecraft:bleach": { + "runtime_id": 633, + "component_based": false + }, + "minecraft:blue_bundle": { + "runtime_id": 266, + "component_based": true + }, + "minecraft:blue_candle": { + "runtime_id": -424, + "component_based": false + }, + "minecraft:blue_candle_cake": { + "runtime_id": -441, + "component_based": false + }, + "minecraft:blue_carpet": { + "runtime_id": -607, + "component_based": false + }, + "minecraft:blue_concrete": { + "runtime_id": -638, + "component_based": false + }, + "minecraft:blue_concrete_powder": { + "runtime_id": -719, + "component_based": false + }, + "minecraft:blue_dye": { + "runtime_id": 425, + "component_based": false + }, + "minecraft:blue_glazed_terracotta": { + "runtime_id": 231, + "component_based": false + }, + "minecraft:blue_ice": { + "runtime_id": -11, + "component_based": false + }, + "minecraft:blue_orchid": { + "runtime_id": -830, + "component_based": false + }, + "minecraft:blue_shulker_box": { + "runtime_id": -623, + "component_based": false + }, + "minecraft:blue_stained_glass": { + "runtime_id": -683, + "component_based": false + }, + "minecraft:blue_stained_glass_pane": { + "runtime_id": -653, + "component_based": false + }, + "minecraft:blue_terracotta": { + "runtime_id": -734, + "component_based": false + }, + "minecraft:blue_wool": { + "runtime_id": -563, + "component_based": false + }, + "minecraft:boat": { + "runtime_id": 786, + "component_based": false + }, + "minecraft:bogged_spawn_egg": { + "runtime_id": 490, + "component_based": false + }, + "minecraft:bolt_armor_trim_smithing_template": { + "runtime_id": 735, + "component_based": false + }, + "minecraft:bone": { + "runtime_id": 441, + "component_based": false + }, + "minecraft:bone_block": { + "runtime_id": 216, + "component_based": false + }, + "minecraft:bone_meal": { + "runtime_id": 437, + "component_based": false + }, + "minecraft:book": { + "runtime_id": 413, + "component_based": false + }, + "minecraft:bookshelf": { + "runtime_id": 47, + "component_based": false + }, + "minecraft:border_block": { + "runtime_id": 212, + "component_based": false + }, + "minecraft:bordure_indented_banner_pattern": { + "runtime_id": 619, + "component_based": false + }, + "minecraft:bow": { + "runtime_id": 324, + "component_based": false + }, + "minecraft:bowl": { + "runtime_id": 346, + "component_based": false + }, + "minecraft:brain_coral": { + "runtime_id": -581, + "component_based": false + }, + "minecraft:brain_coral_block": { + "runtime_id": -849, + "component_based": false + }, + "minecraft:brain_coral_fan": { + "runtime_id": -840, + "component_based": false + }, + "minecraft:brain_coral_wall_fan": { + "runtime_id": -904, + "component_based": false + }, + "minecraft:bread": { + "runtime_id": 283, + "component_based": false + }, + "minecraft:breeze_rod": { + "runtime_id": 274, + "component_based": true + }, + "minecraft:breeze_spawn_egg": { + "runtime_id": 529, + "component_based": false + }, + "minecraft:brewer_pottery_sherd": { + "runtime_id": 697, + "component_based": false + }, + "minecraft:brewing_stand": { + "runtime_id": 458, + "component_based": true + }, + "minecraft:brick": { + "runtime_id": 409, + "component_based": false + }, + "minecraft:brick_block": { + "runtime_id": 45, + "component_based": false + }, + "minecraft:brick_double_slab": { + "runtime_id": -880, + "component_based": false + }, + "minecraft:brick_slab": { + "runtime_id": -874, + "component_based": false + }, + "minecraft:brick_stairs": { + "runtime_id": 108, + "component_based": false + }, + "minecraft:brick_wall": { + "runtime_id": -976, + "component_based": false + }, + "minecraft:brown_bundle": { + "runtime_id": 261, + "component_based": true + }, + "minecraft:brown_candle": { + "runtime_id": -425, + "component_based": false + }, + "minecraft:brown_candle_cake": { + "runtime_id": -442, + "component_based": false + }, + "minecraft:brown_carpet": { + "runtime_id": -608, + "component_based": false + }, + "minecraft:brown_concrete": { + "runtime_id": -639, + "component_based": false + }, + "minecraft:brown_concrete_powder": { + "runtime_id": -720, + "component_based": false + }, + "minecraft:brown_dye": { + "runtime_id": 424, + "component_based": false + }, + "minecraft:brown_glazed_terracotta": { + "runtime_id": 232, + "component_based": false + }, + "minecraft:brown_mushroom": { + "runtime_id": 39, + "component_based": false + }, + "minecraft:brown_mushroom_block": { + "runtime_id": 99, + "component_based": false + }, + "minecraft:brown_shulker_box": { + "runtime_id": -624, + "component_based": false + }, + "minecraft:brown_stained_glass": { + "runtime_id": -684, + "component_based": false + }, + "minecraft:brown_stained_glass_pane": { + "runtime_id": -654, + "component_based": false + }, + "minecraft:brown_terracotta": { + "runtime_id": -735, + "component_based": false + }, + "minecraft:brown_wool": { + "runtime_id": -555, + "component_based": false + }, + "minecraft:brush": { + "runtime_id": 716, + "component_based": false + }, + "minecraft:bubble_column": { + "runtime_id": -160, + "component_based": false + }, + "minecraft:bubble_coral": { + "runtime_id": -582, + "component_based": false + }, + "minecraft:bubble_coral_block": { + "runtime_id": -850, + "component_based": false + }, + "minecraft:bubble_coral_fan": { + "runtime_id": -841, + "component_based": false + }, + "minecraft:bubble_coral_wall_fan": { + "runtime_id": -136, + "component_based": false + }, + "minecraft:bucket": { + "runtime_id": 385, + "component_based": false + }, + "minecraft:budding_amethyst": { + "runtime_id": -328, + "component_based": false + }, + "minecraft:bundle": { + "runtime_id": 269, + "component_based": true + }, + "minecraft:burn_pottery_sherd": { + "runtime_id": 698, + "component_based": false + }, + "minecraft:cactus": { + "runtime_id": 81, + "component_based": false + }, + "minecraft:cake": { + "runtime_id": 443, + "component_based": true + }, + "minecraft:calcite": { + "runtime_id": -326, + "component_based": false + }, + "minecraft:calibrated_sculk_sensor": { + "runtime_id": -580, + "component_based": false + }, + "minecraft:camel_spawn_egg": { + "runtime_id": 692, + "component_based": false + }, + "minecraft:camera": { + "runtime_id": 630, + "component_based": false + }, + "minecraft:campfire": { + "runtime_id": 624, + "component_based": true + }, + "minecraft:candle": { + "runtime_id": -412, + "component_based": false + }, + "minecraft:candle_cake": { + "runtime_id": -429, + "component_based": false + }, + "minecraft:carpet": { + "runtime_id": 745, + "component_based": false + }, + "minecraft:carrot": { + "runtime_id": 301, + "component_based": false + }, + "minecraft:carrot_on_a_stick": { + "runtime_id": 550, + "component_based": false + }, + "minecraft:carrots": { + "runtime_id": 141, + "component_based": false + }, + "minecraft:cartography_table": { + "runtime_id": -200, + "component_based": false + }, + "minecraft:carved_pumpkin": { + "runtime_id": -155, + "component_based": false + }, + "minecraft:cat_spawn_egg": { + "runtime_id": 516, + "component_based": false + }, + "minecraft:cauldron": { + "runtime_id": 459, + "component_based": true + }, + "minecraft:cave_spider_spawn_egg": { + "runtime_id": 484, + "component_based": false + }, + "minecraft:cave_vines": { + "runtime_id": -322, + "component_based": false + }, + "minecraft:cave_vines_body_with_berries": { + "runtime_id": -375, + "component_based": false + }, + "minecraft:cave_vines_head_with_berries": { + "runtime_id": -376, + "component_based": false + }, + "minecraft:chain": { + "runtime_id": 656, + "component_based": true + }, + "minecraft:chain_command_block": { + "runtime_id": 189, + "component_based": false + }, + "minecraft:chainmail_boots": { + "runtime_id": 367, + "component_based": false + }, + "minecraft:chainmail_chestplate": { + "runtime_id": 365, + "component_based": false + }, + "minecraft:chainmail_helmet": { + "runtime_id": 364, + "component_based": false + }, + "minecraft:chainmail_leggings": { + "runtime_id": 366, + "component_based": false + }, + "minecraft:charcoal": { + "runtime_id": 327, + "component_based": true + }, + "minecraft:chemical_heat": { + "runtime_id": 192, + "component_based": false + }, + "minecraft:chemistry_table": { + "runtime_id": 780, + "component_based": false + }, + "minecraft:cherry_boat": { + "runtime_id": 686, + "component_based": false + }, + "minecraft:cherry_button": { + "runtime_id": -530, + "component_based": false + }, + "minecraft:cherry_chest_boat": { + "runtime_id": 687, + "component_based": false + }, + "minecraft:cherry_door": { + "runtime_id": -531, + "component_based": false + }, + "minecraft:cherry_double_slab": { + "runtime_id": -540, + "component_based": false + }, + "minecraft:cherry_fence": { + "runtime_id": -532, + "component_based": false + }, + "minecraft:cherry_fence_gate": { + "runtime_id": -533, + "component_based": false + }, + "minecraft:cherry_hanging_sign": { + "runtime_id": -534, + "component_based": false + }, + "minecraft:cherry_leaves": { + "runtime_id": -548, + "component_based": false + }, + "minecraft:cherry_log": { + "runtime_id": -536, + "component_based": false + }, + "minecraft:cherry_planks": { + "runtime_id": -537, + "component_based": false + }, + "minecraft:cherry_pressure_plate": { + "runtime_id": -538, + "component_based": false + }, + "minecraft:cherry_sapling": { + "runtime_id": -547, + "component_based": false + }, + "minecraft:cherry_sign": { + "runtime_id": 688, + "component_based": false + }, + "minecraft:cherry_slab": { + "runtime_id": -539, + "component_based": false + }, + "minecraft:cherry_stairs": { + "runtime_id": -541, + "component_based": false + }, + "minecraft:cherry_standing_sign": { + "runtime_id": -542, + "component_based": false + }, + "minecraft:cherry_trapdoor": { + "runtime_id": -543, + "component_based": false + }, + "minecraft:cherry_wall_sign": { + "runtime_id": -544, + "component_based": false + }, + "minecraft:cherry_wood": { + "runtime_id": -546, + "component_based": false + }, + "minecraft:chest": { + "runtime_id": 54, + "component_based": false + }, + "minecraft:chest_boat": { + "runtime_id": 682, + "component_based": false + }, + "minecraft:chest_minecart": { + "runtime_id": 415, + "component_based": false + }, + "minecraft:chicken": { + "runtime_id": 297, + "component_based": false + }, + "minecraft:chicken_spawn_egg": { + "runtime_id": 462, + "component_based": false + }, + "minecraft:chipped_anvil": { + "runtime_id": -959, + "component_based": false + }, + "minecraft:chiseled_bookshelf": { + "runtime_id": -526, + "component_based": false + }, + "minecraft:chiseled_copper": { + "runtime_id": -760, + "component_based": false + }, + "minecraft:chiseled_deepslate": { + "runtime_id": -395, + "component_based": false + }, + "minecraft:chiseled_nether_bricks": { + "runtime_id": -302, + "component_based": false + }, + "minecraft:chiseled_polished_blackstone": { + "runtime_id": -279, + "component_based": false + }, + "minecraft:chiseled_quartz_block": { + "runtime_id": -953, + "component_based": false + }, + "minecraft:chiseled_red_sandstone": { + "runtime_id": -956, + "component_based": false + }, + "minecraft:chiseled_sandstone": { + "runtime_id": -944, + "component_based": false + }, + "minecraft:chiseled_stone_bricks": { + "runtime_id": -870, + "component_based": false + }, + "minecraft:chiseled_tuff": { + "runtime_id": -753, + "component_based": false + }, + "minecraft:chiseled_tuff_bricks": { + "runtime_id": -759, + "component_based": false + }, + "minecraft:chorus_flower": { + "runtime_id": 200, + "component_based": false + }, + "minecraft:chorus_fruit": { + "runtime_id": 591, + "component_based": false + }, + "minecraft:chorus_plant": { + "runtime_id": 240, + "component_based": false + }, + "minecraft:clay": { + "runtime_id": 82, + "component_based": false + }, + "minecraft:clay_ball": { + "runtime_id": 410, + "component_based": false + }, + "minecraft:client_request_placeholder_block": { + "runtime_id": -465, + "component_based": false + }, + "minecraft:clock": { + "runtime_id": 419, + "component_based": false + }, + "minecraft:coal": { + "runtime_id": 326, + "component_based": true + }, + "minecraft:coal_block": { + "runtime_id": 173, + "component_based": false + }, + "minecraft:coal_ore": { + "runtime_id": 16, + "component_based": false + }, + "minecraft:coarse_dirt": { + "runtime_id": -962, + "component_based": false + }, + "minecraft:coast_armor_trim_smithing_template": { + "runtime_id": 720, + "component_based": false + }, + "minecraft:cobbled_deepslate": { + "runtime_id": -379, + "component_based": false + }, + "minecraft:cobbled_deepslate_double_slab": { + "runtime_id": -396, + "component_based": false + }, + "minecraft:cobbled_deepslate_slab": { + "runtime_id": -380, + "component_based": false + }, + "minecraft:cobbled_deepslate_stairs": { + "runtime_id": -381, + "component_based": false + }, + "minecraft:cobbled_deepslate_wall": { + "runtime_id": -382, + "component_based": false + }, + "minecraft:cobblestone": { + "runtime_id": 4, + "component_based": false + }, + "minecraft:cobblestone_double_slab": { + "runtime_id": -879, + "component_based": false + }, + "minecraft:cobblestone_slab": { + "runtime_id": -873, + "component_based": false + }, + "minecraft:cobblestone_wall": { + "runtime_id": 139, + "component_based": false + }, + "minecraft:cocoa": { + "runtime_id": 127, + "component_based": false + }, + "minecraft:cocoa_beans": { + "runtime_id": 438, + "component_based": false + }, + "minecraft:cod": { + "runtime_id": 286, + "component_based": false + }, + "minecraft:cod_bucket": { + "runtime_id": 389, + "component_based": false + }, + "minecraft:cod_spawn_egg": { + "runtime_id": 508, + "component_based": false + }, + "minecraft:colored_torch_blue": { + "runtime_id": 204, + "component_based": false + }, + "minecraft:colored_torch_bp": { + "runtime_id": 784, + "component_based": false + }, + "minecraft:colored_torch_green": { + "runtime_id": -963, + "component_based": false + }, + "minecraft:colored_torch_purple": { + "runtime_id": -964, + "component_based": false + }, + "minecraft:colored_torch_red": { + "runtime_id": 202, + "component_based": false + }, + "minecraft:colored_torch_rg": { + "runtime_id": 783, + "component_based": false + }, + "minecraft:command_block": { + "runtime_id": 137, + "component_based": false + }, + "minecraft:command_block_minecart": { + "runtime_id": 596, + "component_based": false + }, + "minecraft:comparator": { + "runtime_id": 555, + "component_based": true + }, + "minecraft:compass": { + "runtime_id": 417, + "component_based": false + }, + "minecraft:composter": { + "runtime_id": -213, + "component_based": false + }, + "minecraft:compound": { + "runtime_id": 631, + "component_based": false + }, + "minecraft:compound_creator": { + "runtime_id": 238, + "component_based": false + }, + "minecraft:concrete": { + "runtime_id": 771, + "component_based": false + }, + "minecraft:concrete_powder": { + "runtime_id": 772, + "component_based": false + }, + "minecraft:conduit": { + "runtime_id": -157, + "component_based": false + }, + "minecraft:cooked_beef": { + "runtime_id": 296, + "component_based": false + }, + "minecraft:cooked_chicken": { + "runtime_id": 298, + "component_based": false + }, + "minecraft:cooked_cod": { + "runtime_id": 290, + "component_based": false + }, + "minecraft:cooked_mutton": { + "runtime_id": 584, + "component_based": false + }, + "minecraft:cooked_porkchop": { + "runtime_id": 285, + "component_based": false + }, + "minecraft:cooked_rabbit": { + "runtime_id": 311, + "component_based": false + }, + "minecraft:cooked_salmon": { + "runtime_id": 291, + "component_based": false + }, + "minecraft:cookie": { + "runtime_id": 293, + "component_based": false + }, + "minecraft:copper_block": { + "runtime_id": -340, + "component_based": false + }, + "minecraft:copper_bulb": { + "runtime_id": -776, + "component_based": false + }, + "minecraft:copper_door": { + "runtime_id": -784, + "component_based": false + }, + "minecraft:copper_grate": { + "runtime_id": -768, + "component_based": false + }, + "minecraft:copper_ingot": { + "runtime_id": 538, + "component_based": false + }, + "minecraft:copper_ore": { + "runtime_id": -311, + "component_based": false + }, + "minecraft:copper_trapdoor": { + "runtime_id": -792, + "component_based": false + }, + "minecraft:coral": { + "runtime_id": 767, + "component_based": false + }, + "minecraft:coral_block": { + "runtime_id": 749, + "component_based": false + }, + "minecraft:coral_fan": { + "runtime_id": 758, + "component_based": false + }, + "minecraft:coral_fan_dead": { + "runtime_id": 759, + "component_based": false + }, + "minecraft:cornflower": { + "runtime_id": -838, + "component_based": false + }, + "minecraft:cow_spawn_egg": { + "runtime_id": 463, + "component_based": false + }, + "minecraft:cracked_deepslate_bricks": { + "runtime_id": -410, + "component_based": false + }, + "minecraft:cracked_deepslate_tiles": { + "runtime_id": -409, + "component_based": false + }, + "minecraft:cracked_nether_bricks": { + "runtime_id": -303, + "component_based": false + }, + "minecraft:cracked_polished_blackstone_bricks": { + "runtime_id": -280, + "component_based": false + }, + "minecraft:cracked_stone_bricks": { + "runtime_id": -869, + "component_based": false + }, + "minecraft:crafter": { + "runtime_id": -313, + "component_based": false + }, + "minecraft:crafting_table": { + "runtime_id": 58, + "component_based": false + }, + "minecraft:creeper_banner_pattern": { + "runtime_id": 615, + "component_based": false + }, + "minecraft:creeper_head": { + "runtime_id": -968, + "component_based": false + }, + "minecraft:creeper_spawn_egg": { + "runtime_id": 468, + "component_based": false + }, + "minecraft:crimson_button": { + "runtime_id": -260, + "component_based": false + }, + "minecraft:crimson_door": { + "runtime_id": 653, + "component_based": false + }, + "minecraft:crimson_double_slab": { + "runtime_id": -266, + "component_based": false + }, + "minecraft:crimson_fence": { + "runtime_id": -256, + "component_based": false + }, + "minecraft:crimson_fence_gate": { + "runtime_id": -258, + "component_based": false + }, + "minecraft:crimson_fungus": { + "runtime_id": -228, + "component_based": false + }, + "minecraft:crimson_hanging_sign": { + "runtime_id": -506, + "component_based": false + }, + "minecraft:crimson_hyphae": { + "runtime_id": -299, + "component_based": false + }, + "minecraft:crimson_nylium": { + "runtime_id": -232, + "component_based": false + }, + "minecraft:crimson_planks": { + "runtime_id": -242, + "component_based": false + }, + "minecraft:crimson_pressure_plate": { + "runtime_id": -262, + "component_based": false + }, + "minecraft:crimson_roots": { + "runtime_id": -223, + "component_based": false + }, + "minecraft:crimson_sign": { + "runtime_id": 651, + "component_based": false + }, + "minecraft:crimson_slab": { + "runtime_id": -264, + "component_based": false + }, + "minecraft:crimson_stairs": { + "runtime_id": -254, + "component_based": false + }, + "minecraft:crimson_standing_sign": { + "runtime_id": -250, + "component_based": false + }, + "minecraft:crimson_stem": { + "runtime_id": -225, + "component_based": false + }, + "minecraft:crimson_trapdoor": { + "runtime_id": -246, + "component_based": false + }, + "minecraft:crimson_wall_sign": { + "runtime_id": -252, + "component_based": false + }, + "minecraft:crossbow": { + "runtime_id": 608, + "component_based": false + }, + "minecraft:crying_obsidian": { + "runtime_id": -289, + "component_based": false + }, + "minecraft:cut_copper": { + "runtime_id": -347, + "component_based": false + }, + "minecraft:cut_copper_slab": { + "runtime_id": -361, + "component_based": false + }, + "minecraft:cut_copper_stairs": { + "runtime_id": -354, + "component_based": false + }, + "minecraft:cut_red_sandstone": { + "runtime_id": -957, + "component_based": false + }, + "minecraft:cut_red_sandstone_double_slab": { + "runtime_id": -928, + "component_based": false + }, + "minecraft:cut_red_sandstone_slab": { + "runtime_id": -901, + "component_based": false + }, + "minecraft:cut_sandstone": { + "runtime_id": -945, + "component_based": false + }, + "minecraft:cut_sandstone_double_slab": { + "runtime_id": -927, + "component_based": false + }, + "minecraft:cut_sandstone_slab": { + "runtime_id": -900, + "component_based": false + }, + "minecraft:cyan_bundle": { + "runtime_id": 265, + "component_based": true + }, + "minecraft:cyan_candle": { + "runtime_id": -422, + "component_based": false + }, + "minecraft:cyan_candle_cake": { + "runtime_id": -439, + "component_based": false + }, + "minecraft:cyan_carpet": { + "runtime_id": -605, + "component_based": false + }, + "minecraft:cyan_concrete": { + "runtime_id": -636, + "component_based": false + }, + "minecraft:cyan_concrete_powder": { + "runtime_id": -717, + "component_based": false + }, + "minecraft:cyan_dye": { + "runtime_id": 427, + "component_based": false + }, + "minecraft:cyan_glazed_terracotta": { + "runtime_id": 229, + "component_based": false + }, + "minecraft:cyan_shulker_box": { + "runtime_id": -621, + "component_based": false + }, + "minecraft:cyan_stained_glass": { + "runtime_id": -681, + "component_based": false + }, + "minecraft:cyan_stained_glass_pane": { + "runtime_id": -651, + "component_based": false + }, + "minecraft:cyan_terracotta": { + "runtime_id": -732, + "component_based": false + }, + "minecraft:cyan_wool": { + "runtime_id": -561, + "component_based": false + }, + "minecraft:damaged_anvil": { + "runtime_id": -960, + "component_based": false + }, + "minecraft:dandelion": { + "runtime_id": 37, + "component_based": false + }, + "minecraft:danger_pottery_sherd": { + "runtime_id": 699, + "component_based": false + }, + "minecraft:dark_oak_boat": { + "runtime_id": 406, + "component_based": false + }, + "minecraft:dark_oak_button": { + "runtime_id": -142, + "component_based": false + }, + "minecraft:dark_oak_chest_boat": { + "runtime_id": 680, + "component_based": false + }, + "minecraft:dark_oak_door": { + "runtime_id": 590, + "component_based": false + }, + "minecraft:dark_oak_double_slab": { + "runtime_id": -813, + "component_based": false + }, + "minecraft:dark_oak_fence": { + "runtime_id": -577, + "component_based": false + }, + "minecraft:dark_oak_fence_gate": { + "runtime_id": 186, + "component_based": false + }, + "minecraft:dark_oak_hanging_sign": { + "runtime_id": -505, + "component_based": false + }, + "minecraft:dark_oak_leaves": { + "runtime_id": -803, + "component_based": false + }, + "minecraft:dark_oak_log": { + "runtime_id": -572, + "component_based": false + }, + "minecraft:dark_oak_planks": { + "runtime_id": -743, + "component_based": false + }, + "minecraft:dark_oak_pressure_plate": { + "runtime_id": -152, + "component_based": false + }, + "minecraft:dark_oak_sapling": { + "runtime_id": -829, + "component_based": false + }, + "minecraft:dark_oak_sign": { + "runtime_id": 613, + "component_based": false + }, + "minecraft:dark_oak_slab": { + "runtime_id": -808, + "component_based": false + }, + "minecraft:dark_oak_stairs": { + "runtime_id": 164, + "component_based": false + }, + "minecraft:dark_oak_trapdoor": { + "runtime_id": -147, + "component_based": false + }, + "minecraft:dark_oak_wood": { + "runtime_id": -818, + "component_based": false + }, + "minecraft:dark_prismarine": { + "runtime_id": -947, + "component_based": false + }, + "minecraft:dark_prismarine_double_slab": { + "runtime_id": -913, + "component_based": false + }, + "minecraft:dark_prismarine_slab": { + "runtime_id": -886, + "component_based": false + }, + "minecraft:dark_prismarine_stairs": { + "runtime_id": -3, + "component_based": false + }, + "minecraft:darkoak_standing_sign": { + "runtime_id": -192, + "component_based": false + }, + "minecraft:darkoak_wall_sign": { + "runtime_id": -193, + "component_based": false + }, + "minecraft:daylight_detector": { + "runtime_id": 151, + "component_based": false + }, + "minecraft:daylight_detector_inverted": { + "runtime_id": 178, + "component_based": false + }, + "minecraft:dead_brain_coral": { + "runtime_id": -586, + "component_based": false + }, + "minecraft:dead_brain_coral_block": { + "runtime_id": -854, + "component_based": false + }, + "minecraft:dead_brain_coral_fan": { + "runtime_id": -844, + "component_based": false + }, + "minecraft:dead_brain_coral_wall_fan": { + "runtime_id": -906, + "component_based": false + }, + "minecraft:dead_bubble_coral": { + "runtime_id": -587, + "component_based": false + }, + "minecraft:dead_bubble_coral_block": { + "runtime_id": -855, + "component_based": false + }, + "minecraft:dead_bubble_coral_fan": { + "runtime_id": -845, + "component_based": false + }, + "minecraft:dead_bubble_coral_wall_fan": { + "runtime_id": -908, + "component_based": false + }, + "minecraft:dead_fire_coral": { + "runtime_id": -588, + "component_based": false + }, + "minecraft:dead_fire_coral_block": { + "runtime_id": -856, + "component_based": false + }, + "minecraft:dead_fire_coral_fan": { + "runtime_id": -846, + "component_based": false + }, + "minecraft:dead_fire_coral_wall_fan": { + "runtime_id": -909, + "component_based": false + }, + "minecraft:dead_horn_coral": { + "runtime_id": -589, + "component_based": false + }, + "minecraft:dead_horn_coral_block": { + "runtime_id": -857, + "component_based": false + }, + "minecraft:dead_horn_coral_fan": { + "runtime_id": -847, + "component_based": false + }, + "minecraft:dead_horn_coral_wall_fan": { + "runtime_id": -910, + "component_based": false + }, + "minecraft:dead_tube_coral": { + "runtime_id": -585, + "component_based": false + }, + "minecraft:dead_tube_coral_block": { + "runtime_id": -853, + "component_based": false + }, + "minecraft:dead_tube_coral_fan": { + "runtime_id": -134, + "component_based": false + }, + "minecraft:dead_tube_coral_wall_fan": { + "runtime_id": -905, + "component_based": false + }, + "minecraft:deadbush": { + "runtime_id": 32, + "component_based": false + }, + "minecraft:debug_stick": { + "runtime_id": 626, + "component_based": false + }, + "minecraft:decorated_pot": { + "runtime_id": -551, + "component_based": false + }, + "minecraft:deepslate": { + "runtime_id": -378, + "component_based": false + }, + "minecraft:deepslate_brick_double_slab": { + "runtime_id": -399, + "component_based": false + }, + "minecraft:deepslate_brick_slab": { + "runtime_id": -392, + "component_based": false + }, + "minecraft:deepslate_brick_stairs": { + "runtime_id": -393, + "component_based": false + }, + "minecraft:deepslate_brick_wall": { + "runtime_id": -394, + "component_based": false + }, + "minecraft:deepslate_bricks": { + "runtime_id": -391, + "component_based": false + }, + "minecraft:deepslate_coal_ore": { + "runtime_id": -406, + "component_based": false + }, + "minecraft:deepslate_copper_ore": { + "runtime_id": -408, + "component_based": false + }, + "minecraft:deepslate_diamond_ore": { + "runtime_id": -405, + "component_based": false + }, + "minecraft:deepslate_emerald_ore": { + "runtime_id": -407, + "component_based": false + }, + "minecraft:deepslate_gold_ore": { + "runtime_id": -402, + "component_based": false + }, + "minecraft:deepslate_iron_ore": { + "runtime_id": -401, + "component_based": false + }, + "minecraft:deepslate_lapis_ore": { + "runtime_id": -400, + "component_based": false + }, + "minecraft:deepslate_redstone_ore": { + "runtime_id": -403, + "component_based": false + }, + "minecraft:deepslate_tile_double_slab": { + "runtime_id": -398, + "component_based": false + }, + "minecraft:deepslate_tile_slab": { + "runtime_id": -388, + "component_based": false + }, + "minecraft:deepslate_tile_stairs": { + "runtime_id": -389, + "component_based": false + }, + "minecraft:deepslate_tile_wall": { + "runtime_id": -390, + "component_based": false + }, + "minecraft:deepslate_tiles": { + "runtime_id": -387, + "component_based": false + }, + "minecraft:deny": { + "runtime_id": 211, + "component_based": false + }, + "minecraft:deprecated_anvil": { + "runtime_id": -961, + "component_based": false + }, + "minecraft:deprecated_purpur_block_1": { + "runtime_id": -950, + "component_based": false + }, + "minecraft:deprecated_purpur_block_2": { + "runtime_id": -952, + "component_based": false + }, + "minecraft:detector_rail": { + "runtime_id": 28, + "component_based": false + }, + "minecraft:diamond": { + "runtime_id": 328, + "component_based": false + }, + "minecraft:diamond_axe": { + "runtime_id": 343, + "component_based": false + }, + "minecraft:diamond_block": { + "runtime_id": 57, + "component_based": false + }, + "minecraft:diamond_boots": { + "runtime_id": 375, + "component_based": false + }, + "minecraft:diamond_chestplate": { + "runtime_id": 373, + "component_based": false + }, + "minecraft:diamond_helmet": { + "runtime_id": 372, + "component_based": false + }, + "minecraft:diamond_hoe": { + "runtime_id": 357, + "component_based": false + }, + "minecraft:diamond_horse_armor": { + "runtime_id": 566, + "component_based": false + }, + "minecraft:diamond_leggings": { + "runtime_id": 374, + "component_based": false + }, + "minecraft:diamond_ore": { + "runtime_id": 56, + "component_based": false + }, + "minecraft:diamond_pickaxe": { + "runtime_id": 342, + "component_based": false + }, + "minecraft:diamond_shovel": { + "runtime_id": 341, + "component_based": false + }, + "minecraft:diamond_sword": { + "runtime_id": 340, + "component_based": false + }, + "minecraft:diorite": { + "runtime_id": -592, + "component_based": false + }, + "minecraft:diorite_double_slab": { + "runtime_id": -921, + "component_based": false + }, + "minecraft:diorite_slab": { + "runtime_id": -894, + "component_based": false + }, + "minecraft:diorite_stairs": { + "runtime_id": -170, + "component_based": false + }, + "minecraft:diorite_wall": { + "runtime_id": -973, + "component_based": false + }, + "minecraft:dirt": { + "runtime_id": 3, + "component_based": false + }, + "minecraft:dirt_with_roots": { + "runtime_id": -318, + "component_based": false + }, + "minecraft:disc_fragment_5": { + "runtime_id": 674, + "component_based": false + }, + "minecraft:dispenser": { + "runtime_id": 23, + "component_based": false + }, + "minecraft:dolphin_spawn_egg": { + "runtime_id": 512, + "component_based": false + }, + "minecraft:donkey_spawn_egg": { + "runtime_id": 493, + "component_based": false + }, + "minecraft:double_cut_copper_slab": { + "runtime_id": -368, + "component_based": false + }, + "minecraft:double_plant": { + "runtime_id": 765, + "component_based": false + }, + "minecraft:double_stone_block_slab": { + "runtime_id": 754, + "component_based": false + }, + "minecraft:double_stone_block_slab2": { + "runtime_id": 755, + "component_based": false + }, + "minecraft:double_stone_block_slab3": { + "runtime_id": 756, + "component_based": false + }, + "minecraft:double_stone_block_slab4": { + "runtime_id": 757, + "component_based": false + }, + "minecraft:dragon_breath": { + "runtime_id": 593, + "component_based": false + }, + "minecraft:dragon_egg": { + "runtime_id": 122, + "component_based": false + }, + "minecraft:dragon_head": { + "runtime_id": -969, + "component_based": false + }, + "minecraft:dried_kelp": { + "runtime_id": 292, + "component_based": false + }, + "minecraft:dried_kelp_block": { + "runtime_id": -139, + "component_based": false + }, + "minecraft:dripstone_block": { + "runtime_id": -317, + "component_based": false + }, + "minecraft:dropper": { + "runtime_id": 125, + "component_based": false + }, + "minecraft:drowned_spawn_egg": { + "runtime_id": 511, + "component_based": false + }, + "minecraft:dune_armor_trim_smithing_template": { + "runtime_id": 719, + "component_based": false + }, + "minecraft:dye": { + "runtime_id": 787, + "component_based": false + }, + "minecraft:echo_shard": { + "runtime_id": 684, + "component_based": false + }, + "minecraft:egg": { + "runtime_id": 416, + "component_based": false + }, + "minecraft:elder_guardian_spawn_egg": { + "runtime_id": 499, + "component_based": false + }, + "minecraft:element_0": { + "runtime_id": 36, + "component_based": false + }, + "minecraft:element_1": { + "runtime_id": -12, + "component_based": false + }, + "minecraft:element_10": { + "runtime_id": -21, + "component_based": false + }, + "minecraft:element_100": { + "runtime_id": -111, + "component_based": false + }, + "minecraft:element_101": { + "runtime_id": -112, + "component_based": false + }, + "minecraft:element_102": { + "runtime_id": -113, + "component_based": false + }, + "minecraft:element_103": { + "runtime_id": -114, + "component_based": false + }, + "minecraft:element_104": { + "runtime_id": -115, + "component_based": false + }, + "minecraft:element_105": { + "runtime_id": -116, + "component_based": false + }, + "minecraft:element_106": { + "runtime_id": -117, + "component_based": false + }, + "minecraft:element_107": { + "runtime_id": -118, + "component_based": false + }, + "minecraft:element_108": { + "runtime_id": -119, + "component_based": false + }, + "minecraft:element_109": { + "runtime_id": -120, + "component_based": false + }, + "minecraft:element_11": { + "runtime_id": -22, + "component_based": false + }, + "minecraft:element_110": { + "runtime_id": -121, + "component_based": false + }, + "minecraft:element_111": { + "runtime_id": -122, + "component_based": false + }, + "minecraft:element_112": { + "runtime_id": -123, + "component_based": false + }, + "minecraft:element_113": { + "runtime_id": -124, + "component_based": false + }, + "minecraft:element_114": { + "runtime_id": -125, + "component_based": false + }, + "minecraft:element_115": { + "runtime_id": -126, + "component_based": false + }, + "minecraft:element_116": { + "runtime_id": -127, + "component_based": false + }, + "minecraft:element_117": { + "runtime_id": -128, + "component_based": false + }, + "minecraft:element_118": { + "runtime_id": -129, + "component_based": false + }, + "minecraft:element_12": { + "runtime_id": -23, + "component_based": false + }, + "minecraft:element_13": { + "runtime_id": -24, + "component_based": false + }, + "minecraft:element_14": { + "runtime_id": -25, + "component_based": false + }, + "minecraft:element_15": { + "runtime_id": -26, + "component_based": false + }, + "minecraft:element_16": { + "runtime_id": -27, + "component_based": false + }, + "minecraft:element_17": { + "runtime_id": -28, + "component_based": false + }, + "minecraft:element_18": { + "runtime_id": -29, + "component_based": false + }, + "minecraft:element_19": { + "runtime_id": -30, + "component_based": false + }, + "minecraft:element_2": { + "runtime_id": -13, + "component_based": false + }, + "minecraft:element_20": { + "runtime_id": -31, + "component_based": false + }, + "minecraft:element_21": { + "runtime_id": -32, + "component_based": false + }, + "minecraft:element_22": { + "runtime_id": -33, + "component_based": false + }, + "minecraft:element_23": { + "runtime_id": -34, + "component_based": false + }, + "minecraft:element_24": { + "runtime_id": -35, + "component_based": false + }, + "minecraft:element_25": { + "runtime_id": -36, + "component_based": false + }, + "minecraft:element_26": { + "runtime_id": -37, + "component_based": false + }, + "minecraft:element_27": { + "runtime_id": -38, + "component_based": false + }, + "minecraft:element_28": { + "runtime_id": -39, + "component_based": false + }, + "minecraft:element_29": { + "runtime_id": -40, + "component_based": false + }, + "minecraft:element_3": { + "runtime_id": -14, + "component_based": false + }, + "minecraft:element_30": { + "runtime_id": -41, + "component_based": false + }, + "minecraft:element_31": { + "runtime_id": -42, + "component_based": false + }, + "minecraft:element_32": { + "runtime_id": -43, + "component_based": false + }, + "minecraft:element_33": { + "runtime_id": -44, + "component_based": false + }, + "minecraft:element_34": { + "runtime_id": -45, + "component_based": false + }, + "minecraft:element_35": { + "runtime_id": -46, + "component_based": false + }, + "minecraft:element_36": { + "runtime_id": -47, + "component_based": false + }, + "minecraft:element_37": { + "runtime_id": -48, + "component_based": false + }, + "minecraft:element_38": { + "runtime_id": -49, + "component_based": false + }, + "minecraft:element_39": { + "runtime_id": -50, + "component_based": false + }, + "minecraft:element_4": { + "runtime_id": -15, + "component_based": false + }, + "minecraft:element_40": { + "runtime_id": -51, + "component_based": false + }, + "minecraft:element_41": { + "runtime_id": -52, + "component_based": false + }, + "minecraft:element_42": { + "runtime_id": -53, + "component_based": false + }, + "minecraft:element_43": { + "runtime_id": -54, + "component_based": false + }, + "minecraft:element_44": { + "runtime_id": -55, + "component_based": false + }, + "minecraft:element_45": { + "runtime_id": -56, + "component_based": false + }, + "minecraft:element_46": { + "runtime_id": -57, + "component_based": false + }, + "minecraft:element_47": { + "runtime_id": -58, + "component_based": false + }, + "minecraft:element_48": { + "runtime_id": -59, + "component_based": false + }, + "minecraft:element_49": { + "runtime_id": -60, + "component_based": false + }, + "minecraft:element_5": { + "runtime_id": -16, + "component_based": false + }, + "minecraft:element_50": { + "runtime_id": -61, + "component_based": false + }, + "minecraft:element_51": { + "runtime_id": -62, + "component_based": false + }, + "minecraft:element_52": { + "runtime_id": -63, + "component_based": false + }, + "minecraft:element_53": { + "runtime_id": -64, + "component_based": false + }, + "minecraft:element_54": { + "runtime_id": -65, + "component_based": false + }, + "minecraft:element_55": { + "runtime_id": -66, + "component_based": false + }, + "minecraft:element_56": { + "runtime_id": -67, + "component_based": false + }, + "minecraft:element_57": { + "runtime_id": -68, + "component_based": false + }, + "minecraft:element_58": { + "runtime_id": -69, + "component_based": false + }, + "minecraft:element_59": { + "runtime_id": -70, + "component_based": false + }, + "minecraft:element_6": { + "runtime_id": -17, + "component_based": false + }, + "minecraft:element_60": { + "runtime_id": -71, + "component_based": false + }, + "minecraft:element_61": { + "runtime_id": -72, + "component_based": false + }, + "minecraft:element_62": { + "runtime_id": -73, + "component_based": false + }, + "minecraft:element_63": { + "runtime_id": -74, + "component_based": false + }, + "minecraft:element_64": { + "runtime_id": -75, + "component_based": false + }, + "minecraft:element_65": { + "runtime_id": -76, + "component_based": false + }, + "minecraft:element_66": { + "runtime_id": -77, + "component_based": false + }, + "minecraft:element_67": { + "runtime_id": -78, + "component_based": false + }, + "minecraft:element_68": { + "runtime_id": -79, + "component_based": false + }, + "minecraft:element_69": { + "runtime_id": -80, + "component_based": false + }, + "minecraft:element_7": { + "runtime_id": -18, + "component_based": false + }, + "minecraft:element_70": { + "runtime_id": -81, + "component_based": false + }, + "minecraft:element_71": { + "runtime_id": -82, + "component_based": false + }, + "minecraft:element_72": { + "runtime_id": -83, + "component_based": false + }, + "minecraft:element_73": { + "runtime_id": -84, + "component_based": false + }, + "minecraft:element_74": { + "runtime_id": -85, + "component_based": false + }, + "minecraft:element_75": { + "runtime_id": -86, + "component_based": false + }, + "minecraft:element_76": { + "runtime_id": -87, + "component_based": false + }, + "minecraft:element_77": { + "runtime_id": -88, + "component_based": false + }, + "minecraft:element_78": { + "runtime_id": -89, + "component_based": false + }, + "minecraft:element_79": { + "runtime_id": -90, + "component_based": false + }, + "minecraft:element_8": { + "runtime_id": -19, + "component_based": false + }, + "minecraft:element_80": { + "runtime_id": -91, + "component_based": false + }, + "minecraft:element_81": { + "runtime_id": -92, + "component_based": false + }, + "minecraft:element_82": { + "runtime_id": -93, + "component_based": false + }, + "minecraft:element_83": { + "runtime_id": -94, + "component_based": false + }, + "minecraft:element_84": { + "runtime_id": -95, + "component_based": false + }, + "minecraft:element_85": { + "runtime_id": -96, + "component_based": false + }, + "minecraft:element_86": { + "runtime_id": -97, + "component_based": false + }, + "minecraft:element_87": { + "runtime_id": -98, + "component_based": false + }, + "minecraft:element_88": { + "runtime_id": -99, + "component_based": false + }, + "minecraft:element_89": { + "runtime_id": -100, + "component_based": false + }, + "minecraft:element_9": { + "runtime_id": -20, + "component_based": false + }, + "minecraft:element_90": { + "runtime_id": -101, + "component_based": false + }, + "minecraft:element_91": { + "runtime_id": -102, + "component_based": false + }, + "minecraft:element_92": { + "runtime_id": -103, + "component_based": false + }, + "minecraft:element_93": { + "runtime_id": -104, + "component_based": false + }, + "minecraft:element_94": { + "runtime_id": -105, + "component_based": false + }, + "minecraft:element_95": { + "runtime_id": -106, + "component_based": false + }, + "minecraft:element_96": { + "runtime_id": -107, + "component_based": false + }, + "minecraft:element_97": { + "runtime_id": -108, + "component_based": false + }, + "minecraft:element_98": { + "runtime_id": -109, + "component_based": false + }, + "minecraft:element_99": { + "runtime_id": -110, + "component_based": false + }, + "minecraft:element_constructor": { + "runtime_id": -987, + "component_based": false + }, + "minecraft:elytra": { + "runtime_id": 597, + "component_based": false + }, + "minecraft:emerald": { + "runtime_id": 546, + "component_based": false + }, + "minecraft:emerald_block": { + "runtime_id": 133, + "component_based": false + }, + "minecraft:emerald_ore": { + "runtime_id": 129, + "component_based": false + }, + "minecraft:empty_map": { + "runtime_id": 549, + "component_based": false + }, + "minecraft:enchanted_book": { + "runtime_id": 554, + "component_based": false + }, + "minecraft:enchanted_golden_apple": { + "runtime_id": 281, + "component_based": false + }, + "minecraft:enchanting_table": { + "runtime_id": 116, + "component_based": false + }, + "minecraft:end_brick_stairs": { + "runtime_id": -178, + "component_based": false + }, + "minecraft:end_bricks": { + "runtime_id": 206, + "component_based": false + }, + "minecraft:end_crystal": { + "runtime_id": 790, + "component_based": false + }, + "minecraft:end_gateway": { + "runtime_id": 209, + "component_based": false + }, + "minecraft:end_portal": { + "runtime_id": 119, + "component_based": false + }, + "minecraft:end_portal_frame": { + "runtime_id": 120, + "component_based": false + }, + "minecraft:end_rod": { + "runtime_id": 208, + "component_based": false + }, + "minecraft:end_stone": { + "runtime_id": 121, + "component_based": false + }, + "minecraft:end_stone_brick_double_slab": { + "runtime_id": -167, + "component_based": false + }, + "minecraft:end_stone_brick_slab": { + "runtime_id": -162, + "component_based": false + }, + "minecraft:end_stone_brick_wall": { + "runtime_id": -980, + "component_based": false + }, + "minecraft:ender_chest": { + "runtime_id": 130, + "component_based": false + }, + "minecraft:ender_dragon_spawn_egg": { + "runtime_id": 535, + "component_based": false + }, + "minecraft:ender_eye": { + "runtime_id": 460, + "component_based": false + }, + "minecraft:ender_pearl": { + "runtime_id": 448, + "component_based": false + }, + "minecraft:enderman_spawn_egg": { + "runtime_id": 469, + "component_based": false + }, + "minecraft:endermite_spawn_egg": { + "runtime_id": 487, + "component_based": false + }, + "minecraft:evoker_spawn_egg": { + "runtime_id": 503, + "component_based": false + }, + "minecraft:experience_bottle": { + "runtime_id": 542, + "component_based": false + }, + "minecraft:explorer_pottery_sherd": { + "runtime_id": 700, + "component_based": false + }, + "minecraft:exposed_chiseled_copper": { + "runtime_id": -761, + "component_based": false + }, + "minecraft:exposed_copper": { + "runtime_id": -341, + "component_based": false + }, + "minecraft:exposed_copper_bulb": { + "runtime_id": -777, + "component_based": false + }, + "minecraft:exposed_copper_door": { + "runtime_id": -785, + "component_based": false + }, + "minecraft:exposed_copper_grate": { + "runtime_id": -769, + "component_based": false + }, + "minecraft:exposed_copper_trapdoor": { + "runtime_id": -793, + "component_based": false + }, + "minecraft:exposed_cut_copper": { + "runtime_id": -348, + "component_based": false + }, + "minecraft:exposed_cut_copper_slab": { + "runtime_id": -362, + "component_based": false + }, + "minecraft:exposed_cut_copper_stairs": { + "runtime_id": -355, + "component_based": false + }, + "minecraft:exposed_double_cut_copper_slab": { + "runtime_id": -369, + "component_based": false + }, + "minecraft:eye_armor_trim_smithing_template": { + "runtime_id": 723, + "component_based": false + }, + "minecraft:farmland": { + "runtime_id": 60, + "component_based": false + }, + "minecraft:feather": { + "runtime_id": 352, + "component_based": false + }, + "minecraft:fence": { + "runtime_id": 747, + "component_based": false + }, + "minecraft:fence_gate": { + "runtime_id": 107, + "component_based": false + }, + "minecraft:fermented_spider_eye": { + "runtime_id": 455, + "component_based": false + }, + "minecraft:fern": { + "runtime_id": -848, + "component_based": false + }, + "minecraft:field_masoned_banner_pattern": { + "runtime_id": 618, + "component_based": false + }, + "minecraft:filled_map": { + "runtime_id": 446, + "component_based": false + }, + "minecraft:fire": { + "runtime_id": 51, + "component_based": false + }, + "minecraft:fire_charge": { + "runtime_id": 543, + "component_based": false + }, + "minecraft:fire_coral": { + "runtime_id": -583, + "component_based": false + }, + "minecraft:fire_coral_block": { + "runtime_id": -851, + "component_based": false + }, + "minecraft:fire_coral_fan": { + "runtime_id": -842, + "component_based": false + }, + "minecraft:fire_coral_wall_fan": { + "runtime_id": -907, + "component_based": false + }, + "minecraft:firework_rocket": { + "runtime_id": 552, + "component_based": false + }, + "minecraft:firework_star": { + "runtime_id": 553, + "component_based": false + }, + "minecraft:fishing_rod": { + "runtime_id": 418, + "component_based": true + }, + "minecraft:fletching_table": { + "runtime_id": -201, + "component_based": false + }, + "minecraft:flint": { + "runtime_id": 381, + "component_based": false + }, + "minecraft:flint_and_steel": { + "runtime_id": 323, + "component_based": false + }, + "minecraft:flow_armor_trim_smithing_template": { + "runtime_id": 734, + "component_based": false + }, + "minecraft:flow_banner_pattern": { + "runtime_id": 622, + "component_based": false + }, + "minecraft:flow_pottery_sherd": { + "runtime_id": 701, + "component_based": false + }, + "minecraft:flower_banner_pattern": { + "runtime_id": 614, + "component_based": false + }, + "minecraft:flower_pot": { + "runtime_id": 548, + "component_based": true + }, + "minecraft:flowering_azalea": { + "runtime_id": -338, + "component_based": false + }, + "minecraft:flowing_lava": { + "runtime_id": 10, + "component_based": false + }, + "minecraft:flowing_water": { + "runtime_id": 8, + "component_based": false + }, + "minecraft:fox_spawn_egg": { + "runtime_id": 518, + "component_based": false + }, + "minecraft:frame": { + "runtime_id": 547, + "component_based": true + }, + "minecraft:friend_pottery_sherd": { + "runtime_id": 702, + "component_based": false + }, + "minecraft:frog_spawn": { + "runtime_id": -468, + "component_based": false + }, + "minecraft:frog_spawn_egg": { + "runtime_id": 665, + "component_based": false + }, + "minecraft:frosted_ice": { + "runtime_id": 207, + "component_based": false + }, + "minecraft:furnace": { + "runtime_id": 61, + "component_based": false + }, + "minecraft:ghast_spawn_egg": { + "runtime_id": 481, + "component_based": false + }, + "minecraft:ghast_tear": { + "runtime_id": 451, + "component_based": false + }, + "minecraft:gilded_blackstone": { + "runtime_id": -281, + "component_based": false + }, + "minecraft:glass": { + "runtime_id": 20, + "component_based": false + }, + "minecraft:glass_bottle": { + "runtime_id": 454, + "component_based": false + }, + "minecraft:glass_pane": { + "runtime_id": 102, + "component_based": false + }, + "minecraft:glistering_melon_slice": { + "runtime_id": 461, + "component_based": false + }, + "minecraft:globe_banner_pattern": { + "runtime_id": 621, + "component_based": false + }, + "minecraft:glow_berries": { + "runtime_id": 791, + "component_based": false + }, + "minecraft:glow_frame": { + "runtime_id": 660, + "component_based": true + }, + "minecraft:glow_ink_sac": { + "runtime_id": 537, + "component_based": false + }, + "minecraft:glow_lichen": { + "runtime_id": -411, + "component_based": false + }, + "minecraft:glow_squid_spawn_egg": { + "runtime_id": 532, + "component_based": false + }, + "minecraft:glow_stick": { + "runtime_id": 638, + "component_based": false + }, + "minecraft:glowingobsidian": { + "runtime_id": 246, + "component_based": false + }, + "minecraft:glowstone": { + "runtime_id": 89, + "component_based": false + }, + "minecraft:glowstone_dust": { + "runtime_id": 420, + "component_based": false + }, + "minecraft:goat_horn": { + "runtime_id": 664, + "component_based": false + }, + "minecraft:goat_spawn_egg": { + "runtime_id": 531, + "component_based": false + }, + "minecraft:gold_block": { + "runtime_id": 41, + "component_based": false + }, + "minecraft:gold_ingot": { + "runtime_id": 330, + "component_based": false + }, + "minecraft:gold_nugget": { + "runtime_id": 452, + "component_based": false + }, + "minecraft:gold_ore": { + "runtime_id": 14, + "component_based": false + }, + "minecraft:golden_apple": { + "runtime_id": 280, + "component_based": false + }, + "minecraft:golden_axe": { + "runtime_id": 350, + "component_based": false + }, + "minecraft:golden_boots": { + "runtime_id": 379, + "component_based": false + }, + "minecraft:golden_carrot": { + "runtime_id": 305, + "component_based": false + }, + "minecraft:golden_chestplate": { + "runtime_id": 377, + "component_based": false + }, + "minecraft:golden_helmet": { + "runtime_id": 376, + "component_based": false + }, + "minecraft:golden_hoe": { + "runtime_id": 358, + "component_based": false + }, + "minecraft:golden_horse_armor": { + "runtime_id": 565, + "component_based": false + }, + "minecraft:golden_leggings": { + "runtime_id": 378, + "component_based": false + }, + "minecraft:golden_pickaxe": { + "runtime_id": 349, + "component_based": false + }, + "minecraft:golden_rail": { + "runtime_id": 27, + "component_based": false + }, + "minecraft:golden_shovel": { + "runtime_id": 348, + "component_based": false + }, + "minecraft:golden_sword": { + "runtime_id": 347, + "component_based": false + }, + "minecraft:granite": { + "runtime_id": -590, + "component_based": false + }, + "minecraft:granite_double_slab": { + "runtime_id": -923, + "component_based": false + }, + "minecraft:granite_slab": { + "runtime_id": -896, + "component_based": false + }, + "minecraft:granite_stairs": { + "runtime_id": -169, + "component_based": false + }, + "minecraft:granite_wall": { + "runtime_id": -972, + "component_based": false + }, + "minecraft:grass_block": { + "runtime_id": 2, + "component_based": false + }, + "minecraft:grass_path": { + "runtime_id": 198, + "component_based": false + }, + "minecraft:gravel": { + "runtime_id": 13, + "component_based": false + }, + "minecraft:gray_bundle": { + "runtime_id": 264, + "component_based": true + }, + "minecraft:gray_candle": { + "runtime_id": -420, + "component_based": false + }, + "minecraft:gray_candle_cake": { + "runtime_id": -437, + "component_based": false + }, + "minecraft:gray_carpet": { + "runtime_id": -603, + "component_based": false + }, + "minecraft:gray_concrete": { + "runtime_id": -634, + "component_based": false + }, + "minecraft:gray_concrete_powder": { + "runtime_id": -715, + "component_based": false + }, + "minecraft:gray_dye": { + "runtime_id": 429, + "component_based": false + }, + "minecraft:gray_glazed_terracotta": { + "runtime_id": 227, + "component_based": false + }, + "minecraft:gray_shulker_box": { + "runtime_id": -619, + "component_based": false + }, + "minecraft:gray_stained_glass": { + "runtime_id": -679, + "component_based": false + }, + "minecraft:gray_stained_glass_pane": { + "runtime_id": -649, + "component_based": false + }, + "minecraft:gray_terracotta": { + "runtime_id": -730, + "component_based": false + }, + "minecraft:gray_wool": { + "runtime_id": -553, + "component_based": false + }, + "minecraft:green_bundle": { + "runtime_id": 262, + "component_based": true + }, + "minecraft:green_candle": { + "runtime_id": -426, + "component_based": false + }, + "minecraft:green_candle_cake": { + "runtime_id": -443, + "component_based": false + }, + "minecraft:green_carpet": { + "runtime_id": -609, + "component_based": false + }, + "minecraft:green_concrete": { + "runtime_id": -640, + "component_based": false + }, + "minecraft:green_concrete_powder": { + "runtime_id": -721, + "component_based": false + }, + "minecraft:green_dye": { + "runtime_id": 423, + "component_based": false + }, + "minecraft:green_glazed_terracotta": { + "runtime_id": 233, + "component_based": false + }, + "minecraft:green_shulker_box": { + "runtime_id": -625, + "component_based": false + }, + "minecraft:green_stained_glass": { + "runtime_id": -685, + "component_based": false + }, + "minecraft:green_stained_glass_pane": { + "runtime_id": -655, + "component_based": false + }, + "minecraft:green_terracotta": { + "runtime_id": -736, + "component_based": false + }, + "minecraft:green_wool": { + "runtime_id": -560, + "component_based": false + }, + "minecraft:grindstone": { + "runtime_id": -195, + "component_based": false + }, + "minecraft:guardian_spawn_egg": { + "runtime_id": 488, + "component_based": false + }, + "minecraft:gunpowder": { + "runtime_id": 353, + "component_based": false + }, + "minecraft:guster_banner_pattern": { + "runtime_id": 623, + "component_based": false + }, + "minecraft:guster_pottery_sherd": { + "runtime_id": 703, + "component_based": false + }, + "minecraft:hanging_roots": { + "runtime_id": -319, + "component_based": false + }, + "minecraft:hard_black_stained_glass": { + "runtime_id": -702, + "component_based": false + }, + "minecraft:hard_black_stained_glass_pane": { + "runtime_id": -672, + "component_based": false + }, + "minecraft:hard_blue_stained_glass": { + "runtime_id": -698, + "component_based": false + }, + "minecraft:hard_blue_stained_glass_pane": { + "runtime_id": -668, + "component_based": false + }, + "minecraft:hard_brown_stained_glass": { + "runtime_id": -699, + "component_based": false + }, + "minecraft:hard_brown_stained_glass_pane": { + "runtime_id": -669, + "component_based": false + }, + "minecraft:hard_cyan_stained_glass": { + "runtime_id": -696, + "component_based": false + }, + "minecraft:hard_cyan_stained_glass_pane": { + "runtime_id": -666, + "component_based": false + }, + "minecraft:hard_glass": { + "runtime_id": 253, + "component_based": false + }, + "minecraft:hard_glass_pane": { + "runtime_id": 190, + "component_based": false + }, + "minecraft:hard_gray_stained_glass": { + "runtime_id": -694, + "component_based": false + }, + "minecraft:hard_gray_stained_glass_pane": { + "runtime_id": -664, + "component_based": false + }, + "minecraft:hard_green_stained_glass": { + "runtime_id": -700, + "component_based": false + }, + "minecraft:hard_green_stained_glass_pane": { + "runtime_id": -670, + "component_based": false + }, + "minecraft:hard_light_blue_stained_glass": { + "runtime_id": -690, + "component_based": false + }, + "minecraft:hard_light_blue_stained_glass_pane": { + "runtime_id": -660, + "component_based": false + }, + "minecraft:hard_light_gray_stained_glass": { + "runtime_id": -695, + "component_based": false + }, + "minecraft:hard_light_gray_stained_glass_pane": { + "runtime_id": -665, + "component_based": false + }, + "minecraft:hard_lime_stained_glass": { + "runtime_id": -692, + "component_based": false + }, + "minecraft:hard_lime_stained_glass_pane": { + "runtime_id": -662, + "component_based": false + }, + "minecraft:hard_magenta_stained_glass": { + "runtime_id": -689, + "component_based": false + }, + "minecraft:hard_magenta_stained_glass_pane": { + "runtime_id": -659, + "component_based": false + }, + "minecraft:hard_orange_stained_glass": { + "runtime_id": -688, + "component_based": false + }, + "minecraft:hard_orange_stained_glass_pane": { + "runtime_id": -658, + "component_based": false + }, + "minecraft:hard_pink_stained_glass": { + "runtime_id": -693, + "component_based": false + }, + "minecraft:hard_pink_stained_glass_pane": { + "runtime_id": -663, + "component_based": false + }, + "minecraft:hard_purple_stained_glass": { + "runtime_id": -697, + "component_based": false + }, + "minecraft:hard_purple_stained_glass_pane": { + "runtime_id": -667, + "component_based": false + }, + "minecraft:hard_red_stained_glass": { + "runtime_id": -701, + "component_based": false + }, + "minecraft:hard_red_stained_glass_pane": { + "runtime_id": -671, + "component_based": false + }, + "minecraft:hard_stained_glass": { + "runtime_id": 781, + "component_based": false + }, + "minecraft:hard_stained_glass_pane": { + "runtime_id": 782, + "component_based": false + }, + "minecraft:hard_white_stained_glass": { + "runtime_id": 254, + "component_based": false + }, + "minecraft:hard_white_stained_glass_pane": { + "runtime_id": 191, + "component_based": false + }, + "minecraft:hard_yellow_stained_glass": { + "runtime_id": -691, + "component_based": false + }, + "minecraft:hard_yellow_stained_glass_pane": { + "runtime_id": -661, + "component_based": false + }, + "minecraft:hardened_clay": { + "runtime_id": 172, + "component_based": false + }, + "minecraft:hay_block": { + "runtime_id": 170, + "component_based": false + }, + "minecraft:heart_of_the_sea": { + "runtime_id": 604, + "component_based": false + }, + "minecraft:heart_pottery_sherd": { + "runtime_id": 704, + "component_based": false + }, + "minecraft:heartbreak_pottery_sherd": { + "runtime_id": 705, + "component_based": false + }, + "minecraft:heavy_core": { + "runtime_id": -316, + "component_based": false + }, + "minecraft:heavy_weighted_pressure_plate": { + "runtime_id": 148, + "component_based": false + }, + "minecraft:hoglin_spawn_egg": { + "runtime_id": 524, + "component_based": false + }, + "minecraft:honey_block": { + "runtime_id": -220, + "component_based": false + }, + "minecraft:honey_bottle": { + "runtime_id": 628, + "component_based": false + }, + "minecraft:honeycomb": { + "runtime_id": 627, + "component_based": false + }, + "minecraft:honeycomb_block": { + "runtime_id": -221, + "component_based": false + }, + "minecraft:hopper": { + "runtime_id": 560, + "component_based": true + }, + "minecraft:hopper_minecart": { + "runtime_id": 559, + "component_based": false + }, + "minecraft:horn_coral": { + "runtime_id": -584, + "component_based": false + }, + "minecraft:horn_coral_block": { + "runtime_id": -852, + "component_based": false + }, + "minecraft:horn_coral_fan": { + "runtime_id": -843, + "component_based": false + }, + "minecraft:horn_coral_wall_fan": { + "runtime_id": -137, + "component_based": false + }, + "minecraft:horse_spawn_egg": { + "runtime_id": 485, + "component_based": false + }, + "minecraft:host_armor_trim_smithing_template": { + "runtime_id": 733, + "component_based": false + }, + "minecraft:howl_pottery_sherd": { + "runtime_id": 706, + "component_based": false + }, + "minecraft:husk_spawn_egg": { + "runtime_id": 491, + "component_based": false + }, + "minecraft:ice": { + "runtime_id": 79, + "component_based": false + }, + "minecraft:ice_bomb": { + "runtime_id": 632, + "component_based": false + }, + "minecraft:infested_chiseled_stone_bricks": { + "runtime_id": -862, + "component_based": false + }, + "minecraft:infested_cobblestone": { + "runtime_id": -858, + "component_based": false + }, + "minecraft:infested_cracked_stone_bricks": { + "runtime_id": -861, + "component_based": false + }, + "minecraft:infested_deepslate": { + "runtime_id": -454, + "component_based": false + }, + "minecraft:infested_mossy_stone_bricks": { + "runtime_id": -860, + "component_based": false + }, + "minecraft:infested_stone": { + "runtime_id": 97, + "component_based": false + }, + "minecraft:infested_stone_bricks": { + "runtime_id": -859, + "component_based": false + }, + "minecraft:info_update": { + "runtime_id": 248, + "component_based": false + }, + "minecraft:info_update2": { + "runtime_id": 249, + "component_based": false + }, + "minecraft:ink_sac": { + "runtime_id": 439, + "component_based": false + }, + "minecraft:invisible_bedrock": { + "runtime_id": 95, + "component_based": false + }, + "minecraft:iron_axe": { + "runtime_id": 322, + "component_based": false + }, + "minecraft:iron_bars": { + "runtime_id": 101, + "component_based": false + }, + "minecraft:iron_block": { + "runtime_id": 42, + "component_based": false + }, + "minecraft:iron_boots": { + "runtime_id": 371, + "component_based": false + }, + "minecraft:iron_chestplate": { + "runtime_id": 369, + "component_based": false + }, + "minecraft:iron_door": { + "runtime_id": 397, + "component_based": false + }, + "minecraft:iron_golem_spawn_egg": { + "runtime_id": 533, + "component_based": false + }, + "minecraft:iron_helmet": { + "runtime_id": 368, + "component_based": false + }, + "minecraft:iron_hoe": { + "runtime_id": 356, + "component_based": false + }, + "minecraft:iron_horse_armor": { + "runtime_id": 564, + "component_based": false + }, + "minecraft:iron_ingot": { + "runtime_id": 329, + "component_based": false + }, + "minecraft:iron_leggings": { + "runtime_id": 370, + "component_based": false + }, + "minecraft:iron_nugget": { + "runtime_id": 602, + "component_based": false + }, + "minecraft:iron_ore": { + "runtime_id": 15, + "component_based": false + }, + "minecraft:iron_pickaxe": { + "runtime_id": 321, + "component_based": false + }, + "minecraft:iron_shovel": { + "runtime_id": 320, + "component_based": false + }, + "minecraft:iron_sword": { + "runtime_id": 331, + "component_based": false + }, + "minecraft:iron_trapdoor": { + "runtime_id": 167, + "component_based": false + }, + "minecraft:item.acacia_door": { + "runtime_id": 196, + "component_based": false + }, + "minecraft:item.bed": { + "runtime_id": 26, + "component_based": false + }, + "minecraft:item.beetroot": { + "runtime_id": 244, + "component_based": false + }, + "minecraft:item.birch_door": { + "runtime_id": 194, + "component_based": false + }, + "minecraft:item.brewing_stand": { + "runtime_id": 117, + "component_based": false + }, + "minecraft:item.cake": { + "runtime_id": 92, + "component_based": false + }, + "minecraft:item.camera": { + "runtime_id": 242, + "component_based": false + }, + "minecraft:item.campfire": { + "runtime_id": -209, + "component_based": false + }, + "minecraft:item.cauldron": { + "runtime_id": 118, + "component_based": false + }, + "minecraft:item.chain": { + "runtime_id": -286, + "component_based": false + }, + "minecraft:item.crimson_door": { + "runtime_id": -244, + "component_based": false + }, + "minecraft:item.dark_oak_door": { + "runtime_id": 197, + "component_based": false + }, + "minecraft:item.flower_pot": { + "runtime_id": 140, + "component_based": false + }, + "minecraft:item.frame": { + "runtime_id": 199, + "component_based": false + }, + "minecraft:item.glow_frame": { + "runtime_id": -339, + "component_based": false + }, + "minecraft:item.hopper": { + "runtime_id": 154, + "component_based": false + }, + "minecraft:item.iron_door": { + "runtime_id": 71, + "component_based": false + }, + "minecraft:item.jungle_door": { + "runtime_id": 195, + "component_based": false + }, + "minecraft:item.kelp": { + "runtime_id": -138, + "component_based": false + }, + "minecraft:item.mangrove_door": { + "runtime_id": -493, + "component_based": false + }, + "minecraft:item.nether_sprouts": { + "runtime_id": -238, + "component_based": false + }, + "minecraft:item.nether_wart": { + "runtime_id": 115, + "component_based": false + }, + "minecraft:item.reeds": { + "runtime_id": 83, + "component_based": false + }, + "minecraft:item.soul_campfire": { + "runtime_id": -290, + "component_based": false + }, + "minecraft:item.spruce_door": { + "runtime_id": 193, + "component_based": false + }, + "minecraft:item.warped_door": { + "runtime_id": -245, + "component_based": false + }, + "minecraft:item.wheat": { + "runtime_id": 59, + "component_based": false + }, + "minecraft:item.wooden_door": { + "runtime_id": 64, + "component_based": false + }, + "minecraft:jigsaw": { + "runtime_id": -211, + "component_based": false + }, + "minecraft:jukebox": { + "runtime_id": 84, + "component_based": false + }, + "minecraft:jungle_boat": { + "runtime_id": 403, + "component_based": false + }, + "minecraft:jungle_button": { + "runtime_id": -143, + "component_based": false + }, + "minecraft:jungle_chest_boat": { + "runtime_id": 677, + "component_based": false + }, + "minecraft:jungle_door": { + "runtime_id": 588, + "component_based": false + }, + "minecraft:jungle_double_slab": { + "runtime_id": -811, + "component_based": false + }, + "minecraft:jungle_fence": { + "runtime_id": -578, + "component_based": false + }, + "minecraft:jungle_fence_gate": { + "runtime_id": 185, + "component_based": false + }, + "minecraft:jungle_hanging_sign": { + "runtime_id": -503, + "component_based": false + }, + "minecraft:jungle_leaves": { + "runtime_id": -802, + "component_based": false + }, + "minecraft:jungle_log": { + "runtime_id": -571, + "component_based": false + }, + "minecraft:jungle_planks": { + "runtime_id": -741, + "component_based": false + }, + "minecraft:jungle_pressure_plate": { + "runtime_id": -153, + "component_based": false + }, + "minecraft:jungle_sapling": { + "runtime_id": -827, + "component_based": false + }, + "minecraft:jungle_sign": { + "runtime_id": 611, + "component_based": false + }, + "minecraft:jungle_slab": { + "runtime_id": -806, + "component_based": false + }, + "minecraft:jungle_stairs": { + "runtime_id": 136, + "component_based": false + }, + "minecraft:jungle_standing_sign": { + "runtime_id": -188, + "component_based": false + }, + "minecraft:jungle_trapdoor": { + "runtime_id": -148, + "component_based": false + }, + "minecraft:jungle_wall_sign": { + "runtime_id": -189, + "component_based": false + }, + "minecraft:jungle_wood": { + "runtime_id": -816, + "component_based": false + }, + "minecraft:kelp": { + "runtime_id": 408, + "component_based": true + }, + "minecraft:lab_table": { + "runtime_id": -988, + "component_based": false + }, + "minecraft:ladder": { + "runtime_id": 65, + "component_based": false + }, + "minecraft:lantern": { + "runtime_id": -208, + "component_based": false + }, + "minecraft:lapis_block": { + "runtime_id": 22, + "component_based": false + }, + "minecraft:lapis_lazuli": { + "runtime_id": 440, + "component_based": false + }, + "minecraft:lapis_ore": { + "runtime_id": 21, + "component_based": false + }, + "minecraft:large_amethyst_bud": { + "runtime_id": -330, + "component_based": false + }, + "minecraft:large_fern": { + "runtime_id": -865, + "component_based": false + }, + "minecraft:lava": { + "runtime_id": 11, + "component_based": false + }, + "minecraft:lava_bucket": { + "runtime_id": 388, + "component_based": false + }, + "minecraft:lead": { + "runtime_id": 580, + "component_based": false + }, + "minecraft:leather": { + "runtime_id": 407, + "component_based": false + }, + "minecraft:leather_boots": { + "runtime_id": 363, + "component_based": false + }, + "minecraft:leather_chestplate": { + "runtime_id": 361, + "component_based": false + }, + "minecraft:leather_helmet": { + "runtime_id": 360, + "component_based": false + }, + "minecraft:leather_horse_armor": { + "runtime_id": 563, + "component_based": false + }, + "minecraft:leather_leggings": { + "runtime_id": 362, + "component_based": false + }, + "minecraft:leaves": { + "runtime_id": 761, + "component_based": false + }, + "minecraft:leaves2": { + "runtime_id": 762, + "component_based": false + }, + "minecraft:lectern": { + "runtime_id": -194, + "component_based": false + }, + "minecraft:lever": { + "runtime_id": 69, + "component_based": false + }, + "minecraft:light_block": { + "runtime_id": 785, + "component_based": false + }, + "minecraft:light_block_0": { + "runtime_id": -215, + "component_based": false + }, + "minecraft:light_block_1": { + "runtime_id": -929, + "component_based": false + }, + "minecraft:light_block_10": { + "runtime_id": -938, + "component_based": false + }, + "minecraft:light_block_11": { + "runtime_id": -939, + "component_based": false + }, + "minecraft:light_block_12": { + "runtime_id": -940, + "component_based": false + }, + "minecraft:light_block_13": { + "runtime_id": -941, + "component_based": false + }, + "minecraft:light_block_14": { + "runtime_id": -942, + "component_based": false + }, + "minecraft:light_block_15": { + "runtime_id": -943, + "component_based": false + }, + "minecraft:light_block_2": { + "runtime_id": -930, + "component_based": false + }, + "minecraft:light_block_3": { + "runtime_id": -931, + "component_based": false + }, + "minecraft:light_block_4": { + "runtime_id": -932, + "component_based": false + }, + "minecraft:light_block_5": { + "runtime_id": -933, + "component_based": false + }, + "minecraft:light_block_6": { + "runtime_id": -934, + "component_based": false + }, + "minecraft:light_block_7": { + "runtime_id": -935, + "component_based": false + }, + "minecraft:light_block_8": { + "runtime_id": -936, + "component_based": false + }, + "minecraft:light_block_9": { + "runtime_id": -937, + "component_based": false + }, + "minecraft:light_blue_bundle": { + "runtime_id": 257, + "component_based": true + }, + "minecraft:light_blue_candle": { + "runtime_id": -416, + "component_based": false + }, + "minecraft:light_blue_candle_cake": { + "runtime_id": -433, + "component_based": false + }, + "minecraft:light_blue_carpet": { + "runtime_id": -599, + "component_based": false + }, + "minecraft:light_blue_concrete": { + "runtime_id": -630, + "component_based": false + }, + "minecraft:light_blue_concrete_powder": { + "runtime_id": -711, + "component_based": false + }, + "minecraft:light_blue_dye": { + "runtime_id": 433, + "component_based": false + }, + "minecraft:light_blue_glazed_terracotta": { + "runtime_id": 223, + "component_based": false + }, + "minecraft:light_blue_shulker_box": { + "runtime_id": -615, + "component_based": false + }, + "minecraft:light_blue_stained_glass": { + "runtime_id": -675, + "component_based": false + }, + "minecraft:light_blue_stained_glass_pane": { + "runtime_id": -645, + "component_based": false + }, + "minecraft:light_blue_terracotta": { + "runtime_id": -726, + "component_based": false + }, + "minecraft:light_blue_wool": { + "runtime_id": -562, + "component_based": false + }, + "minecraft:light_gray_bundle": { + "runtime_id": 273, + "component_based": true + }, + "minecraft:light_gray_candle": { + "runtime_id": -421, + "component_based": false + }, + "minecraft:light_gray_candle_cake": { + "runtime_id": -438, + "component_based": false + }, + "minecraft:light_gray_carpet": { + "runtime_id": -604, + "component_based": false + }, + "minecraft:light_gray_concrete": { + "runtime_id": -635, + "component_based": false + }, + "minecraft:light_gray_concrete_powder": { + "runtime_id": -716, + "component_based": false + }, + "minecraft:light_gray_dye": { + "runtime_id": 428, + "component_based": false + }, + "minecraft:light_gray_shulker_box": { + "runtime_id": -620, + "component_based": false + }, + "minecraft:light_gray_stained_glass": { + "runtime_id": -680, + "component_based": false + }, + "minecraft:light_gray_stained_glass_pane": { + "runtime_id": -650, + "component_based": false + }, + "minecraft:light_gray_terracotta": { + "runtime_id": -731, + "component_based": false + }, + "minecraft:light_gray_wool": { + "runtime_id": -552, + "component_based": false + }, + "minecraft:light_weighted_pressure_plate": { + "runtime_id": 147, + "component_based": false + }, + "minecraft:lightning_rod": { + "runtime_id": -312, + "component_based": false + }, + "minecraft:lilac": { + "runtime_id": -863, + "component_based": false + }, + "minecraft:lily_of_the_valley": { + "runtime_id": -839, + "component_based": false + }, + "minecraft:lime_bundle": { + "runtime_id": 263, + "component_based": true + }, + "minecraft:lime_candle": { + "runtime_id": -418, + "component_based": false + }, + "minecraft:lime_candle_cake": { + "runtime_id": -435, + "component_based": false + }, + "minecraft:lime_carpet": { + "runtime_id": -601, + "component_based": false + }, + "minecraft:lime_concrete": { + "runtime_id": -632, + "component_based": false + }, + "minecraft:lime_concrete_powder": { + "runtime_id": -713, + "component_based": false + }, + "minecraft:lime_dye": { + "runtime_id": 431, + "component_based": false + }, + "minecraft:lime_glazed_terracotta": { + "runtime_id": 225, + "component_based": false + }, + "minecraft:lime_shulker_box": { + "runtime_id": -617, + "component_based": false + }, + "minecraft:lime_stained_glass": { + "runtime_id": -677, + "component_based": false + }, + "minecraft:lime_stained_glass_pane": { + "runtime_id": -647, + "component_based": false + }, + "minecraft:lime_terracotta": { + "runtime_id": -728, + "component_based": false + }, + "minecraft:lime_wool": { + "runtime_id": -559, + "component_based": false + }, + "minecraft:lingering_potion": { + "runtime_id": 595, + "component_based": false + }, + "minecraft:lit_blast_furnace": { + "runtime_id": -214, + "component_based": false + }, + "minecraft:lit_deepslate_redstone_ore": { + "runtime_id": -404, + "component_based": false + }, + "minecraft:lit_furnace": { + "runtime_id": 62, + "component_based": false + }, + "minecraft:lit_pumpkin": { + "runtime_id": 91, + "component_based": false + }, + "minecraft:lit_redstone_lamp": { + "runtime_id": 124, + "component_based": false + }, + "minecraft:lit_redstone_ore": { + "runtime_id": 74, + "component_based": false + }, + "minecraft:lit_smoker": { + "runtime_id": -199, + "component_based": false + }, + "minecraft:llama_spawn_egg": { + "runtime_id": 501, + "component_based": false + }, + "minecraft:lodestone": { + "runtime_id": -222, + "component_based": false + }, + "minecraft:lodestone_compass": { + "runtime_id": 639, + "component_based": false + }, + "minecraft:log": { + "runtime_id": 746, + "component_based": false + }, + "minecraft:log2": { + "runtime_id": 769, + "component_based": false + }, + "minecraft:loom": { + "runtime_id": -204, + "component_based": false + }, + "minecraft:mace": { + "runtime_id": 344, + "component_based": false + }, + "minecraft:magenta_bundle": { + "runtime_id": 271, + "component_based": true + }, + "minecraft:magenta_candle": { + "runtime_id": -415, + "component_based": false + }, + "minecraft:magenta_candle_cake": { + "runtime_id": -432, + "component_based": false + }, + "minecraft:magenta_carpet": { + "runtime_id": -598, + "component_based": false + }, + "minecraft:magenta_concrete": { + "runtime_id": -629, + "component_based": false + }, + "minecraft:magenta_concrete_powder": { + "runtime_id": -710, + "component_based": false + }, + "minecraft:magenta_dye": { + "runtime_id": 434, + "component_based": false + }, + "minecraft:magenta_glazed_terracotta": { + "runtime_id": 222, + "component_based": false + }, + "minecraft:magenta_shulker_box": { + "runtime_id": -614, + "component_based": false + }, + "minecraft:magenta_stained_glass": { + "runtime_id": -674, + "component_based": false + }, + "minecraft:magenta_stained_glass_pane": { + "runtime_id": -644, + "component_based": false + }, + "minecraft:magenta_terracotta": { + "runtime_id": -725, + "component_based": false + }, + "minecraft:magenta_wool": { + "runtime_id": -565, + "component_based": false + }, + "minecraft:magma": { + "runtime_id": 213, + "component_based": false + }, + "minecraft:magma_cream": { + "runtime_id": 457, + "component_based": false + }, + "minecraft:magma_cube_spawn_egg": { + "runtime_id": 482, + "component_based": false + }, + "minecraft:mangrove_boat": { + "runtime_id": 672, + "component_based": false + }, + "minecraft:mangrove_button": { + "runtime_id": -487, + "component_based": false + }, + "minecraft:mangrove_chest_boat": { + "runtime_id": 681, + "component_based": false + }, + "minecraft:mangrove_door": { + "runtime_id": 670, + "component_based": false + }, + "minecraft:mangrove_double_slab": { + "runtime_id": -499, + "component_based": false + }, + "minecraft:mangrove_fence": { + "runtime_id": -491, + "component_based": false + }, + "minecraft:mangrove_fence_gate": { + "runtime_id": -492, + "component_based": false + }, + "minecraft:mangrove_hanging_sign": { + "runtime_id": -508, + "component_based": false + }, + "minecraft:mangrove_leaves": { + "runtime_id": -472, + "component_based": false + }, + "minecraft:mangrove_log": { + "runtime_id": -484, + "component_based": false + }, + "minecraft:mangrove_planks": { + "runtime_id": -486, + "component_based": false + }, + "minecraft:mangrove_pressure_plate": { + "runtime_id": -490, + "component_based": false + }, + "minecraft:mangrove_propagule": { + "runtime_id": -474, + "component_based": false + }, + "minecraft:mangrove_roots": { + "runtime_id": -482, + "component_based": false + }, + "minecraft:mangrove_sign": { + "runtime_id": 671, + "component_based": false + }, + "minecraft:mangrove_slab": { + "runtime_id": -489, + "component_based": false + }, + "minecraft:mangrove_stairs": { + "runtime_id": -488, + "component_based": false + }, + "minecraft:mangrove_standing_sign": { + "runtime_id": -494, + "component_based": false + }, + "minecraft:mangrove_trapdoor": { + "runtime_id": -496, + "component_based": false + }, + "minecraft:mangrove_wall_sign": { + "runtime_id": -495, + "component_based": false + }, + "minecraft:mangrove_wood": { + "runtime_id": -497, + "component_based": false + }, + "minecraft:material_reducer": { + "runtime_id": -986, + "component_based": false + }, + "minecraft:medicine": { + "runtime_id": 636, + "component_based": false + }, + "minecraft:medium_amethyst_bud": { + "runtime_id": -331, + "component_based": false + }, + "minecraft:melon_block": { + "runtime_id": 103, + "component_based": false + }, + "minecraft:melon_seeds": { + "runtime_id": 315, + "component_based": false + }, + "minecraft:melon_slice": { + "runtime_id": 294, + "component_based": false + }, + "minecraft:melon_stem": { + "runtime_id": 105, + "component_based": false + }, + "minecraft:milk_bucket": { + "runtime_id": 386, + "component_based": false + }, + "minecraft:minecart": { + "runtime_id": 395, + "component_based": false + }, + "minecraft:miner_pottery_sherd": { + "runtime_id": 707, + "component_based": false + }, + "minecraft:mob_spawner": { + "runtime_id": 52, + "component_based": false + }, + "minecraft:mojang_banner_pattern": { + "runtime_id": 617, + "component_based": false + }, + "minecraft:monster_egg": { + "runtime_id": 770, + "component_based": false + }, + "minecraft:mooshroom_spawn_egg": { + "runtime_id": 467, + "component_based": false + }, + "minecraft:moss_block": { + "runtime_id": -320, + "component_based": false + }, + "minecraft:moss_carpet": { + "runtime_id": -335, + "component_based": false + }, + "minecraft:mossy_cobblestone": { + "runtime_id": 48, + "component_based": false + }, + "minecraft:mossy_cobblestone_double_slab": { + "runtime_id": -915, + "component_based": false + }, + "minecraft:mossy_cobblestone_slab": { + "runtime_id": -888, + "component_based": false + }, + "minecraft:mossy_cobblestone_stairs": { + "runtime_id": -179, + "component_based": false + }, + "minecraft:mossy_cobblestone_wall": { + "runtime_id": -971, + "component_based": false + }, + "minecraft:mossy_stone_brick_double_slab": { + "runtime_id": -168, + "component_based": false + }, + "minecraft:mossy_stone_brick_slab": { + "runtime_id": -166, + "component_based": false + }, + "minecraft:mossy_stone_brick_stairs": { + "runtime_id": -175, + "component_based": false + }, + "minecraft:mossy_stone_brick_wall": { + "runtime_id": -978, + "component_based": false + }, + "minecraft:mossy_stone_bricks": { + "runtime_id": -868, + "component_based": false + }, + "minecraft:mourner_pottery_sherd": { + "runtime_id": 708, + "component_based": false + }, + "minecraft:moving_block": { + "runtime_id": 250, + "component_based": false + }, + "minecraft:mud": { + "runtime_id": -473, + "component_based": false + }, + "minecraft:mud_brick_double_slab": { + "runtime_id": -479, + "component_based": false + }, + "minecraft:mud_brick_slab": { + "runtime_id": -478, + "component_based": false + }, + "minecraft:mud_brick_stairs": { + "runtime_id": -480, + "component_based": false + }, + "minecraft:mud_brick_wall": { + "runtime_id": -481, + "component_based": false + }, + "minecraft:mud_bricks": { + "runtime_id": -475, + "component_based": false + }, + "minecraft:muddy_mangrove_roots": { + "runtime_id": -483, + "component_based": false + }, + "minecraft:mule_spawn_egg": { + "runtime_id": 494, + "component_based": false + }, + "minecraft:mushroom_stem": { + "runtime_id": -1008, + "component_based": false + }, + "minecraft:mushroom_stew": { + "runtime_id": 282, + "component_based": false + }, + "minecraft:music_disc_11": { + "runtime_id": 577, + "component_based": true + }, + "minecraft:music_disc_13": { + "runtime_id": 567, + "component_based": true + }, + "minecraft:music_disc_5": { + "runtime_id": 673, + "component_based": true + }, + "minecraft:music_disc_blocks": { + "runtime_id": 569, + "component_based": true + }, + "minecraft:music_disc_cat": { + "runtime_id": 568, + "component_based": true + }, + "minecraft:music_disc_chirp": { + "runtime_id": 570, + "component_based": true + }, + "minecraft:music_disc_creator": { + "runtime_id": 777, + "component_based": true + }, + "minecraft:music_disc_creator_music_box": { + "runtime_id": 778, + "component_based": true + }, + "minecraft:music_disc_far": { + "runtime_id": 571, + "component_based": true + }, + "minecraft:music_disc_mall": { + "runtime_id": 572, + "component_based": true + }, + "minecraft:music_disc_mellohi": { + "runtime_id": 573, + "component_based": true + }, + "minecraft:music_disc_otherside": { + "runtime_id": 663, + "component_based": true + }, + "minecraft:music_disc_pigstep": { + "runtime_id": 657, + "component_based": true + }, + "minecraft:music_disc_precipice": { + "runtime_id": 779, + "component_based": true + }, + "minecraft:music_disc_relic": { + "runtime_id": 736, + "component_based": true + }, + "minecraft:music_disc_stal": { + "runtime_id": 574, + "component_based": true + }, + "minecraft:music_disc_strad": { + "runtime_id": 575, + "component_based": true + }, + "minecraft:music_disc_wait": { + "runtime_id": 578, + "component_based": true + }, + "minecraft:music_disc_ward": { + "runtime_id": 576, + "component_based": true + }, + "minecraft:mutton": { + "runtime_id": 583, + "component_based": false + }, + "minecraft:mycelium": { + "runtime_id": 110, + "component_based": false + }, + "minecraft:name_tag": { + "runtime_id": 581, + "component_based": false + }, + "minecraft:nautilus_shell": { + "runtime_id": 603, + "component_based": false + }, + "minecraft:nether_brick": { + "runtime_id": 112, + "component_based": false + }, + "minecraft:nether_brick_double_slab": { + "runtime_id": -883, + "component_based": false + }, + "minecraft:nether_brick_fence": { + "runtime_id": 113, + "component_based": false + }, + "minecraft:nether_brick_slab": { + "runtime_id": -877, + "component_based": false + }, + "minecraft:nether_brick_stairs": { + "runtime_id": 114, + "component_based": false + }, + "minecraft:nether_brick_wall": { + "runtime_id": -979, + "component_based": false + }, + "minecraft:nether_gold_ore": { + "runtime_id": -288, + "component_based": false + }, + "minecraft:nether_sprouts": { + "runtime_id": 658, + "component_based": true + }, + "minecraft:nether_star": { + "runtime_id": 551, + "component_based": false + }, + "minecraft:nether_wart": { + "runtime_id": 316, + "component_based": false + }, + "minecraft:nether_wart_block": { + "runtime_id": 214, + "component_based": false + }, + "minecraft:netherbrick": { + "runtime_id": 556, + "component_based": false + }, + "minecraft:netherite_axe": { + "runtime_id": 643, + "component_based": false + }, + "minecraft:netherite_block": { + "runtime_id": -270, + "component_based": false + }, + "minecraft:netherite_boots": { + "runtime_id": 649, + "component_based": false + }, + "minecraft:netherite_chestplate": { + "runtime_id": 647, + "component_based": false + }, + "minecraft:netherite_helmet": { + "runtime_id": 646, + "component_based": false + }, + "minecraft:netherite_hoe": { + "runtime_id": 644, + "component_based": false + }, + "minecraft:netherite_ingot": { + "runtime_id": 645, + "component_based": false + }, + "minecraft:netherite_leggings": { + "runtime_id": 648, + "component_based": false + }, + "minecraft:netherite_pickaxe": { + "runtime_id": 642, + "component_based": false + }, + "minecraft:netherite_scrap": { + "runtime_id": 650, + "component_based": false + }, + "minecraft:netherite_shovel": { + "runtime_id": 641, + "component_based": false + }, + "minecraft:netherite_sword": { + "runtime_id": 640, + "component_based": false + }, + "minecraft:netherite_upgrade_smithing_template": { + "runtime_id": 717, + "component_based": false + }, + "minecraft:netherrack": { + "runtime_id": 87, + "component_based": false + }, + "minecraft:netherreactor": { + "runtime_id": 247, + "component_based": false + }, + "minecraft:normal_stone_double_slab": { + "runtime_id": -926, + "component_based": false + }, + "minecraft:normal_stone_slab": { + "runtime_id": -899, + "component_based": false + }, + "minecraft:normal_stone_stairs": { + "runtime_id": -180, + "component_based": false + }, + "minecraft:noteblock": { + "runtime_id": 25, + "component_based": false + }, + "minecraft:npc_spawn_egg": { + "runtime_id": 498, + "component_based": false + }, + "minecraft:oak_boat": { + "runtime_id": 401, + "component_based": false + }, + "minecraft:oak_chest_boat": { + "runtime_id": 675, + "component_based": false + }, + "minecraft:oak_double_slab": { + "runtime_id": 157, + "component_based": false + }, + "minecraft:oak_fence": { + "runtime_id": 85, + "component_based": false + }, + "minecraft:oak_hanging_sign": { + "runtime_id": -500, + "component_based": false + }, + "minecraft:oak_leaves": { + "runtime_id": 18, + "component_based": false + }, + "minecraft:oak_log": { + "runtime_id": 17, + "component_based": false + }, + "minecraft:oak_planks": { + "runtime_id": 5, + "component_based": false + }, + "minecraft:oak_sapling": { + "runtime_id": 6, + "component_based": false + }, + "minecraft:oak_sign": { + "runtime_id": 383, + "component_based": false + }, + "minecraft:oak_slab": { + "runtime_id": 158, + "component_based": false + }, + "minecraft:oak_stairs": { + "runtime_id": 53, + "component_based": false + }, + "minecraft:oak_wood": { + "runtime_id": -212, + "component_based": false + }, + "minecraft:observer": { + "runtime_id": 251, + "component_based": false + }, + "minecraft:obsidian": { + "runtime_id": 49, + "component_based": false + }, + "minecraft:ocelot_spawn_egg": { + "runtime_id": 478, + "component_based": false + }, + "minecraft:ochre_froglight": { + "runtime_id": -471, + "component_based": false + }, + "minecraft:ominous_bottle": { + "runtime_id": 629, + "component_based": false + }, + "minecraft:ominous_trial_key": { + "runtime_id": 276, + "component_based": true + }, + "minecraft:orange_bundle": { + "runtime_id": 258, + "component_based": true + }, + "minecraft:orange_candle": { + "runtime_id": -414, + "component_based": false + }, + "minecraft:orange_candle_cake": { + "runtime_id": -431, + "component_based": false + }, + "minecraft:orange_carpet": { + "runtime_id": -597, + "component_based": false + }, + "minecraft:orange_concrete": { + "runtime_id": -628, + "component_based": false + }, + "minecraft:orange_concrete_powder": { + "runtime_id": -709, + "component_based": false + }, + "minecraft:orange_dye": { + "runtime_id": 435, + "component_based": false + }, + "minecraft:orange_glazed_terracotta": { + "runtime_id": 221, + "component_based": false + }, + "minecraft:orange_shulker_box": { + "runtime_id": -613, + "component_based": false + }, + "minecraft:orange_stained_glass": { + "runtime_id": -673, + "component_based": false + }, + "minecraft:orange_stained_glass_pane": { + "runtime_id": -643, + "component_based": false + }, + "minecraft:orange_terracotta": { + "runtime_id": -724, + "component_based": false + }, + "minecraft:orange_tulip": { + "runtime_id": -834, + "component_based": false + }, + "minecraft:orange_wool": { + "runtime_id": -557, + "component_based": false + }, + "minecraft:oxeye_daisy": { + "runtime_id": -837, + "component_based": false + }, + "minecraft:oxidized_chiseled_copper": { + "runtime_id": -763, + "component_based": false + }, + "minecraft:oxidized_copper": { + "runtime_id": -343, + "component_based": false + }, + "minecraft:oxidized_copper_bulb": { + "runtime_id": -779, + "component_based": false + }, + "minecraft:oxidized_copper_door": { + "runtime_id": -787, + "component_based": false + }, + "minecraft:oxidized_copper_grate": { + "runtime_id": -771, + "component_based": false + }, + "minecraft:oxidized_copper_trapdoor": { + "runtime_id": -795, + "component_based": false + }, + "minecraft:oxidized_cut_copper": { + "runtime_id": -350, + "component_based": false + }, + "minecraft:oxidized_cut_copper_slab": { + "runtime_id": -364, + "component_based": false + }, + "minecraft:oxidized_cut_copper_stairs": { + "runtime_id": -357, + "component_based": false + }, + "minecraft:oxidized_double_cut_copper_slab": { + "runtime_id": -371, + "component_based": false + }, + "minecraft:packed_ice": { + "runtime_id": 174, + "component_based": false + }, + "minecraft:packed_mud": { + "runtime_id": -477, + "component_based": false + }, + "minecraft:painting": { + "runtime_id": 382, + "component_based": false + }, + "minecraft:panda_spawn_egg": { + "runtime_id": 517, + "component_based": false + }, + "minecraft:paper": { + "runtime_id": 412, + "component_based": false + }, + "minecraft:parrot_spawn_egg": { + "runtime_id": 506, + "component_based": false + }, + "minecraft:pearlescent_froglight": { + "runtime_id": -469, + "component_based": false + }, + "minecraft:peony": { + "runtime_id": -867, + "component_based": false + }, + "minecraft:petrified_oak_double_slab": { + "runtime_id": -903, + "component_based": false + }, + "minecraft:petrified_oak_slab": { + "runtime_id": -902, + "component_based": false + }, + "minecraft:phantom_membrane": { + "runtime_id": 607, + "component_based": false + }, + "minecraft:phantom_spawn_egg": { + "runtime_id": 514, + "component_based": false + }, + "minecraft:pig_spawn_egg": { + "runtime_id": 464, + "component_based": false + }, + "minecraft:piglin_banner_pattern": { + "runtime_id": 620, + "component_based": false + }, + "minecraft:piglin_brute_spawn_egg": { + "runtime_id": 527, + "component_based": false + }, + "minecraft:piglin_head": { + "runtime_id": -970, + "component_based": false + }, + "minecraft:piglin_spawn_egg": { + "runtime_id": 525, + "component_based": false + }, + "minecraft:pillager_spawn_egg": { + "runtime_id": 519, + "component_based": false + }, + "minecraft:pink_bundle": { + "runtime_id": 272, + "component_based": true + }, + "minecraft:pink_candle": { + "runtime_id": -419, + "component_based": false + }, + "minecraft:pink_candle_cake": { + "runtime_id": -436, + "component_based": false + }, + "minecraft:pink_carpet": { + "runtime_id": -602, + "component_based": false + }, + "minecraft:pink_concrete": { + "runtime_id": -633, + "component_based": false + }, + "minecraft:pink_concrete_powder": { + "runtime_id": -714, + "component_based": false + }, + "minecraft:pink_dye": { + "runtime_id": 430, + "component_based": false + }, + "minecraft:pink_glazed_terracotta": { + "runtime_id": 226, + "component_based": false + }, + "minecraft:pink_petals": { + "runtime_id": -549, + "component_based": false + }, + "minecraft:pink_shulker_box": { + "runtime_id": -618, + "component_based": false + }, + "minecraft:pink_stained_glass": { + "runtime_id": -678, + "component_based": false + }, + "minecraft:pink_stained_glass_pane": { + "runtime_id": -648, + "component_based": false + }, + "minecraft:pink_terracotta": { + "runtime_id": -729, + "component_based": false + }, + "minecraft:pink_tulip": { + "runtime_id": -836, + "component_based": false + }, + "minecraft:pink_wool": { + "runtime_id": -566, + "component_based": false + }, + "minecraft:piston": { + "runtime_id": 33, + "component_based": false + }, + "minecraft:piston_arm_collision": { + "runtime_id": 34, + "component_based": false + }, + "minecraft:pitcher_crop": { + "runtime_id": -574, + "component_based": false + }, + "minecraft:pitcher_plant": { + "runtime_id": -612, + "component_based": false + }, + "minecraft:pitcher_pod": { + "runtime_id": 319, + "component_based": false + }, + "minecraft:planks": { + "runtime_id": 766, + "component_based": false + }, + "minecraft:player_head": { + "runtime_id": -967, + "component_based": false + }, + "minecraft:plenty_pottery_sherd": { + "runtime_id": 709, + "component_based": false + }, + "minecraft:podzol": { + "runtime_id": 243, + "component_based": false + }, + "minecraft:pointed_dripstone": { + "runtime_id": -308, + "component_based": false + }, + "minecraft:poisonous_potato": { + "runtime_id": 304, + "component_based": false + }, + "minecraft:polar_bear_spawn_egg": { + "runtime_id": 500, + "component_based": false + }, + "minecraft:polished_andesite": { + "runtime_id": -595, + "component_based": false + }, + "minecraft:polished_andesite_double_slab": { + "runtime_id": -919, + "component_based": false + }, + "minecraft:polished_andesite_slab": { + "runtime_id": -892, + "component_based": false + }, + "minecraft:polished_andesite_stairs": { + "runtime_id": -174, + "component_based": false + }, + "minecraft:polished_basalt": { + "runtime_id": -235, + "component_based": false + }, + "minecraft:polished_blackstone": { + "runtime_id": -291, + "component_based": false + }, + "minecraft:polished_blackstone_brick_double_slab": { + "runtime_id": -285, + "component_based": false + }, + "minecraft:polished_blackstone_brick_slab": { + "runtime_id": -284, + "component_based": false + }, + "minecraft:polished_blackstone_brick_stairs": { + "runtime_id": -275, + "component_based": false + }, + "minecraft:polished_blackstone_brick_wall": { + "runtime_id": -278, + "component_based": false + }, + "minecraft:polished_blackstone_bricks": { + "runtime_id": -274, + "component_based": false + }, + "minecraft:polished_blackstone_button": { + "runtime_id": -296, + "component_based": false + }, + "minecraft:polished_blackstone_double_slab": { + "runtime_id": -294, + "component_based": false + }, + "minecraft:polished_blackstone_pressure_plate": { + "runtime_id": -295, + "component_based": false + }, + "minecraft:polished_blackstone_slab": { + "runtime_id": -293, + "component_based": false + }, + "minecraft:polished_blackstone_stairs": { + "runtime_id": -292, + "component_based": false + }, + "minecraft:polished_blackstone_wall": { + "runtime_id": -297, + "component_based": false + }, + "minecraft:polished_deepslate": { + "runtime_id": -383, + "component_based": false + }, + "minecraft:polished_deepslate_double_slab": { + "runtime_id": -397, + "component_based": false + }, + "minecraft:polished_deepslate_slab": { + "runtime_id": -384, + "component_based": false + }, + "minecraft:polished_deepslate_stairs": { + "runtime_id": -385, + "component_based": false + }, + "minecraft:polished_deepslate_wall": { + "runtime_id": -386, + "component_based": false + }, + "minecraft:polished_diorite": { + "runtime_id": -593, + "component_based": false + }, + "minecraft:polished_diorite_double_slab": { + "runtime_id": -922, + "component_based": false + }, + "minecraft:polished_diorite_slab": { + "runtime_id": -895, + "component_based": false + }, + "minecraft:polished_diorite_stairs": { + "runtime_id": -173, + "component_based": false + }, + "minecraft:polished_granite": { + "runtime_id": -591, + "component_based": false + }, + "minecraft:polished_granite_double_slab": { + "runtime_id": -924, + "component_based": false + }, + "minecraft:polished_granite_slab": { + "runtime_id": -897, + "component_based": false + }, + "minecraft:polished_granite_stairs": { + "runtime_id": -172, + "component_based": false + }, + "minecraft:polished_tuff": { + "runtime_id": -748, + "component_based": false + }, + "minecraft:polished_tuff_double_slab": { + "runtime_id": -750, + "component_based": false + }, + "minecraft:polished_tuff_slab": { + "runtime_id": -749, + "component_based": false + }, + "minecraft:polished_tuff_stairs": { + "runtime_id": -751, + "component_based": false + }, + "minecraft:polished_tuff_wall": { + "runtime_id": -752, + "component_based": false + }, + "minecraft:popped_chorus_fruit": { + "runtime_id": 592, + "component_based": false + }, + "minecraft:poppy": { + "runtime_id": 38, + "component_based": false + }, + "minecraft:porkchop": { + "runtime_id": 284, + "component_based": false + }, + "minecraft:portal": { + "runtime_id": 90, + "component_based": false + }, + "minecraft:potato": { + "runtime_id": 302, + "component_based": false + }, + "minecraft:potatoes": { + "runtime_id": 142, + "component_based": false + }, + "minecraft:potion": { + "runtime_id": 453, + "component_based": false + }, + "minecraft:powder_snow": { + "runtime_id": -306, + "component_based": false + }, + "minecraft:powder_snow_bucket": { + "runtime_id": 393, + "component_based": false + }, + "minecraft:powered_comparator": { + "runtime_id": 150, + "component_based": false + }, + "minecraft:powered_repeater": { + "runtime_id": 94, + "component_based": false + }, + "minecraft:prismarine": { + "runtime_id": 168, + "component_based": false + }, + "minecraft:prismarine_brick_double_slab": { + "runtime_id": -914, + "component_based": false + }, + "minecraft:prismarine_brick_slab": { + "runtime_id": -887, + "component_based": false + }, + "minecraft:prismarine_bricks": { + "runtime_id": -948, + "component_based": false + }, + "minecraft:prismarine_bricks_stairs": { + "runtime_id": -4, + "component_based": false + }, + "minecraft:prismarine_crystals": { + "runtime_id": 582, + "component_based": false + }, + "minecraft:prismarine_double_slab": { + "runtime_id": -912, + "component_based": false + }, + "minecraft:prismarine_shard": { + "runtime_id": 598, + "component_based": false + }, + "minecraft:prismarine_slab": { + "runtime_id": -885, + "component_based": false + }, + "minecraft:prismarine_stairs": { + "runtime_id": -2, + "component_based": false + }, + "minecraft:prismarine_wall": { + "runtime_id": -981, + "component_based": false + }, + "minecraft:prize_pottery_sherd": { + "runtime_id": 710, + "component_based": false + }, + "minecraft:pufferfish": { + "runtime_id": 289, + "component_based": false + }, + "minecraft:pufferfish_bucket": { + "runtime_id": 392, + "component_based": false + }, + "minecraft:pufferfish_spawn_egg": { + "runtime_id": 509, + "component_based": false + }, + "minecraft:pumpkin": { + "runtime_id": 86, + "component_based": false + }, + "minecraft:pumpkin_pie": { + "runtime_id": 306, + "component_based": false + }, + "minecraft:pumpkin_seeds": { + "runtime_id": 314, + "component_based": false + }, + "minecraft:pumpkin_stem": { + "runtime_id": 104, + "component_based": false + }, + "minecraft:purple_bundle": { + "runtime_id": 270, + "component_based": true + }, + "minecraft:purple_candle": { + "runtime_id": -423, + "component_based": false + }, + "minecraft:purple_candle_cake": { + "runtime_id": -440, + "component_based": false + }, + "minecraft:purple_carpet": { + "runtime_id": -606, + "component_based": false + }, + "minecraft:purple_concrete": { + "runtime_id": -637, + "component_based": false + }, + "minecraft:purple_concrete_powder": { + "runtime_id": -718, + "component_based": false + }, + "minecraft:purple_dye": { + "runtime_id": 426, + "component_based": false + }, + "minecraft:purple_glazed_terracotta": { + "runtime_id": 219, + "component_based": false + }, + "minecraft:purple_shulker_box": { + "runtime_id": -622, + "component_based": false + }, + "minecraft:purple_stained_glass": { + "runtime_id": -682, + "component_based": false + }, + "minecraft:purple_stained_glass_pane": { + "runtime_id": -652, + "component_based": false + }, + "minecraft:purple_terracotta": { + "runtime_id": -733, + "component_based": false + }, + "minecraft:purple_wool": { + "runtime_id": -564, + "component_based": false + }, + "minecraft:purpur_block": { + "runtime_id": 201, + "component_based": false + }, + "minecraft:purpur_double_slab": { + "runtime_id": -911, + "component_based": false + }, + "minecraft:purpur_pillar": { + "runtime_id": -951, + "component_based": false + }, + "minecraft:purpur_slab": { + "runtime_id": -884, + "component_based": false + }, + "minecraft:purpur_stairs": { + "runtime_id": 203, + "component_based": false + }, + "minecraft:quartz": { + "runtime_id": 557, + "component_based": false + }, + "minecraft:quartz_block": { + "runtime_id": 155, + "component_based": false + }, + "minecraft:quartz_bricks": { + "runtime_id": -304, + "component_based": false + }, + "minecraft:quartz_double_slab": { + "runtime_id": -882, + "component_based": false + }, + "minecraft:quartz_ore": { + "runtime_id": 153, + "component_based": false + }, + "minecraft:quartz_pillar": { + "runtime_id": -954, + "component_based": false + }, + "minecraft:quartz_slab": { + "runtime_id": -876, + "component_based": false + }, + "minecraft:quartz_stairs": { + "runtime_id": 156, + "component_based": false + }, + "minecraft:rabbit": { + "runtime_id": 310, + "component_based": false + }, + "minecraft:rabbit_foot": { + "runtime_id": 561, + "component_based": false + }, + "minecraft:rabbit_hide": { + "runtime_id": 562, + "component_based": false + }, + "minecraft:rabbit_spawn_egg": { + "runtime_id": 486, + "component_based": false + }, + "minecraft:rabbit_stew": { + "runtime_id": 312, + "component_based": false + }, + "minecraft:rail": { + "runtime_id": 66, + "component_based": false + }, + "minecraft:raiser_armor_trim_smithing_template": { + "runtime_id": 731, + "component_based": false + }, + "minecraft:rapid_fertilizer": { + "runtime_id": 634, + "component_based": false + }, + "minecraft:ravager_spawn_egg": { + "runtime_id": 521, + "component_based": false + }, + "minecraft:raw_copper": { + "runtime_id": 541, + "component_based": false + }, + "minecraft:raw_copper_block": { + "runtime_id": -452, + "component_based": false + }, + "minecraft:raw_gold": { + "runtime_id": 540, + "component_based": false + }, + "minecraft:raw_gold_block": { + "runtime_id": -453, + "component_based": false + }, + "minecraft:raw_iron": { + "runtime_id": 539, + "component_based": false + }, + "minecraft:raw_iron_block": { + "runtime_id": -451, + "component_based": false + }, + "minecraft:recovery_compass": { + "runtime_id": 683, + "component_based": false + }, + "minecraft:red_bundle": { + "runtime_id": 267, + "component_based": true + }, + "minecraft:red_candle": { + "runtime_id": -427, + "component_based": false + }, + "minecraft:red_candle_cake": { + "runtime_id": -444, + "component_based": false + }, + "minecraft:red_carpet": { + "runtime_id": -610, + "component_based": false + }, + "minecraft:red_concrete": { + "runtime_id": -641, + "component_based": false + }, + "minecraft:red_concrete_powder": { + "runtime_id": -722, + "component_based": false + }, + "minecraft:red_dye": { + "runtime_id": 422, + "component_based": false + }, + "minecraft:red_flower": { + "runtime_id": 764, + "component_based": false + }, + "minecraft:red_glazed_terracotta": { + "runtime_id": 234, + "component_based": false + }, + "minecraft:red_mushroom": { + "runtime_id": 40, + "component_based": false + }, + "minecraft:red_mushroom_block": { + "runtime_id": 100, + "component_based": false + }, + "minecraft:red_nether_brick": { + "runtime_id": 215, + "component_based": false + }, + "minecraft:red_nether_brick_double_slab": { + "runtime_id": -917, + "component_based": false + }, + "minecraft:red_nether_brick_slab": { + "runtime_id": -890, + "component_based": false + }, + "minecraft:red_nether_brick_stairs": { + "runtime_id": -184, + "component_based": false + }, + "minecraft:red_nether_brick_wall": { + "runtime_id": -983, + "component_based": false + }, + "minecraft:red_sand": { + "runtime_id": -949, + "component_based": false + }, + "minecraft:red_sandstone": { + "runtime_id": 179, + "component_based": false + }, + "minecraft:red_sandstone_double_slab": { + "runtime_id": 181, + "component_based": false + }, + "minecraft:red_sandstone_slab": { + "runtime_id": 182, + "component_based": false + }, + "minecraft:red_sandstone_stairs": { + "runtime_id": 180, + "component_based": false + }, + "minecraft:red_sandstone_wall": { + "runtime_id": -982, + "component_based": false + }, + "minecraft:red_shulker_box": { + "runtime_id": -626, + "component_based": false + }, + "minecraft:red_stained_glass": { + "runtime_id": -686, + "component_based": false + }, + "minecraft:red_stained_glass_pane": { + "runtime_id": -656, + "component_based": false + }, + "minecraft:red_terracotta": { + "runtime_id": -737, + "component_based": false + }, + "minecraft:red_tulip": { + "runtime_id": -833, + "component_based": false + }, + "minecraft:red_wool": { + "runtime_id": -556, + "component_based": false + }, + "minecraft:redstone": { + "runtime_id": 398, + "component_based": false + }, + "minecraft:redstone_block": { + "runtime_id": 152, + "component_based": false + }, + "minecraft:redstone_lamp": { + "runtime_id": 123, + "component_based": false + }, + "minecraft:redstone_ore": { + "runtime_id": 73, + "component_based": false + }, + "minecraft:redstone_torch": { + "runtime_id": 76, + "component_based": false + }, + "minecraft:redstone_wire": { + "runtime_id": 55, + "component_based": false + }, + "minecraft:reinforced_deepslate": { + "runtime_id": -466, + "component_based": false + }, + "minecraft:repeater": { + "runtime_id": 445, + "component_based": true + }, + "minecraft:repeating_command_block": { + "runtime_id": 188, + "component_based": false + }, + "minecraft:reserved6": { + "runtime_id": 255, + "component_based": false + }, + "minecraft:respawn_anchor": { + "runtime_id": -272, + "component_based": false + }, + "minecraft:rib_armor_trim_smithing_template": { + "runtime_id": 727, + "component_based": false + }, + "minecraft:rose_bush": { + "runtime_id": -866, + "component_based": false + }, + "minecraft:rotten_flesh": { + "runtime_id": 299, + "component_based": false + }, + "minecraft:saddle": { + "runtime_id": 396, + "component_based": false + }, + "minecraft:salmon": { + "runtime_id": 287, + "component_based": false + }, + "minecraft:salmon_bucket": { + "runtime_id": 390, + "component_based": false + }, + "minecraft:salmon_spawn_egg": { + "runtime_id": 510, + "component_based": false + }, + "minecraft:sand": { + "runtime_id": 12, + "component_based": false + }, + "minecraft:sandstone": { + "runtime_id": 24, + "component_based": false + }, + "minecraft:sandstone_double_slab": { + "runtime_id": -878, + "component_based": false + }, + "minecraft:sandstone_slab": { + "runtime_id": -872, + "component_based": false + }, + "minecraft:sandstone_stairs": { + "runtime_id": 128, + "component_based": false + }, + "minecraft:sandstone_wall": { + "runtime_id": -975, + "component_based": false + }, + "minecraft:sapling": { + "runtime_id": 760, + "component_based": false + }, + "minecraft:scaffolding": { + "runtime_id": -165, + "component_based": false + }, + "minecraft:scrape_pottery_sherd": { + "runtime_id": 711, + "component_based": false + }, + "minecraft:sculk": { + "runtime_id": -458, + "component_based": false + }, + "minecraft:sculk_catalyst": { + "runtime_id": -460, + "component_based": false + }, + "minecraft:sculk_sensor": { + "runtime_id": -307, + "component_based": false + }, + "minecraft:sculk_shrieker": { + "runtime_id": -461, + "component_based": false + }, + "minecraft:sculk_vein": { + "runtime_id": -459, + "component_based": false + }, + "minecraft:sea_lantern": { + "runtime_id": 169, + "component_based": false + }, + "minecraft:sea_pickle": { + "runtime_id": -156, + "component_based": false + }, + "minecraft:seagrass": { + "runtime_id": -130, + "component_based": false + }, + "minecraft:sentry_armor_trim_smithing_template": { + "runtime_id": 718, + "component_based": false + }, + "minecraft:shaper_armor_trim_smithing_template": { + "runtime_id": 732, + "component_based": false + }, + "minecraft:sheaf_pottery_sherd": { + "runtime_id": 712, + "component_based": false + }, + "minecraft:shears": { + "runtime_id": 447, + "component_based": false + }, + "minecraft:sheep_spawn_egg": { + "runtime_id": 465, + "component_based": false + }, + "minecraft:shelter_pottery_sherd": { + "runtime_id": 713, + "component_based": false + }, + "minecraft:shield": { + "runtime_id": 380, + "component_based": false + }, + "minecraft:short_grass": { + "runtime_id": 31, + "component_based": false + }, + "minecraft:shroomlight": { + "runtime_id": -230, + "component_based": false + }, + "minecraft:shulker_box": { + "runtime_id": 775, + "component_based": false + }, + "minecraft:shulker_shell": { + "runtime_id": 599, + "component_based": false + }, + "minecraft:shulker_spawn_egg": { + "runtime_id": 497, + "component_based": false + }, + "minecraft:silence_armor_trim_smithing_template": { + "runtime_id": 729, + "component_based": false + }, + "minecraft:silver_glazed_terracotta": { + "runtime_id": 228, + "component_based": false + }, + "minecraft:silverfish_spawn_egg": { + "runtime_id": 470, + "component_based": false + }, + "minecraft:skeleton_horse_spawn_egg": { + "runtime_id": 495, + "component_based": false + }, + "minecraft:skeleton_skull": { + "runtime_id": 144, + "component_based": false + }, + "minecraft:skeleton_spawn_egg": { + "runtime_id": 471, + "component_based": false + }, + "minecraft:skull": { + "runtime_id": 737, + "component_based": false + }, + "minecraft:skull_banner_pattern": { + "runtime_id": 616, + "component_based": false + }, + "minecraft:skull_pottery_sherd": { + "runtime_id": 714, + "component_based": false + }, + "minecraft:slime": { + "runtime_id": 165, + "component_based": false + }, + "minecraft:slime_ball": { + "runtime_id": 414, + "component_based": false + }, + "minecraft:slime_spawn_egg": { + "runtime_id": 472, + "component_based": false + }, + "minecraft:small_amethyst_bud": { + "runtime_id": -332, + "component_based": false + }, + "minecraft:small_dripleaf_block": { + "runtime_id": -336, + "component_based": false + }, + "minecraft:smithing_table": { + "runtime_id": -202, + "component_based": false + }, + "minecraft:smoker": { + "runtime_id": -198, + "component_based": false + }, + "minecraft:smooth_basalt": { + "runtime_id": -377, + "component_based": false + }, + "minecraft:smooth_quartz": { + "runtime_id": -955, + "component_based": false + }, + "minecraft:smooth_quartz_double_slab": { + "runtime_id": -925, + "component_based": false + }, + "minecraft:smooth_quartz_slab": { + "runtime_id": -898, + "component_based": false + }, + "minecraft:smooth_quartz_stairs": { + "runtime_id": -185, + "component_based": false + }, + "minecraft:smooth_red_sandstone": { + "runtime_id": -958, + "component_based": false + }, + "minecraft:smooth_red_sandstone_double_slab": { + "runtime_id": -918, + "component_based": false + }, + "minecraft:smooth_red_sandstone_slab": { + "runtime_id": -891, + "component_based": false + }, + "minecraft:smooth_red_sandstone_stairs": { + "runtime_id": -176, + "component_based": false + }, + "minecraft:smooth_sandstone": { + "runtime_id": -946, + "component_based": false + }, + "minecraft:smooth_sandstone_double_slab": { + "runtime_id": -916, + "component_based": false + }, + "minecraft:smooth_sandstone_slab": { + "runtime_id": -889, + "component_based": false + }, + "minecraft:smooth_sandstone_stairs": { + "runtime_id": -177, + "component_based": false + }, + "minecraft:smooth_stone": { + "runtime_id": -183, + "component_based": false + }, + "minecraft:smooth_stone_double_slab": { + "runtime_id": 43, + "component_based": false + }, + "minecraft:smooth_stone_slab": { + "runtime_id": 44, + "component_based": false + }, + "minecraft:sniffer_egg": { + "runtime_id": -596, + "component_based": false + }, + "minecraft:sniffer_spawn_egg": { + "runtime_id": 528, + "component_based": false + }, + "minecraft:snort_pottery_sherd": { + "runtime_id": 715, + "component_based": false + }, + "minecraft:snout_armor_trim_smithing_template": { + "runtime_id": 726, + "component_based": false + }, + "minecraft:snow": { + "runtime_id": 80, + "component_based": false + }, + "minecraft:snow_golem_spawn_egg": { + "runtime_id": 534, + "component_based": false + }, + "minecraft:snow_layer": { + "runtime_id": 78, + "component_based": false + }, + "minecraft:snowball": { + "runtime_id": 399, + "component_based": true + }, + "minecraft:soul_campfire": { + "runtime_id": 659, + "component_based": true + }, + "minecraft:soul_fire": { + "runtime_id": -237, + "component_based": false + }, + "minecraft:soul_lantern": { + "runtime_id": -269, + "component_based": false + }, + "minecraft:soul_sand": { + "runtime_id": 88, + "component_based": false + }, + "minecraft:soul_soil": { + "runtime_id": -236, + "component_based": false + }, + "minecraft:soul_torch": { + "runtime_id": -268, + "component_based": false + }, + "minecraft:sparkler": { + "runtime_id": 637, + "component_based": false + }, + "minecraft:spawn_egg": { + "runtime_id": 789, + "component_based": false + }, + "minecraft:spider_eye": { + "runtime_id": 300, + "component_based": false + }, + "minecraft:spider_spawn_egg": { + "runtime_id": 473, + "component_based": false + }, + "minecraft:spire_armor_trim_smithing_template": { + "runtime_id": 728, + "component_based": false + }, + "minecraft:splash_potion": { + "runtime_id": 594, + "component_based": false + }, + "minecraft:sponge": { + "runtime_id": 19, + "component_based": false + }, + "minecraft:spore_blossom": { + "runtime_id": -321, + "component_based": false + }, + "minecraft:spruce_boat": { + "runtime_id": 404, + "component_based": false + }, + "minecraft:spruce_button": { + "runtime_id": -144, + "component_based": false + }, + "minecraft:spruce_chest_boat": { + "runtime_id": 678, + "component_based": false + }, + "minecraft:spruce_door": { + "runtime_id": 586, + "component_based": false + }, + "minecraft:spruce_double_slab": { + "runtime_id": -809, + "component_based": false + }, + "minecraft:spruce_fence": { + "runtime_id": -579, + "component_based": false + }, + "minecraft:spruce_fence_gate": { + "runtime_id": 183, + "component_based": false + }, + "minecraft:spruce_hanging_sign": { + "runtime_id": -501, + "component_based": false + }, + "minecraft:spruce_leaves": { + "runtime_id": -800, + "component_based": false + }, + "minecraft:spruce_log": { + "runtime_id": -569, + "component_based": false + }, + "minecraft:spruce_planks": { + "runtime_id": -739, + "component_based": false + }, + "minecraft:spruce_pressure_plate": { + "runtime_id": -154, + "component_based": false + }, + "minecraft:spruce_sapling": { + "runtime_id": -825, + "component_based": false + }, + "minecraft:spruce_sign": { + "runtime_id": 609, + "component_based": false + }, + "minecraft:spruce_slab": { + "runtime_id": -804, + "component_based": false + }, + "minecraft:spruce_stairs": { + "runtime_id": 134, + "component_based": false + }, + "minecraft:spruce_standing_sign": { + "runtime_id": -181, + "component_based": false + }, + "minecraft:spruce_trapdoor": { + "runtime_id": -149, + "component_based": false + }, + "minecraft:spruce_wall_sign": { + "runtime_id": -182, + "component_based": false + }, + "minecraft:spruce_wood": { + "runtime_id": -814, + "component_based": false + }, + "minecraft:spyglass": { + "runtime_id": 662, + "component_based": false + }, + "minecraft:squid_spawn_egg": { + "runtime_id": 477, + "component_based": false + }, + "minecraft:stained_glass": { + "runtime_id": 773, + "component_based": false + }, + "minecraft:stained_glass_pane": { + "runtime_id": 774, + "component_based": false + }, + "minecraft:stained_hardened_clay": { + "runtime_id": 738, + "component_based": false + }, + "minecraft:standing_banner": { + "runtime_id": 176, + "component_based": false + }, + "minecraft:standing_sign": { + "runtime_id": 63, + "component_based": false + }, + "minecraft:stick": { + "runtime_id": 345, + "component_based": false + }, + "minecraft:sticky_piston": { + "runtime_id": 29, + "component_based": false + }, + "minecraft:sticky_piston_arm_collision": { + "runtime_id": -217, + "component_based": false + }, + "minecraft:stone": { + "runtime_id": 1, + "component_based": false + }, + "minecraft:stone_axe": { + "runtime_id": 339, + "component_based": false + }, + "minecraft:stone_block_slab": { + "runtime_id": 750, + "component_based": false + }, + "minecraft:stone_block_slab2": { + "runtime_id": 751, + "component_based": false + }, + "minecraft:stone_block_slab3": { + "runtime_id": 752, + "component_based": false + }, + "minecraft:stone_block_slab4": { + "runtime_id": 753, + "component_based": false + }, + "minecraft:stone_brick_double_slab": { + "runtime_id": -881, + "component_based": false + }, + "minecraft:stone_brick_slab": { + "runtime_id": -875, + "component_based": false + }, + "minecraft:stone_brick_stairs": { + "runtime_id": 109, + "component_based": false + }, + "minecraft:stone_brick_wall": { + "runtime_id": -977, + "component_based": false + }, + "minecraft:stone_bricks": { + "runtime_id": 98, + "component_based": false + }, + "minecraft:stone_button": { + "runtime_id": 77, + "component_based": false + }, + "minecraft:stone_hoe": { + "runtime_id": 355, + "component_based": false + }, + "minecraft:stone_pickaxe": { + "runtime_id": 338, + "component_based": false + }, + "minecraft:stone_pressure_plate": { + "runtime_id": 70, + "component_based": false + }, + "minecraft:stone_shovel": { + "runtime_id": 337, + "component_based": false + }, + "minecraft:stone_stairs": { + "runtime_id": 67, + "component_based": false + }, + "minecraft:stone_sword": { + "runtime_id": 336, + "component_based": false + }, + "minecraft:stonebrick": { + "runtime_id": 748, + "component_based": false + }, + "minecraft:stonecutter": { + "runtime_id": 245, + "component_based": false + }, + "minecraft:stonecutter_block": { + "runtime_id": -197, + "component_based": false + }, + "minecraft:stray_spawn_egg": { + "runtime_id": 489, + "component_based": false + }, + "minecraft:strider_spawn_egg": { + "runtime_id": 523, + "component_based": false + }, + "minecraft:string": { + "runtime_id": 351, + "component_based": true + }, + "minecraft:stripped_acacia_log": { + "runtime_id": -8, + "component_based": false + }, + "minecraft:stripped_acacia_wood": { + "runtime_id": -823, + "component_based": false + }, + "minecraft:stripped_bamboo_block": { + "runtime_id": -528, + "component_based": false + }, + "minecraft:stripped_birch_log": { + "runtime_id": -6, + "component_based": false + }, + "minecraft:stripped_birch_wood": { + "runtime_id": -821, + "component_based": false + }, + "minecraft:stripped_cherry_log": { + "runtime_id": -535, + "component_based": false + }, + "minecraft:stripped_cherry_wood": { + "runtime_id": -545, + "component_based": false + }, + "minecraft:stripped_crimson_hyphae": { + "runtime_id": -300, + "component_based": false + }, + "minecraft:stripped_crimson_stem": { + "runtime_id": -240, + "component_based": false + }, + "minecraft:stripped_dark_oak_log": { + "runtime_id": -9, + "component_based": false + }, + "minecraft:stripped_dark_oak_wood": { + "runtime_id": -824, + "component_based": false + }, + "minecraft:stripped_jungle_log": { + "runtime_id": -7, + "component_based": false + }, + "minecraft:stripped_jungle_wood": { + "runtime_id": -822, + "component_based": false + }, + "minecraft:stripped_mangrove_log": { + "runtime_id": -485, + "component_based": false + }, + "minecraft:stripped_mangrove_wood": { + "runtime_id": -498, + "component_based": false + }, + "minecraft:stripped_oak_log": { + "runtime_id": -10, + "component_based": false + }, + "minecraft:stripped_oak_wood": { + "runtime_id": -819, + "component_based": false + }, + "minecraft:stripped_spruce_log": { + "runtime_id": -5, + "component_based": false + }, + "minecraft:stripped_spruce_wood": { + "runtime_id": -820, + "component_based": false + }, + "minecraft:stripped_warped_hyphae": { + "runtime_id": -301, + "component_based": false + }, + "minecraft:stripped_warped_stem": { + "runtime_id": -241, + "component_based": false + }, + "minecraft:structure_block": { + "runtime_id": 252, + "component_based": false + }, + "minecraft:structure_void": { + "runtime_id": 217, + "component_based": false + }, + "minecraft:sugar": { + "runtime_id": 442, + "component_based": false + }, + "minecraft:sugar_cane": { + "runtime_id": 411, + "component_based": true + }, + "minecraft:sunflower": { + "runtime_id": 175, + "component_based": false + }, + "minecraft:suspicious_gravel": { + "runtime_id": -573, + "component_based": false + }, + "minecraft:suspicious_sand": { + "runtime_id": -529, + "component_based": false + }, + "minecraft:suspicious_stew": { + "runtime_id": 625, + "component_based": false + }, + "minecraft:sweet_berries": { + "runtime_id": 309, + "component_based": false + }, + "minecraft:sweet_berry_bush": { + "runtime_id": -207, + "component_based": false + }, + "minecraft:tadpole_bucket": { + "runtime_id": 667, + "component_based": false + }, + "minecraft:tadpole_spawn_egg": { + "runtime_id": 666, + "component_based": false + }, + "minecraft:tall_grass": { + "runtime_id": -864, + "component_based": false + }, + "minecraft:tallgrass": { + "runtime_id": 768, + "component_based": false + }, + "minecraft:target": { + "runtime_id": -239, + "component_based": false + }, + "minecraft:tide_armor_trim_smithing_template": { + "runtime_id": 725, + "component_based": false + }, + "minecraft:tinted_glass": { + "runtime_id": -334, + "component_based": false + }, + "minecraft:tnt": { + "runtime_id": 46, + "component_based": false + }, + "minecraft:tnt_minecart": { + "runtime_id": 558, + "component_based": false + }, + "minecraft:torch": { + "runtime_id": 50, + "component_based": false + }, + "minecraft:torchflower": { + "runtime_id": -568, + "component_based": false + }, + "minecraft:torchflower_crop": { + "runtime_id": -567, + "component_based": false + }, + "minecraft:torchflower_seeds": { + "runtime_id": 318, + "component_based": false + }, + "minecraft:totem_of_undying": { + "runtime_id": 601, + "component_based": false + }, + "minecraft:trader_llama_spawn_egg": { + "runtime_id": 685, + "component_based": false + }, + "minecraft:trapdoor": { + "runtime_id": 96, + "component_based": false + }, + "minecraft:trapped_chest": { + "runtime_id": 146, + "component_based": false + }, + "minecraft:trial_key": { + "runtime_id": 275, + "component_based": true + }, + "minecraft:trial_spawner": { + "runtime_id": -315, + "component_based": false + }, + "minecraft:trident": { + "runtime_id": 579, + "component_based": false + }, + "minecraft:trip_wire": { + "runtime_id": 132, + "component_based": false + }, + "minecraft:tripwire_hook": { + "runtime_id": 131, + "component_based": false + }, + "minecraft:tropical_fish": { + "runtime_id": 288, + "component_based": false + }, + "minecraft:tropical_fish_bucket": { + "runtime_id": 391, + "component_based": false + }, + "minecraft:tropical_fish_spawn_egg": { + "runtime_id": 507, + "component_based": false + }, + "minecraft:tube_coral": { + "runtime_id": -131, + "component_based": false + }, + "minecraft:tube_coral_block": { + "runtime_id": -132, + "component_based": false + }, + "minecraft:tube_coral_fan": { + "runtime_id": -133, + "component_based": false + }, + "minecraft:tube_coral_wall_fan": { + "runtime_id": -135, + "component_based": false + }, + "minecraft:tuff": { + "runtime_id": -333, + "component_based": false + }, + "minecraft:tuff_brick_double_slab": { + "runtime_id": -756, + "component_based": false + }, + "minecraft:tuff_brick_slab": { + "runtime_id": -755, + "component_based": false + }, + "minecraft:tuff_brick_stairs": { + "runtime_id": -757, + "component_based": false + }, + "minecraft:tuff_brick_wall": { + "runtime_id": -758, + "component_based": false + }, + "minecraft:tuff_bricks": { + "runtime_id": -754, + "component_based": false + }, + "minecraft:tuff_double_slab": { + "runtime_id": -745, + "component_based": false + }, + "minecraft:tuff_slab": { + "runtime_id": -744, + "component_based": false + }, + "minecraft:tuff_stairs": { + "runtime_id": -746, + "component_based": false + }, + "minecraft:tuff_wall": { + "runtime_id": -747, + "component_based": false + }, + "minecraft:turtle_egg": { + "runtime_id": -159, + "component_based": false + }, + "minecraft:turtle_helmet": { + "runtime_id": 606, + "component_based": false + }, + "minecraft:turtle_scute": { + "runtime_id": 605, + "component_based": false + }, + "minecraft:turtle_spawn_egg": { + "runtime_id": 513, + "component_based": false + }, + "minecraft:twisting_vines": { + "runtime_id": -287, + "component_based": false + }, + "minecraft:underwater_tnt": { + "runtime_id": -985, + "component_based": false + }, + "minecraft:underwater_torch": { + "runtime_id": 239, + "component_based": false + }, + "minecraft:undyed_shulker_box": { + "runtime_id": 205, + "component_based": false + }, + "minecraft:unknown": { + "runtime_id": -305, + "component_based": false + }, + "minecraft:unlit_redstone_torch": { + "runtime_id": 75, + "component_based": false + }, + "minecraft:unpowered_comparator": { + "runtime_id": 149, + "component_based": false + }, + "minecraft:unpowered_repeater": { + "runtime_id": 93, + "component_based": false + }, + "minecraft:vault": { + "runtime_id": -314, + "component_based": false + }, + "minecraft:verdant_froglight": { + "runtime_id": -470, + "component_based": false + }, + "minecraft:vex_armor_trim_smithing_template": { + "runtime_id": 724, + "component_based": false + }, + "minecraft:vex_spawn_egg": { + "runtime_id": 504, + "component_based": false + }, + "minecraft:villager_spawn_egg": { + "runtime_id": 476, + "component_based": false + }, + "minecraft:vindicator_spawn_egg": { + "runtime_id": 502, + "component_based": false + }, + "minecraft:vine": { + "runtime_id": 106, + "component_based": false + }, + "minecraft:wall_banner": { + "runtime_id": 177, + "component_based": false + }, + "minecraft:wall_sign": { + "runtime_id": 68, + "component_based": false + }, + "minecraft:wandering_trader_spawn_egg": { + "runtime_id": 520, + "component_based": false + }, + "minecraft:ward_armor_trim_smithing_template": { + "runtime_id": 722, + "component_based": false + }, + "minecraft:warden_spawn_egg": { + "runtime_id": 669, + "component_based": false + }, + "minecraft:warped_button": { + "runtime_id": -261, + "component_based": false + }, + "minecraft:warped_door": { + "runtime_id": 654, + "component_based": false + }, + "minecraft:warped_double_slab": { + "runtime_id": -267, + "component_based": false + }, + "minecraft:warped_fence": { + "runtime_id": -257, + "component_based": false + }, + "minecraft:warped_fence_gate": { + "runtime_id": -259, + "component_based": false + }, + "minecraft:warped_fungus": { + "runtime_id": -229, + "component_based": false + }, + "minecraft:warped_fungus_on_a_stick": { + "runtime_id": 655, + "component_based": true + }, + "minecraft:warped_hanging_sign": { + "runtime_id": -507, + "component_based": false + }, + "minecraft:warped_hyphae": { + "runtime_id": -298, + "component_based": false + }, + "minecraft:warped_nylium": { + "runtime_id": -233, + "component_based": false + }, + "minecraft:warped_planks": { + "runtime_id": -243, + "component_based": false + }, + "minecraft:warped_pressure_plate": { + "runtime_id": -263, + "component_based": false + }, + "minecraft:warped_roots": { + "runtime_id": -224, + "component_based": false + }, + "minecraft:warped_sign": { + "runtime_id": 652, + "component_based": false + }, + "minecraft:warped_slab": { + "runtime_id": -265, + "component_based": false + }, + "minecraft:warped_stairs": { + "runtime_id": -255, + "component_based": false + }, + "minecraft:warped_standing_sign": { + "runtime_id": -251, + "component_based": false + }, + "minecraft:warped_stem": { + "runtime_id": -226, + "component_based": false + }, + "minecraft:warped_trapdoor": { + "runtime_id": -247, + "component_based": false + }, + "minecraft:warped_wall_sign": { + "runtime_id": -253, + "component_based": false + }, + "minecraft:warped_wart_block": { + "runtime_id": -227, + "component_based": false + }, + "minecraft:water": { + "runtime_id": 9, + "component_based": false + }, + "minecraft:water_bucket": { + "runtime_id": 387, + "component_based": false + }, + "minecraft:waterlily": { + "runtime_id": 111, + "component_based": false + }, + "minecraft:waxed_chiseled_copper": { + "runtime_id": -764, + "component_based": false + }, + "minecraft:waxed_copper": { + "runtime_id": -344, + "component_based": false + }, + "minecraft:waxed_copper_bulb": { + "runtime_id": -780, + "component_based": false + }, + "minecraft:waxed_copper_door": { + "runtime_id": -788, + "component_based": false + }, + "minecraft:waxed_copper_grate": { + "runtime_id": -772, + "component_based": false + }, + "minecraft:waxed_copper_trapdoor": { + "runtime_id": -796, + "component_based": false + }, + "minecraft:waxed_cut_copper": { + "runtime_id": -351, + "component_based": false + }, + "minecraft:waxed_cut_copper_slab": { + "runtime_id": -365, + "component_based": false + }, + "minecraft:waxed_cut_copper_stairs": { + "runtime_id": -358, + "component_based": false + }, + "minecraft:waxed_double_cut_copper_slab": { + "runtime_id": -372, + "component_based": false + }, + "minecraft:waxed_exposed_chiseled_copper": { + "runtime_id": -765, + "component_based": false + }, + "minecraft:waxed_exposed_copper": { + "runtime_id": -345, + "component_based": false + }, + "minecraft:waxed_exposed_copper_bulb": { + "runtime_id": -781, + "component_based": false + }, + "minecraft:waxed_exposed_copper_door": { + "runtime_id": -789, + "component_based": false + }, + "minecraft:waxed_exposed_copper_grate": { + "runtime_id": -773, + "component_based": false + }, + "minecraft:waxed_exposed_copper_trapdoor": { + "runtime_id": -797, + "component_based": false + }, + "minecraft:waxed_exposed_cut_copper": { + "runtime_id": -352, + "component_based": false + }, + "minecraft:waxed_exposed_cut_copper_slab": { + "runtime_id": -366, + "component_based": false + }, + "minecraft:waxed_exposed_cut_copper_stairs": { + "runtime_id": -359, + "component_based": false + }, + "minecraft:waxed_exposed_double_cut_copper_slab": { + "runtime_id": -373, + "component_based": false + }, + "minecraft:waxed_oxidized_chiseled_copper": { + "runtime_id": -766, + "component_based": false + }, + "minecraft:waxed_oxidized_copper": { + "runtime_id": -446, + "component_based": false + }, + "minecraft:waxed_oxidized_copper_bulb": { + "runtime_id": -783, + "component_based": false + }, + "minecraft:waxed_oxidized_copper_door": { + "runtime_id": -791, + "component_based": false + }, + "minecraft:waxed_oxidized_copper_grate": { + "runtime_id": -775, + "component_based": false + }, + "minecraft:waxed_oxidized_copper_trapdoor": { + "runtime_id": -799, + "component_based": false + }, + "minecraft:waxed_oxidized_cut_copper": { + "runtime_id": -447, + "component_based": false + }, + "minecraft:waxed_oxidized_cut_copper_slab": { + "runtime_id": -449, + "component_based": false + }, + "minecraft:waxed_oxidized_cut_copper_stairs": { + "runtime_id": -448, + "component_based": false + }, + "minecraft:waxed_oxidized_double_cut_copper_slab": { + "runtime_id": -450, + "component_based": false + }, + "minecraft:waxed_weathered_chiseled_copper": { + "runtime_id": -767, + "component_based": false + }, + "minecraft:waxed_weathered_copper": { + "runtime_id": -346, + "component_based": false + }, + "minecraft:waxed_weathered_copper_bulb": { + "runtime_id": -782, + "component_based": false + }, + "minecraft:waxed_weathered_copper_door": { + "runtime_id": -790, + "component_based": false + }, + "minecraft:waxed_weathered_copper_grate": { + "runtime_id": -774, + "component_based": false + }, + "minecraft:waxed_weathered_copper_trapdoor": { + "runtime_id": -798, + "component_based": false + }, + "minecraft:waxed_weathered_cut_copper": { + "runtime_id": -353, + "component_based": false + }, + "minecraft:waxed_weathered_cut_copper_slab": { + "runtime_id": -367, + "component_based": false + }, + "minecraft:waxed_weathered_cut_copper_stairs": { + "runtime_id": -360, + "component_based": false + }, + "minecraft:waxed_weathered_double_cut_copper_slab": { + "runtime_id": -374, + "component_based": false + }, + "minecraft:wayfinder_armor_trim_smithing_template": { + "runtime_id": 730, + "component_based": false + }, + "minecraft:weathered_chiseled_copper": { + "runtime_id": -762, + "component_based": false + }, + "minecraft:weathered_copper": { + "runtime_id": -342, + "component_based": false + }, + "minecraft:weathered_copper_bulb": { + "runtime_id": -778, + "component_based": false + }, + "minecraft:weathered_copper_door": { + "runtime_id": -786, + "component_based": false + }, + "minecraft:weathered_copper_grate": { + "runtime_id": -770, + "component_based": false + }, + "minecraft:weathered_copper_trapdoor": { + "runtime_id": -794, + "component_based": false + }, + "minecraft:weathered_cut_copper": { + "runtime_id": -349, + "component_based": false + }, + "minecraft:weathered_cut_copper_slab": { + "runtime_id": -363, + "component_based": false + }, + "minecraft:weathered_cut_copper_stairs": { + "runtime_id": -356, + "component_based": false + }, + "minecraft:weathered_double_cut_copper_slab": { + "runtime_id": -370, + "component_based": false + }, + "minecraft:web": { + "runtime_id": 30, + "component_based": false + }, + "minecraft:weeping_vines": { + "runtime_id": -231, + "component_based": false + }, + "minecraft:wet_sponge": { + "runtime_id": -984, + "component_based": false + }, + "minecraft:wheat": { + "runtime_id": 359, + "component_based": false + }, + "minecraft:wheat_seeds": { + "runtime_id": 313, + "component_based": false + }, + "minecraft:white_bundle": { + "runtime_id": 268, + "component_based": true + }, + "minecraft:white_candle": { + "runtime_id": -413, + "component_based": false + }, + "minecraft:white_candle_cake": { + "runtime_id": -430, + "component_based": false + }, + "minecraft:white_carpet": { + "runtime_id": 171, + "component_based": false + }, + "minecraft:white_concrete": { + "runtime_id": 236, + "component_based": false + }, + "minecraft:white_concrete_powder": { + "runtime_id": 237, + "component_based": false + }, + "minecraft:white_dye": { + "runtime_id": 436, + "component_based": false + }, + "minecraft:white_glazed_terracotta": { + "runtime_id": 220, + "component_based": false + }, + "minecraft:white_shulker_box": { + "runtime_id": 218, + "component_based": false + }, + "minecraft:white_stained_glass": { + "runtime_id": 241, + "component_based": false + }, + "minecraft:white_stained_glass_pane": { + "runtime_id": 160, + "component_based": false + }, + "minecraft:white_terracotta": { + "runtime_id": 159, + "component_based": false + }, + "minecraft:white_tulip": { + "runtime_id": -835, + "component_based": false + }, + "minecraft:white_wool": { + "runtime_id": 35, + "component_based": false + }, + "minecraft:wild_armor_trim_smithing_template": { + "runtime_id": 721, + "component_based": false + }, + "minecraft:wind_charge": { + "runtime_id": 277, + "component_based": true + }, + "minecraft:witch_spawn_egg": { + "runtime_id": 479, + "component_based": false + }, + "minecraft:wither_rose": { + "runtime_id": -216, + "component_based": false + }, + "minecraft:wither_skeleton_skull": { + "runtime_id": -965, + "component_based": false + }, + "minecraft:wither_skeleton_spawn_egg": { + "runtime_id": 492, + "component_based": false + }, + "minecraft:wither_spawn_egg": { + "runtime_id": 536, + "component_based": false + }, + "minecraft:wolf_armor": { + "runtime_id": 741, + "component_based": true + }, + "minecraft:wolf_spawn_egg": { + "runtime_id": 466, + "component_based": false + }, + "minecraft:wood": { + "runtime_id": 776, + "component_based": false + }, + "minecraft:wooden_axe": { + "runtime_id": 335, + "component_based": false + }, + "minecraft:wooden_button": { + "runtime_id": 143, + "component_based": false + }, + "minecraft:wooden_door": { + "runtime_id": 384, + "component_based": false + }, + "minecraft:wooden_hoe": { + "runtime_id": 354, + "component_based": false + }, + "minecraft:wooden_pickaxe": { + "runtime_id": 334, + "component_based": false + }, + "minecraft:wooden_pressure_plate": { + "runtime_id": 72, + "component_based": false + }, + "minecraft:wooden_shovel": { + "runtime_id": 333, + "component_based": false + }, + "minecraft:wooden_slab": { + "runtime_id": 763, + "component_based": false + }, + "minecraft:wooden_sword": { + "runtime_id": 332, + "component_based": false + }, + "minecraft:wool": { + "runtime_id": 744, + "component_based": false + }, + "minecraft:writable_book": { + "runtime_id": 544, + "component_based": false + }, + "minecraft:written_book": { + "runtime_id": 545, + "component_based": false + }, + "minecraft:yellow_bundle": { + "runtime_id": 260, + "component_based": true + }, + "minecraft:yellow_candle": { + "runtime_id": -417, + "component_based": false + }, + "minecraft:yellow_candle_cake": { + "runtime_id": -434, + "component_based": false + }, + "minecraft:yellow_carpet": { + "runtime_id": -600, + "component_based": false + }, + "minecraft:yellow_concrete": { + "runtime_id": -631, + "component_based": false + }, + "minecraft:yellow_concrete_powder": { + "runtime_id": -712, + "component_based": false + }, + "minecraft:yellow_dye": { + "runtime_id": 432, + "component_based": false + }, + "minecraft:yellow_glazed_terracotta": { + "runtime_id": 224, + "component_based": false + }, + "minecraft:yellow_shulker_box": { + "runtime_id": -616, + "component_based": false + }, + "minecraft:yellow_stained_glass": { + "runtime_id": -676, + "component_based": false + }, + "minecraft:yellow_stained_glass_pane": { + "runtime_id": -646, + "component_based": false + }, + "minecraft:yellow_terracotta": { + "runtime_id": -727, + "component_based": false + }, + "minecraft:yellow_wool": { + "runtime_id": -558, + "component_based": false + }, + "minecraft:zoglin_spawn_egg": { + "runtime_id": 526, + "component_based": false + }, + "minecraft:zombie_head": { + "runtime_id": -966, + "component_based": false + }, + "minecraft:zombie_horse_spawn_egg": { + "runtime_id": 496, + "component_based": false + }, + "minecraft:zombie_pigman_spawn_egg": { + "runtime_id": 475, + "component_based": false + }, + "minecraft:zombie_spawn_egg": { + "runtime_id": 474, + "component_based": false + }, + "minecraft:zombie_villager_spawn_egg": { + "runtime_id": 505, + "component_based": false + } +} diff --git a/legacyver/required_item_list_766.json b/legacyver/required_item_list_766.json new file mode 100644 index 0000000..c523dd6 --- /dev/null +++ b/legacyver/required_item_list_766.json @@ -0,0 +1,7158 @@ +{ + "minecraft:acacia_boat": { + "runtime_id": 405, + "component_based": false + }, + "minecraft:acacia_button": { + "runtime_id": -140, + "component_based": false + }, + "minecraft:acacia_chest_boat": { + "runtime_id": 680, + "component_based": false + }, + "minecraft:acacia_door": { + "runtime_id": 589, + "component_based": false + }, + "minecraft:acacia_double_slab": { + "runtime_id": -812, + "component_based": false + }, + "minecraft:acacia_fence": { + "runtime_id": -575, + "component_based": false + }, + "minecraft:acacia_fence_gate": { + "runtime_id": 187, + "component_based": false + }, + "minecraft:acacia_hanging_sign": { + "runtime_id": -504, + "component_based": false + }, + "minecraft:acacia_leaves": { + "runtime_id": 161, + "component_based": false + }, + "minecraft:acacia_log": { + "runtime_id": 162, + "component_based": false + }, + "minecraft:acacia_planks": { + "runtime_id": -742, + "component_based": false + }, + "minecraft:acacia_pressure_plate": { + "runtime_id": -150, + "component_based": false + }, + "minecraft:acacia_sapling": { + "runtime_id": -828, + "component_based": false + }, + "minecraft:acacia_sign": { + "runtime_id": 612, + "component_based": false + }, + "minecraft:acacia_slab": { + "runtime_id": -807, + "component_based": false + }, + "minecraft:acacia_stairs": { + "runtime_id": 163, + "component_based": false + }, + "minecraft:acacia_standing_sign": { + "runtime_id": -190, + "component_based": false + }, + "minecraft:acacia_trapdoor": { + "runtime_id": -145, + "component_based": false + }, + "minecraft:acacia_wall_sign": { + "runtime_id": -191, + "component_based": false + }, + "minecraft:acacia_wood": { + "runtime_id": -817, + "component_based": false + }, + "minecraft:activator_rail": { + "runtime_id": 126, + "component_based": false + }, + "minecraft:agent_spawn_egg": { + "runtime_id": 515, + "component_based": false + }, + "minecraft:air": { + "runtime_id": -158, + "component_based": false + }, + "minecraft:allay_spawn_egg": { + "runtime_id": 669, + "component_based": false + }, + "minecraft:allium": { + "runtime_id": -831, + "component_based": false + }, + "minecraft:allow": { + "runtime_id": 210, + "component_based": false + }, + "minecraft:amethyst_block": { + "runtime_id": -327, + "component_based": false + }, + "minecraft:amethyst_cluster": { + "runtime_id": -329, + "component_based": false + }, + "minecraft:amethyst_shard": { + "runtime_id": 662, + "component_based": false + }, + "minecraft:ancient_debris": { + "runtime_id": -271, + "component_based": false + }, + "minecraft:andesite": { + "runtime_id": -594, + "component_based": false + }, + "minecraft:andesite_double_slab": { + "runtime_id": -920, + "component_based": false + }, + "minecraft:andesite_slab": { + "runtime_id": -893, + "component_based": false + }, + "minecraft:andesite_stairs": { + "runtime_id": -171, + "component_based": false + }, + "minecraft:andesite_wall": { + "runtime_id": -974, + "component_based": false + }, + "minecraft:angler_pottery_sherd": { + "runtime_id": 694, + "component_based": false + }, + "minecraft:anvil": { + "runtime_id": 145, + "component_based": false + }, + "minecraft:apple": { + "runtime_id": 278, + "component_based": true + }, + "minecraft:archer_pottery_sherd": { + "runtime_id": 695, + "component_based": false + }, + "minecraft:armadillo_scute": { + "runtime_id": 741, + "component_based": false + }, + "minecraft:armadillo_spawn_egg": { + "runtime_id": 740, + "component_based": false + }, + "minecraft:armor_stand": { + "runtime_id": 585, + "component_based": false + }, + "minecraft:arms_up_pottery_sherd": { + "runtime_id": 696, + "component_based": false + }, + "minecraft:arrow": { + "runtime_id": 325, + "component_based": true + }, + "minecraft:axolotl_bucket": { + "runtime_id": 394, + "component_based": false + }, + "minecraft:axolotl_spawn_egg": { + "runtime_id": 530, + "component_based": false + }, + "minecraft:azalea": { + "runtime_id": -337, + "component_based": false + }, + "minecraft:azalea_leaves": { + "runtime_id": -324, + "component_based": false + }, + "minecraft:azalea_leaves_flowered": { + "runtime_id": -325, + "component_based": false + }, + "minecraft:azure_bluet": { + "runtime_id": -832, + "component_based": false + }, + "minecraft:baked_potato": { + "runtime_id": 303, + "component_based": false + }, + "minecraft:balloon": { + "runtime_id": 636, + "component_based": false + }, + "minecraft:bamboo": { + "runtime_id": -163, + "component_based": false + }, + "minecraft:bamboo_block": { + "runtime_id": -527, + "component_based": false + }, + "minecraft:bamboo_button": { + "runtime_id": -511, + "component_based": false + }, + "minecraft:bamboo_chest_raft": { + "runtime_id": 692, + "component_based": false + }, + "minecraft:bamboo_door": { + "runtime_id": -517, + "component_based": false + }, + "minecraft:bamboo_double_slab": { + "runtime_id": -521, + "component_based": false + }, + "minecraft:bamboo_fence": { + "runtime_id": -515, + "component_based": false + }, + "minecraft:bamboo_fence_gate": { + "runtime_id": -516, + "component_based": false + }, + "minecraft:bamboo_hanging_sign": { + "runtime_id": -522, + "component_based": false + }, + "minecraft:bamboo_mosaic": { + "runtime_id": -509, + "component_based": false + }, + "minecraft:bamboo_mosaic_double_slab": { + "runtime_id": -525, + "component_based": false + }, + "minecraft:bamboo_mosaic_slab": { + "runtime_id": -524, + "component_based": false + }, + "minecraft:bamboo_mosaic_stairs": { + "runtime_id": -523, + "component_based": false + }, + "minecraft:bamboo_planks": { + "runtime_id": -510, + "component_based": false + }, + "minecraft:bamboo_pressure_plate": { + "runtime_id": -514, + "component_based": false + }, + "minecraft:bamboo_raft": { + "runtime_id": 691, + "component_based": false + }, + "minecraft:bamboo_sapling": { + "runtime_id": -164, + "component_based": false + }, + "minecraft:bamboo_sign": { + "runtime_id": 690, + "component_based": false + }, + "minecraft:bamboo_slab": { + "runtime_id": -513, + "component_based": false + }, + "minecraft:bamboo_stairs": { + "runtime_id": -512, + "component_based": false + }, + "minecraft:bamboo_standing_sign": { + "runtime_id": -518, + "component_based": false + }, + "minecraft:bamboo_trapdoor": { + "runtime_id": -520, + "component_based": false + }, + "minecraft:bamboo_wall_sign": { + "runtime_id": -519, + "component_based": false + }, + "minecraft:banner": { + "runtime_id": 600, + "component_based": false + }, + "minecraft:banner_pattern": { + "runtime_id": 794, + "component_based": false + }, + "minecraft:barrel": { + "runtime_id": -203, + "component_based": false + }, + "minecraft:barrier": { + "runtime_id": -161, + "component_based": false + }, + "minecraft:basalt": { + "runtime_id": -234, + "component_based": false + }, + "minecraft:bat_spawn_egg": { + "runtime_id": 480, + "component_based": false + }, + "minecraft:beacon": { + "runtime_id": 138, + "component_based": false + }, + "minecraft:bed": { + "runtime_id": 444, + "component_based": false + }, + "minecraft:bedrock": { + "runtime_id": 7, + "component_based": false + }, + "minecraft:bee_nest": { + "runtime_id": -218, + "component_based": false + }, + "minecraft:bee_spawn_egg": { + "runtime_id": 522, + "component_based": false + }, + "minecraft:beef": { + "runtime_id": 295, + "component_based": false + }, + "minecraft:beehive": { + "runtime_id": -219, + "component_based": false + }, + "minecraft:beetroot": { + "runtime_id": 307, + "component_based": false + }, + "minecraft:beetroot_seeds": { + "runtime_id": 317, + "component_based": false + }, + "minecraft:beetroot_soup": { + "runtime_id": 308, + "component_based": false + }, + "minecraft:bell": { + "runtime_id": -206, + "component_based": false + }, + "minecraft:big_dripleaf": { + "runtime_id": -323, + "component_based": false + }, + "minecraft:birch_boat": { + "runtime_id": 402, + "component_based": false + }, + "minecraft:birch_button": { + "runtime_id": -141, + "component_based": false + }, + "minecraft:birch_chest_boat": { + "runtime_id": 677, + "component_based": false + }, + "minecraft:birch_door": { + "runtime_id": 587, + "component_based": false + }, + "minecraft:birch_double_slab": { + "runtime_id": -810, + "component_based": false + }, + "minecraft:birch_fence": { + "runtime_id": -576, + "component_based": false + }, + "minecraft:birch_fence_gate": { + "runtime_id": 184, + "component_based": false + }, + "minecraft:birch_hanging_sign": { + "runtime_id": -502, + "component_based": false + }, + "minecraft:birch_leaves": { + "runtime_id": -801, + "component_based": false + }, + "minecraft:birch_log": { + "runtime_id": -570, + "component_based": false + }, + "minecraft:birch_planks": { + "runtime_id": -740, + "component_based": false + }, + "minecraft:birch_pressure_plate": { + "runtime_id": -151, + "component_based": false + }, + "minecraft:birch_sapling": { + "runtime_id": -826, + "component_based": false + }, + "minecraft:birch_sign": { + "runtime_id": 610, + "component_based": false + }, + "minecraft:birch_slab": { + "runtime_id": -805, + "component_based": false + }, + "minecraft:birch_stairs": { + "runtime_id": 135, + "component_based": false + }, + "minecraft:birch_standing_sign": { + "runtime_id": -186, + "component_based": false + }, + "minecraft:birch_trapdoor": { + "runtime_id": -146, + "component_based": false + }, + "minecraft:birch_wall_sign": { + "runtime_id": -187, + "component_based": false + }, + "minecraft:birch_wood": { + "runtime_id": -815, + "component_based": false + }, + "minecraft:black_bundle": { + "runtime_id": 257, + "component_based": true + }, + "minecraft:black_candle": { + "runtime_id": -428, + "component_based": false + }, + "minecraft:black_candle_cake": { + "runtime_id": -445, + "component_based": false + }, + "minecraft:black_carpet": { + "runtime_id": -611, + "component_based": false + }, + "minecraft:black_concrete": { + "runtime_id": -642, + "component_based": false + }, + "minecraft:black_concrete_powder": { + "runtime_id": -723, + "component_based": false + }, + "minecraft:black_dye": { + "runtime_id": 421, + "component_based": false + }, + "minecraft:black_glazed_terracotta": { + "runtime_id": 235, + "component_based": false + }, + "minecraft:black_shulker_box": { + "runtime_id": -627, + "component_based": false + }, + "minecraft:black_stained_glass": { + "runtime_id": -687, + "component_based": false + }, + "minecraft:black_stained_glass_pane": { + "runtime_id": -657, + "component_based": false + }, + "minecraft:black_terracotta": { + "runtime_id": -738, + "component_based": false + }, + "minecraft:black_wool": { + "runtime_id": -554, + "component_based": false + }, + "minecraft:blackstone": { + "runtime_id": -273, + "component_based": false + }, + "minecraft:blackstone_double_slab": { + "runtime_id": -283, + "component_based": false + }, + "minecraft:blackstone_slab": { + "runtime_id": -282, + "component_based": false + }, + "minecraft:blackstone_stairs": { + "runtime_id": -276, + "component_based": false + }, + "minecraft:blackstone_wall": { + "runtime_id": -277, + "component_based": false + }, + "minecraft:blade_pottery_sherd": { + "runtime_id": 697, + "component_based": false + }, + "minecraft:blast_furnace": { + "runtime_id": -196, + "component_based": false + }, + "minecraft:blaze_powder": { + "runtime_id": 456, + "component_based": false + }, + "minecraft:blaze_rod": { + "runtime_id": 449, + "component_based": false + }, + "minecraft:blaze_spawn_egg": { + "runtime_id": 483, + "component_based": false + }, + "minecraft:bleach": { + "runtime_id": 634, + "component_based": false + }, + "minecraft:blue_bundle": { + "runtime_id": 258, + "component_based": true + }, + "minecraft:blue_candle": { + "runtime_id": -424, + "component_based": false + }, + "minecraft:blue_candle_cake": { + "runtime_id": -441, + "component_based": false + }, + "minecraft:blue_carpet": { + "runtime_id": -607, + "component_based": false + }, + "minecraft:blue_concrete": { + "runtime_id": -638, + "component_based": false + }, + "minecraft:blue_concrete_powder": { + "runtime_id": -719, + "component_based": false + }, + "minecraft:blue_dye": { + "runtime_id": 425, + "component_based": false + }, + "minecraft:blue_glazed_terracotta": { + "runtime_id": 231, + "component_based": false + }, + "minecraft:blue_ice": { + "runtime_id": -11, + "component_based": false + }, + "minecraft:blue_orchid": { + "runtime_id": -830, + "component_based": false + }, + "minecraft:blue_shulker_box": { + "runtime_id": -623, + "component_based": false + }, + "minecraft:blue_stained_glass": { + "runtime_id": -683, + "component_based": false + }, + "minecraft:blue_stained_glass_pane": { + "runtime_id": -653, + "component_based": false + }, + "minecraft:blue_terracotta": { + "runtime_id": -734, + "component_based": false + }, + "minecraft:blue_wool": { + "runtime_id": -563, + "component_based": false + }, + "minecraft:board": { + "runtime_id": 630, + "component_based": false + }, + "minecraft:boat": { + "runtime_id": 792, + "component_based": false + }, + "minecraft:bogged_spawn_egg": { + "runtime_id": 490, + "component_based": false + }, + "minecraft:bolt_armor_trim_smithing_template": { + "runtime_id": 736, + "component_based": false + }, + "minecraft:bone": { + "runtime_id": 441, + "component_based": false + }, + "minecraft:bone_block": { + "runtime_id": 216, + "component_based": false + }, + "minecraft:bone_meal": { + "runtime_id": 437, + "component_based": false + }, + "minecraft:book": { + "runtime_id": 413, + "component_based": false + }, + "minecraft:bookshelf": { + "runtime_id": 47, + "component_based": false + }, + "minecraft:border_block": { + "runtime_id": 212, + "component_based": false + }, + "minecraft:bordure_indented_banner_pattern": { + "runtime_id": 619, + "component_based": false + }, + "minecraft:bow": { + "runtime_id": 324, + "component_based": false + }, + "minecraft:bowl": { + "runtime_id": 346, + "component_based": false + }, + "minecraft:brain_coral": { + "runtime_id": -581, + "component_based": false + }, + "minecraft:brain_coral_block": { + "runtime_id": -849, + "component_based": false + }, + "minecraft:brain_coral_fan": { + "runtime_id": -840, + "component_based": false + }, + "minecraft:brain_coral_wall_fan": { + "runtime_id": -904, + "component_based": false + }, + "minecraft:bread": { + "runtime_id": 283, + "component_based": false + }, + "minecraft:breeze_rod": { + "runtime_id": 274, + "component_based": true + }, + "minecraft:breeze_spawn_egg": { + "runtime_id": 529, + "component_based": false + }, + "minecraft:brewer_pottery_sherd": { + "runtime_id": 698, + "component_based": false + }, + "minecraft:brewing_stand": { + "runtime_id": 458, + "component_based": true + }, + "minecraft:brick": { + "runtime_id": 409, + "component_based": false + }, + "minecraft:brick_block": { + "runtime_id": 45, + "component_based": false + }, + "minecraft:brick_double_slab": { + "runtime_id": -880, + "component_based": false + }, + "minecraft:brick_slab": { + "runtime_id": -874, + "component_based": false + }, + "minecraft:brick_stairs": { + "runtime_id": 108, + "component_based": false + }, + "minecraft:brick_wall": { + "runtime_id": -976, + "component_based": false + }, + "minecraft:brown_bundle": { + "runtime_id": 259, + "component_based": true + }, + "minecraft:brown_candle": { + "runtime_id": -425, + "component_based": false + }, + "minecraft:brown_candle_cake": { + "runtime_id": -442, + "component_based": false + }, + "minecraft:brown_carpet": { + "runtime_id": -608, + "component_based": false + }, + "minecraft:brown_concrete": { + "runtime_id": -639, + "component_based": false + }, + "minecraft:brown_concrete_powder": { + "runtime_id": -720, + "component_based": false + }, + "minecraft:brown_dye": { + "runtime_id": 424, + "component_based": false + }, + "minecraft:brown_glazed_terracotta": { + "runtime_id": 232, + "component_based": false + }, + "minecraft:brown_mushroom": { + "runtime_id": 39, + "component_based": false + }, + "minecraft:brown_mushroom_block": { + "runtime_id": 99, + "component_based": false + }, + "minecraft:brown_shulker_box": { + "runtime_id": -624, + "component_based": false + }, + "minecraft:brown_stained_glass": { + "runtime_id": -684, + "component_based": false + }, + "minecraft:brown_stained_glass_pane": { + "runtime_id": -654, + "component_based": false + }, + "minecraft:brown_terracotta": { + "runtime_id": -735, + "component_based": false + }, + "minecraft:brown_wool": { + "runtime_id": -555, + "component_based": false + }, + "minecraft:brush": { + "runtime_id": 717, + "component_based": false + }, + "minecraft:bubble_column": { + "runtime_id": -160, + "component_based": false + }, + "minecraft:bubble_coral": { + "runtime_id": -582, + "component_based": false + }, + "minecraft:bubble_coral_block": { + "runtime_id": -850, + "component_based": false + }, + "minecraft:bubble_coral_fan": { + "runtime_id": -841, + "component_based": false + }, + "minecraft:bubble_coral_wall_fan": { + "runtime_id": -136, + "component_based": false + }, + "minecraft:bucket": { + "runtime_id": 385, + "component_based": false + }, + "minecraft:budding_amethyst": { + "runtime_id": -328, + "component_based": false + }, + "minecraft:bundle": { + "runtime_id": 262, + "component_based": true + }, + "minecraft:burn_pottery_sherd": { + "runtime_id": 699, + "component_based": false + }, + "minecraft:cactus": { + "runtime_id": 81, + "component_based": false + }, + "minecraft:cake": { + "runtime_id": 443, + "component_based": true + }, + "minecraft:calcite": { + "runtime_id": -326, + "component_based": false + }, + "minecraft:calibrated_sculk_sensor": { + "runtime_id": -580, + "component_based": false + }, + "minecraft:camel_spawn_egg": { + "runtime_id": 693, + "component_based": false + }, + "minecraft:camera": { + "runtime_id": 631, + "component_based": false + }, + "minecraft:campfire": { + "runtime_id": 624, + "component_based": true + }, + "minecraft:candle": { + "runtime_id": -412, + "component_based": false + }, + "minecraft:candle_cake": { + "runtime_id": -429, + "component_based": false + }, + "minecraft:carpet": { + "runtime_id": 751, + "component_based": false + }, + "minecraft:carrot": { + "runtime_id": 301, + "component_based": false + }, + "minecraft:carrot_on_a_stick": { + "runtime_id": 550, + "component_based": false + }, + "minecraft:carrots": { + "runtime_id": 141, + "component_based": false + }, + "minecraft:cartography_table": { + "runtime_id": -200, + "component_based": false + }, + "minecraft:carved_pumpkin": { + "runtime_id": -155, + "component_based": false + }, + "minecraft:cat_spawn_egg": { + "runtime_id": 516, + "component_based": false + }, + "minecraft:cauldron": { + "runtime_id": 459, + "component_based": true + }, + "minecraft:cave_spider_spawn_egg": { + "runtime_id": 484, + "component_based": false + }, + "minecraft:cave_vines": { + "runtime_id": -322, + "component_based": false + }, + "minecraft:cave_vines_body_with_berries": { + "runtime_id": -375, + "component_based": false + }, + "minecraft:cave_vines_head_with_berries": { + "runtime_id": -376, + "component_based": false + }, + "minecraft:chain": { + "runtime_id": 657, + "component_based": true + }, + "minecraft:chain_command_block": { + "runtime_id": 189, + "component_based": false + }, + "minecraft:chainmail_boots": { + "runtime_id": 367, + "component_based": false + }, + "minecraft:chainmail_chestplate": { + "runtime_id": 365, + "component_based": false + }, + "minecraft:chainmail_helmet": { + "runtime_id": 364, + "component_based": false + }, + "minecraft:chainmail_leggings": { + "runtime_id": 366, + "component_based": false + }, + "minecraft:chalkboard": { + "runtime_id": 230, + "component_based": false + }, + "minecraft:charcoal": { + "runtime_id": 327, + "component_based": true + }, + "minecraft:chemical_heat": { + "runtime_id": 192, + "component_based": false + }, + "minecraft:chemistry_table": { + "runtime_id": 786, + "component_based": false + }, + "minecraft:cherry_boat": { + "runtime_id": 687, + "component_based": false + }, + "minecraft:cherry_button": { + "runtime_id": -530, + "component_based": false + }, + "minecraft:cherry_chest_boat": { + "runtime_id": 688, + "component_based": false + }, + "minecraft:cherry_door": { + "runtime_id": -531, + "component_based": false + }, + "minecraft:cherry_double_slab": { + "runtime_id": -540, + "component_based": false + }, + "minecraft:cherry_fence": { + "runtime_id": -532, + "component_based": false + }, + "minecraft:cherry_fence_gate": { + "runtime_id": -533, + "component_based": false + }, + "minecraft:cherry_hanging_sign": { + "runtime_id": -534, + "component_based": false + }, + "minecraft:cherry_leaves": { + "runtime_id": -548, + "component_based": false + }, + "minecraft:cherry_log": { + "runtime_id": -536, + "component_based": false + }, + "minecraft:cherry_planks": { + "runtime_id": -537, + "component_based": false + }, + "minecraft:cherry_pressure_plate": { + "runtime_id": -538, + "component_based": false + }, + "minecraft:cherry_sapling": { + "runtime_id": -547, + "component_based": false + }, + "minecraft:cherry_sign": { + "runtime_id": 689, + "component_based": false + }, + "minecraft:cherry_slab": { + "runtime_id": -539, + "component_based": false + }, + "minecraft:cherry_stairs": { + "runtime_id": -541, + "component_based": false + }, + "minecraft:cherry_standing_sign": { + "runtime_id": -542, + "component_based": false + }, + "minecraft:cherry_trapdoor": { + "runtime_id": -543, + "component_based": false + }, + "minecraft:cherry_wall_sign": { + "runtime_id": -544, + "component_based": false + }, + "minecraft:cherry_wood": { + "runtime_id": -546, + "component_based": false + }, + "minecraft:chest": { + "runtime_id": 54, + "component_based": false + }, + "minecraft:chest_boat": { + "runtime_id": 683, + "component_based": false + }, + "minecraft:chest_minecart": { + "runtime_id": 415, + "component_based": false + }, + "minecraft:chicken": { + "runtime_id": 297, + "component_based": false + }, + "minecraft:chicken_spawn_egg": { + "runtime_id": 462, + "component_based": false + }, + "minecraft:chipped_anvil": { + "runtime_id": -959, + "component_based": false + }, + "minecraft:chiseled_bookshelf": { + "runtime_id": -526, + "component_based": false + }, + "minecraft:chiseled_copper": { + "runtime_id": -760, + "component_based": false + }, + "minecraft:chiseled_deepslate": { + "runtime_id": -395, + "component_based": false + }, + "minecraft:chiseled_nether_bricks": { + "runtime_id": -302, + "component_based": false + }, + "minecraft:chiseled_polished_blackstone": { + "runtime_id": -279, + "component_based": false + }, + "minecraft:chiseled_quartz_block": { + "runtime_id": -953, + "component_based": false + }, + "minecraft:chiseled_red_sandstone": { + "runtime_id": -956, + "component_based": false + }, + "minecraft:chiseled_resin_bricks": { + "runtime_id": -1020, + "component_based": false + }, + "minecraft:chiseled_sandstone": { + "runtime_id": -944, + "component_based": false + }, + "minecraft:chiseled_stone_bricks": { + "runtime_id": -870, + "component_based": false + }, + "minecraft:chiseled_tuff": { + "runtime_id": -753, + "component_based": false + }, + "minecraft:chiseled_tuff_bricks": { + "runtime_id": -759, + "component_based": false + }, + "minecraft:chorus_flower": { + "runtime_id": 200, + "component_based": false + }, + "minecraft:chorus_fruit": { + "runtime_id": 591, + "component_based": false + }, + "minecraft:chorus_plant": { + "runtime_id": 240, + "component_based": false + }, + "minecraft:clay": { + "runtime_id": 82, + "component_based": false + }, + "minecraft:clay_ball": { + "runtime_id": 410, + "component_based": false + }, + "minecraft:client_request_placeholder_block": { + "runtime_id": -465, + "component_based": false + }, + "minecraft:clock": { + "runtime_id": 419, + "component_based": false + }, + "minecraft:closed_eyeblossom": { + "runtime_id": -1019, + "component_based": false + }, + "minecraft:coal": { + "runtime_id": 326, + "component_based": true + }, + "minecraft:coal_block": { + "runtime_id": 173, + "component_based": false + }, + "minecraft:coal_ore": { + "runtime_id": 16, + "component_based": false + }, + "minecraft:coarse_dirt": { + "runtime_id": -962, + "component_based": false + }, + "minecraft:coast_armor_trim_smithing_template": { + "runtime_id": 721, + "component_based": false + }, + "minecraft:cobbled_deepslate": { + "runtime_id": -379, + "component_based": false + }, + "minecraft:cobbled_deepslate_double_slab": { + "runtime_id": -396, + "component_based": false + }, + "minecraft:cobbled_deepslate_slab": { + "runtime_id": -380, + "component_based": false + }, + "minecraft:cobbled_deepslate_stairs": { + "runtime_id": -381, + "component_based": false + }, + "minecraft:cobbled_deepslate_wall": { + "runtime_id": -382, + "component_based": false + }, + "minecraft:cobblestone": { + "runtime_id": 4, + "component_based": false + }, + "minecraft:cobblestone_double_slab": { + "runtime_id": -879, + "component_based": false + }, + "minecraft:cobblestone_slab": { + "runtime_id": -873, + "component_based": false + }, + "minecraft:cobblestone_wall": { + "runtime_id": 139, + "component_based": false + }, + "minecraft:cocoa": { + "runtime_id": 127, + "component_based": false + }, + "minecraft:cocoa_beans": { + "runtime_id": 438, + "component_based": false + }, + "minecraft:cod": { + "runtime_id": 286, + "component_based": false + }, + "minecraft:cod_bucket": { + "runtime_id": 389, + "component_based": false + }, + "minecraft:cod_spawn_egg": { + "runtime_id": 508, + "component_based": false + }, + "minecraft:colored_torch_blue": { + "runtime_id": 204, + "component_based": false + }, + "minecraft:colored_torch_bp": { + "runtime_id": 790, + "component_based": false + }, + "minecraft:colored_torch_green": { + "runtime_id": -963, + "component_based": false + }, + "minecraft:colored_torch_purple": { + "runtime_id": -964, + "component_based": false + }, + "minecraft:colored_torch_red": { + "runtime_id": 202, + "component_based": false + }, + "minecraft:colored_torch_rg": { + "runtime_id": 789, + "component_based": false + }, + "minecraft:command_block": { + "runtime_id": 137, + "component_based": false + }, + "minecraft:command_block_minecart": { + "runtime_id": 596, + "component_based": false + }, + "minecraft:comparator": { + "runtime_id": 555, + "component_based": true + }, + "minecraft:compass": { + "runtime_id": 417, + "component_based": false + }, + "minecraft:composter": { + "runtime_id": -213, + "component_based": false + }, + "minecraft:compound": { + "runtime_id": 632, + "component_based": false + }, + "minecraft:compound_creator": { + "runtime_id": 238, + "component_based": false + }, + "minecraft:concrete": { + "runtime_id": 777, + "component_based": false + }, + "minecraft:concrete_powder": { + "runtime_id": 778, + "component_based": false + }, + "minecraft:conduit": { + "runtime_id": -157, + "component_based": false + }, + "minecraft:cooked_beef": { + "runtime_id": 296, + "component_based": false + }, + "minecraft:cooked_chicken": { + "runtime_id": 298, + "component_based": false + }, + "minecraft:cooked_cod": { + "runtime_id": 290, + "component_based": false + }, + "minecraft:cooked_mutton": { + "runtime_id": 584, + "component_based": false + }, + "minecraft:cooked_porkchop": { + "runtime_id": 285, + "component_based": false + }, + "minecraft:cooked_rabbit": { + "runtime_id": 311, + "component_based": false + }, + "minecraft:cooked_salmon": { + "runtime_id": 291, + "component_based": false + }, + "minecraft:cookie": { + "runtime_id": 293, + "component_based": false + }, + "minecraft:copper_block": { + "runtime_id": -340, + "component_based": false + }, + "minecraft:copper_bulb": { + "runtime_id": -776, + "component_based": false + }, + "minecraft:copper_door": { + "runtime_id": -784, + "component_based": false + }, + "minecraft:copper_grate": { + "runtime_id": -768, + "component_based": false + }, + "minecraft:copper_ingot": { + "runtime_id": 538, + "component_based": false + }, + "minecraft:copper_ore": { + "runtime_id": -311, + "component_based": false + }, + "minecraft:copper_trapdoor": { + "runtime_id": -792, + "component_based": false + }, + "minecraft:coral": { + "runtime_id": 773, + "component_based": false + }, + "minecraft:coral_block": { + "runtime_id": 755, + "component_based": false + }, + "minecraft:coral_fan": { + "runtime_id": 764, + "component_based": false + }, + "minecraft:coral_fan_dead": { + "runtime_id": 765, + "component_based": false + }, + "minecraft:cornflower": { + "runtime_id": -838, + "component_based": false + }, + "minecraft:cow_spawn_egg": { + "runtime_id": 463, + "component_based": false + }, + "minecraft:cracked_deepslate_bricks": { + "runtime_id": -410, + "component_based": false + }, + "minecraft:cracked_deepslate_tiles": { + "runtime_id": -409, + "component_based": false + }, + "minecraft:cracked_nether_bricks": { + "runtime_id": -303, + "component_based": false + }, + "minecraft:cracked_polished_blackstone_bricks": { + "runtime_id": -280, + "component_based": false + }, + "minecraft:cracked_stone_bricks": { + "runtime_id": -869, + "component_based": false + }, + "minecraft:crafter": { + "runtime_id": -313, + "component_based": false + }, + "minecraft:crafting_table": { + "runtime_id": 58, + "component_based": false + }, + "minecraft:creaking_heart": { + "runtime_id": -1012, + "component_based": false + }, + "minecraft:creaking_spawn_egg": { + "runtime_id": 748, + "component_based": false + }, + "minecraft:creeper_banner_pattern": { + "runtime_id": 615, + "component_based": false + }, + "minecraft:creeper_head": { + "runtime_id": -968, + "component_based": false + }, + "minecraft:creeper_spawn_egg": { + "runtime_id": 468, + "component_based": false + }, + "minecraft:crimson_button": { + "runtime_id": -260, + "component_based": false + }, + "minecraft:crimson_door": { + "runtime_id": 654, + "component_based": false + }, + "minecraft:crimson_double_slab": { + "runtime_id": -266, + "component_based": false + }, + "minecraft:crimson_fence": { + "runtime_id": -256, + "component_based": false + }, + "minecraft:crimson_fence_gate": { + "runtime_id": -258, + "component_based": false + }, + "minecraft:crimson_fungus": { + "runtime_id": -228, + "component_based": false + }, + "minecraft:crimson_hanging_sign": { + "runtime_id": -506, + "component_based": false + }, + "minecraft:crimson_hyphae": { + "runtime_id": -299, + "component_based": false + }, + "minecraft:crimson_nylium": { + "runtime_id": -232, + "component_based": false + }, + "minecraft:crimson_planks": { + "runtime_id": -242, + "component_based": false + }, + "minecraft:crimson_pressure_plate": { + "runtime_id": -262, + "component_based": false + }, + "minecraft:crimson_roots": { + "runtime_id": -223, + "component_based": false + }, + "minecraft:crimson_sign": { + "runtime_id": 652, + "component_based": false + }, + "minecraft:crimson_slab": { + "runtime_id": -264, + "component_based": false + }, + "minecraft:crimson_stairs": { + "runtime_id": -254, + "component_based": false + }, + "minecraft:crimson_standing_sign": { + "runtime_id": -250, + "component_based": false + }, + "minecraft:crimson_stem": { + "runtime_id": -225, + "component_based": false + }, + "minecraft:crimson_trapdoor": { + "runtime_id": -246, + "component_based": false + }, + "minecraft:crimson_wall_sign": { + "runtime_id": -252, + "component_based": false + }, + "minecraft:crossbow": { + "runtime_id": 608, + "component_based": false + }, + "minecraft:crying_obsidian": { + "runtime_id": -289, + "component_based": false + }, + "minecraft:cut_copper": { + "runtime_id": -347, + "component_based": false + }, + "minecraft:cut_copper_slab": { + "runtime_id": -361, + "component_based": false + }, + "minecraft:cut_copper_stairs": { + "runtime_id": -354, + "component_based": false + }, + "minecraft:cut_red_sandstone": { + "runtime_id": -957, + "component_based": false + }, + "minecraft:cut_red_sandstone_double_slab": { + "runtime_id": -928, + "component_based": false + }, + "minecraft:cut_red_sandstone_slab": { + "runtime_id": -901, + "component_based": false + }, + "minecraft:cut_sandstone": { + "runtime_id": -945, + "component_based": false + }, + "minecraft:cut_sandstone_double_slab": { + "runtime_id": -927, + "component_based": false + }, + "minecraft:cut_sandstone_slab": { + "runtime_id": -900, + "component_based": false + }, + "minecraft:cyan_bundle": { + "runtime_id": 265, + "component_based": true + }, + "minecraft:cyan_candle": { + "runtime_id": -422, + "component_based": false + }, + "minecraft:cyan_candle_cake": { + "runtime_id": -439, + "component_based": false + }, + "minecraft:cyan_carpet": { + "runtime_id": -605, + "component_based": false + }, + "minecraft:cyan_concrete": { + "runtime_id": -636, + "component_based": false + }, + "minecraft:cyan_concrete_powder": { + "runtime_id": -717, + "component_based": false + }, + "minecraft:cyan_dye": { + "runtime_id": 427, + "component_based": false + }, + "minecraft:cyan_glazed_terracotta": { + "runtime_id": 229, + "component_based": false + }, + "minecraft:cyan_shulker_box": { + "runtime_id": -621, + "component_based": false + }, + "minecraft:cyan_stained_glass": { + "runtime_id": -681, + "component_based": false + }, + "minecraft:cyan_stained_glass_pane": { + "runtime_id": -651, + "component_based": false + }, + "minecraft:cyan_terracotta": { + "runtime_id": -732, + "component_based": false + }, + "minecraft:cyan_wool": { + "runtime_id": -561, + "component_based": false + }, + "minecraft:damaged_anvil": { + "runtime_id": -960, + "component_based": false + }, + "minecraft:dandelion": { + "runtime_id": 37, + "component_based": false + }, + "minecraft:danger_pottery_sherd": { + "runtime_id": 700, + "component_based": false + }, + "minecraft:dark_oak_boat": { + "runtime_id": 406, + "component_based": false + }, + "minecraft:dark_oak_button": { + "runtime_id": -142, + "component_based": false + }, + "minecraft:dark_oak_chest_boat": { + "runtime_id": 681, + "component_based": false + }, + "minecraft:dark_oak_door": { + "runtime_id": 590, + "component_based": false + }, + "minecraft:dark_oak_double_slab": { + "runtime_id": -813, + "component_based": false + }, + "minecraft:dark_oak_fence": { + "runtime_id": -577, + "component_based": false + }, + "minecraft:dark_oak_fence_gate": { + "runtime_id": 186, + "component_based": false + }, + "minecraft:dark_oak_hanging_sign": { + "runtime_id": -505, + "component_based": false + }, + "minecraft:dark_oak_leaves": { + "runtime_id": -803, + "component_based": false + }, + "minecraft:dark_oak_log": { + "runtime_id": -572, + "component_based": false + }, + "minecraft:dark_oak_planks": { + "runtime_id": -743, + "component_based": false + }, + "minecraft:dark_oak_pressure_plate": { + "runtime_id": -152, + "component_based": false + }, + "minecraft:dark_oak_sapling": { + "runtime_id": -829, + "component_based": false + }, + "minecraft:dark_oak_sign": { + "runtime_id": 613, + "component_based": false + }, + "minecraft:dark_oak_slab": { + "runtime_id": -808, + "component_based": false + }, + "minecraft:dark_oak_stairs": { + "runtime_id": 164, + "component_based": false + }, + "minecraft:dark_oak_trapdoor": { + "runtime_id": -147, + "component_based": false + }, + "minecraft:dark_oak_wood": { + "runtime_id": -818, + "component_based": false + }, + "minecraft:dark_prismarine": { + "runtime_id": -947, + "component_based": false + }, + "minecraft:dark_prismarine_double_slab": { + "runtime_id": -913, + "component_based": false + }, + "minecraft:dark_prismarine_slab": { + "runtime_id": -886, + "component_based": false + }, + "minecraft:dark_prismarine_stairs": { + "runtime_id": -3, + "component_based": false + }, + "minecraft:darkoak_standing_sign": { + "runtime_id": -192, + "component_based": false + }, + "minecraft:darkoak_wall_sign": { + "runtime_id": -193, + "component_based": false + }, + "minecraft:daylight_detector": { + "runtime_id": 151, + "component_based": false + }, + "minecraft:daylight_detector_inverted": { + "runtime_id": 178, + "component_based": false + }, + "minecraft:dead_brain_coral": { + "runtime_id": -586, + "component_based": false + }, + "minecraft:dead_brain_coral_block": { + "runtime_id": -854, + "component_based": false + }, + "minecraft:dead_brain_coral_fan": { + "runtime_id": -844, + "component_based": false + }, + "minecraft:dead_brain_coral_wall_fan": { + "runtime_id": -906, + "component_based": false + }, + "minecraft:dead_bubble_coral": { + "runtime_id": -587, + "component_based": false + }, + "minecraft:dead_bubble_coral_block": { + "runtime_id": -855, + "component_based": false + }, + "minecraft:dead_bubble_coral_fan": { + "runtime_id": -845, + "component_based": false + }, + "minecraft:dead_bubble_coral_wall_fan": { + "runtime_id": -908, + "component_based": false + }, + "minecraft:dead_fire_coral": { + "runtime_id": -588, + "component_based": false + }, + "minecraft:dead_fire_coral_block": { + "runtime_id": -856, + "component_based": false + }, + "minecraft:dead_fire_coral_fan": { + "runtime_id": -846, + "component_based": false + }, + "minecraft:dead_fire_coral_wall_fan": { + "runtime_id": -909, + "component_based": false + }, + "minecraft:dead_horn_coral": { + "runtime_id": -589, + "component_based": false + }, + "minecraft:dead_horn_coral_block": { + "runtime_id": -857, + "component_based": false + }, + "minecraft:dead_horn_coral_fan": { + "runtime_id": -847, + "component_based": false + }, + "minecraft:dead_horn_coral_wall_fan": { + "runtime_id": -910, + "component_based": false + }, + "minecraft:dead_tube_coral": { + "runtime_id": -585, + "component_based": false + }, + "minecraft:dead_tube_coral_block": { + "runtime_id": -853, + "component_based": false + }, + "minecraft:dead_tube_coral_fan": { + "runtime_id": -134, + "component_based": false + }, + "minecraft:dead_tube_coral_wall_fan": { + "runtime_id": -905, + "component_based": false + }, + "minecraft:deadbush": { + "runtime_id": 32, + "component_based": false + }, + "minecraft:debug_stick": { + "runtime_id": 626, + "component_based": false + }, + "minecraft:decorated_pot": { + "runtime_id": -551, + "component_based": false + }, + "minecraft:deepslate": { + "runtime_id": -378, + "component_based": false + }, + "minecraft:deepslate_brick_double_slab": { + "runtime_id": -399, + "component_based": false + }, + "minecraft:deepslate_brick_slab": { + "runtime_id": -392, + "component_based": false + }, + "minecraft:deepslate_brick_stairs": { + "runtime_id": -393, + "component_based": false + }, + "minecraft:deepslate_brick_wall": { + "runtime_id": -394, + "component_based": false + }, + "minecraft:deepslate_bricks": { + "runtime_id": -391, + "component_based": false + }, + "minecraft:deepslate_coal_ore": { + "runtime_id": -406, + "component_based": false + }, + "minecraft:deepslate_copper_ore": { + "runtime_id": -408, + "component_based": false + }, + "minecraft:deepslate_diamond_ore": { + "runtime_id": -405, + "component_based": false + }, + "minecraft:deepslate_emerald_ore": { + "runtime_id": -407, + "component_based": false + }, + "minecraft:deepslate_gold_ore": { + "runtime_id": -402, + "component_based": false + }, + "minecraft:deepslate_iron_ore": { + "runtime_id": -401, + "component_based": false + }, + "minecraft:deepslate_lapis_ore": { + "runtime_id": -400, + "component_based": false + }, + "minecraft:deepslate_redstone_ore": { + "runtime_id": -403, + "component_based": false + }, + "minecraft:deepslate_tile_double_slab": { + "runtime_id": -398, + "component_based": false + }, + "minecraft:deepslate_tile_slab": { + "runtime_id": -388, + "component_based": false + }, + "minecraft:deepslate_tile_stairs": { + "runtime_id": -389, + "component_based": false + }, + "minecraft:deepslate_tile_wall": { + "runtime_id": -390, + "component_based": false + }, + "minecraft:deepslate_tiles": { + "runtime_id": -387, + "component_based": false + }, + "minecraft:deny": { + "runtime_id": 211, + "component_based": false + }, + "minecraft:deprecated_anvil": { + "runtime_id": -961, + "component_based": false + }, + "minecraft:deprecated_purpur_block_1": { + "runtime_id": -950, + "component_based": false + }, + "minecraft:deprecated_purpur_block_2": { + "runtime_id": -952, + "component_based": false + }, + "minecraft:detector_rail": { + "runtime_id": 28, + "component_based": false + }, + "minecraft:diamond": { + "runtime_id": 328, + "component_based": false + }, + "minecraft:diamond_axe": { + "runtime_id": 343, + "component_based": false + }, + "minecraft:diamond_block": { + "runtime_id": 57, + "component_based": false + }, + "minecraft:diamond_boots": { + "runtime_id": 375, + "component_based": false + }, + "minecraft:diamond_chestplate": { + "runtime_id": 373, + "component_based": false + }, + "minecraft:diamond_helmet": { + "runtime_id": 372, + "component_based": false + }, + "minecraft:diamond_hoe": { + "runtime_id": 357, + "component_based": false + }, + "minecraft:diamond_horse_armor": { + "runtime_id": 566, + "component_based": false + }, + "minecraft:diamond_leggings": { + "runtime_id": 374, + "component_based": false + }, + "minecraft:diamond_ore": { + "runtime_id": 56, + "component_based": false + }, + "minecraft:diamond_pickaxe": { + "runtime_id": 342, + "component_based": false + }, + "minecraft:diamond_shovel": { + "runtime_id": 341, + "component_based": false + }, + "minecraft:diamond_sword": { + "runtime_id": 340, + "component_based": false + }, + "minecraft:diorite": { + "runtime_id": -592, + "component_based": false + }, + "minecraft:diorite_double_slab": { + "runtime_id": -921, + "component_based": false + }, + "minecraft:diorite_slab": { + "runtime_id": -894, + "component_based": false + }, + "minecraft:diorite_stairs": { + "runtime_id": -170, + "component_based": false + }, + "minecraft:diorite_wall": { + "runtime_id": -973, + "component_based": false + }, + "minecraft:dirt": { + "runtime_id": 3, + "component_based": false + }, + "minecraft:dirt_with_roots": { + "runtime_id": -318, + "component_based": false + }, + "minecraft:disc_fragment_5": { + "runtime_id": 675, + "component_based": false + }, + "minecraft:dispenser": { + "runtime_id": 23, + "component_based": false + }, + "minecraft:dolphin_spawn_egg": { + "runtime_id": 512, + "component_based": false + }, + "minecraft:donkey_spawn_egg": { + "runtime_id": 493, + "component_based": false + }, + "minecraft:double_cut_copper_slab": { + "runtime_id": -368, + "component_based": false + }, + "minecraft:double_plant": { + "runtime_id": 771, + "component_based": false + }, + "minecraft:double_stone_block_slab": { + "runtime_id": 760, + "component_based": false + }, + "minecraft:double_stone_block_slab2": { + "runtime_id": 761, + "component_based": false + }, + "minecraft:double_stone_block_slab3": { + "runtime_id": 762, + "component_based": false + }, + "minecraft:double_stone_block_slab4": { + "runtime_id": 763, + "component_based": false + }, + "minecraft:dragon_breath": { + "runtime_id": 593, + "component_based": false + }, + "minecraft:dragon_egg": { + "runtime_id": 122, + "component_based": false + }, + "minecraft:dragon_head": { + "runtime_id": -969, + "component_based": false + }, + "minecraft:dried_kelp": { + "runtime_id": 292, + "component_based": false + }, + "minecraft:dried_kelp_block": { + "runtime_id": -139, + "component_based": false + }, + "minecraft:dripstone_block": { + "runtime_id": -317, + "component_based": false + }, + "minecraft:dropper": { + "runtime_id": 125, + "component_based": false + }, + "minecraft:drowned_spawn_egg": { + "runtime_id": 511, + "component_based": false + }, + "minecraft:dune_armor_trim_smithing_template": { + "runtime_id": 720, + "component_based": false + }, + "minecraft:dye": { + "runtime_id": 793, + "component_based": false + }, + "minecraft:echo_shard": { + "runtime_id": 685, + "component_based": false + }, + "minecraft:egg": { + "runtime_id": 416, + "component_based": false + }, + "minecraft:elder_guardian_spawn_egg": { + "runtime_id": 499, + "component_based": false + }, + "minecraft:element_0": { + "runtime_id": 36, + "component_based": false + }, + "minecraft:element_1": { + "runtime_id": -12, + "component_based": false + }, + "minecraft:element_10": { + "runtime_id": -21, + "component_based": false + }, + "minecraft:element_100": { + "runtime_id": -111, + "component_based": false + }, + "minecraft:element_101": { + "runtime_id": -112, + "component_based": false + }, + "minecraft:element_102": { + "runtime_id": -113, + "component_based": false + }, + "minecraft:element_103": { + "runtime_id": -114, + "component_based": false + }, + "minecraft:element_104": { + "runtime_id": -115, + "component_based": false + }, + "minecraft:element_105": { + "runtime_id": -116, + "component_based": false + }, + "minecraft:element_106": { + "runtime_id": -117, + "component_based": false + }, + "minecraft:element_107": { + "runtime_id": -118, + "component_based": false + }, + "minecraft:element_108": { + "runtime_id": -119, + "component_based": false + }, + "minecraft:element_109": { + "runtime_id": -120, + "component_based": false + }, + "minecraft:element_11": { + "runtime_id": -22, + "component_based": false + }, + "minecraft:element_110": { + "runtime_id": -121, + "component_based": false + }, + "minecraft:element_111": { + "runtime_id": -122, + "component_based": false + }, + "minecraft:element_112": { + "runtime_id": -123, + "component_based": false + }, + "minecraft:element_113": { + "runtime_id": -124, + "component_based": false + }, + "minecraft:element_114": { + "runtime_id": -125, + "component_based": false + }, + "minecraft:element_115": { + "runtime_id": -126, + "component_based": false + }, + "minecraft:element_116": { + "runtime_id": -127, + "component_based": false + }, + "minecraft:element_117": { + "runtime_id": -128, + "component_based": false + }, + "minecraft:element_118": { + "runtime_id": -129, + "component_based": false + }, + "minecraft:element_12": { + "runtime_id": -23, + "component_based": false + }, + "minecraft:element_13": { + "runtime_id": -24, + "component_based": false + }, + "minecraft:element_14": { + "runtime_id": -25, + "component_based": false + }, + "minecraft:element_15": { + "runtime_id": -26, + "component_based": false + }, + "minecraft:element_16": { + "runtime_id": -27, + "component_based": false + }, + "minecraft:element_17": { + "runtime_id": -28, + "component_based": false + }, + "minecraft:element_18": { + "runtime_id": -29, + "component_based": false + }, + "minecraft:element_19": { + "runtime_id": -30, + "component_based": false + }, + "minecraft:element_2": { + "runtime_id": -13, + "component_based": false + }, + "minecraft:element_20": { + "runtime_id": -31, + "component_based": false + }, + "minecraft:element_21": { + "runtime_id": -32, + "component_based": false + }, + "minecraft:element_22": { + "runtime_id": -33, + "component_based": false + }, + "minecraft:element_23": { + "runtime_id": -34, + "component_based": false + }, + "minecraft:element_24": { + "runtime_id": -35, + "component_based": false + }, + "minecraft:element_25": { + "runtime_id": -36, + "component_based": false + }, + "minecraft:element_26": { + "runtime_id": -37, + "component_based": false + }, + "minecraft:element_27": { + "runtime_id": -38, + "component_based": false + }, + "minecraft:element_28": { + "runtime_id": -39, + "component_based": false + }, + "minecraft:element_29": { + "runtime_id": -40, + "component_based": false + }, + "minecraft:element_3": { + "runtime_id": -14, + "component_based": false + }, + "minecraft:element_30": { + "runtime_id": -41, + "component_based": false + }, + "minecraft:element_31": { + "runtime_id": -42, + "component_based": false + }, + "minecraft:element_32": { + "runtime_id": -43, + "component_based": false + }, + "minecraft:element_33": { + "runtime_id": -44, + "component_based": false + }, + "minecraft:element_34": { + "runtime_id": -45, + "component_based": false + }, + "minecraft:element_35": { + "runtime_id": -46, + "component_based": false + }, + "minecraft:element_36": { + "runtime_id": -47, + "component_based": false + }, + "minecraft:element_37": { + "runtime_id": -48, + "component_based": false + }, + "minecraft:element_38": { + "runtime_id": -49, + "component_based": false + }, + "minecraft:element_39": { + "runtime_id": -50, + "component_based": false + }, + "minecraft:element_4": { + "runtime_id": -15, + "component_based": false + }, + "minecraft:element_40": { + "runtime_id": -51, + "component_based": false + }, + "minecraft:element_41": { + "runtime_id": -52, + "component_based": false + }, + "minecraft:element_42": { + "runtime_id": -53, + "component_based": false + }, + "minecraft:element_43": { + "runtime_id": -54, + "component_based": false + }, + "minecraft:element_44": { + "runtime_id": -55, + "component_based": false + }, + "minecraft:element_45": { + "runtime_id": -56, + "component_based": false + }, + "minecraft:element_46": { + "runtime_id": -57, + "component_based": false + }, + "minecraft:element_47": { + "runtime_id": -58, + "component_based": false + }, + "minecraft:element_48": { + "runtime_id": -59, + "component_based": false + }, + "minecraft:element_49": { + "runtime_id": -60, + "component_based": false + }, + "minecraft:element_5": { + "runtime_id": -16, + "component_based": false + }, + "minecraft:element_50": { + "runtime_id": -61, + "component_based": false + }, + "minecraft:element_51": { + "runtime_id": -62, + "component_based": false + }, + "minecraft:element_52": { + "runtime_id": -63, + "component_based": false + }, + "minecraft:element_53": { + "runtime_id": -64, + "component_based": false + }, + "minecraft:element_54": { + "runtime_id": -65, + "component_based": false + }, + "minecraft:element_55": { + "runtime_id": -66, + "component_based": false + }, + "minecraft:element_56": { + "runtime_id": -67, + "component_based": false + }, + "minecraft:element_57": { + "runtime_id": -68, + "component_based": false + }, + "minecraft:element_58": { + "runtime_id": -69, + "component_based": false + }, + "minecraft:element_59": { + "runtime_id": -70, + "component_based": false + }, + "minecraft:element_6": { + "runtime_id": -17, + "component_based": false + }, + "minecraft:element_60": { + "runtime_id": -71, + "component_based": false + }, + "minecraft:element_61": { + "runtime_id": -72, + "component_based": false + }, + "minecraft:element_62": { + "runtime_id": -73, + "component_based": false + }, + "minecraft:element_63": { + "runtime_id": -74, + "component_based": false + }, + "minecraft:element_64": { + "runtime_id": -75, + "component_based": false + }, + "minecraft:element_65": { + "runtime_id": -76, + "component_based": false + }, + "minecraft:element_66": { + "runtime_id": -77, + "component_based": false + }, + "minecraft:element_67": { + "runtime_id": -78, + "component_based": false + }, + "minecraft:element_68": { + "runtime_id": -79, + "component_based": false + }, + "minecraft:element_69": { + "runtime_id": -80, + "component_based": false + }, + "minecraft:element_7": { + "runtime_id": -18, + "component_based": false + }, + "minecraft:element_70": { + "runtime_id": -81, + "component_based": false + }, + "minecraft:element_71": { + "runtime_id": -82, + "component_based": false + }, + "minecraft:element_72": { + "runtime_id": -83, + "component_based": false + }, + "minecraft:element_73": { + "runtime_id": -84, + "component_based": false + }, + "minecraft:element_74": { + "runtime_id": -85, + "component_based": false + }, + "minecraft:element_75": { + "runtime_id": -86, + "component_based": false + }, + "minecraft:element_76": { + "runtime_id": -87, + "component_based": false + }, + "minecraft:element_77": { + "runtime_id": -88, + "component_based": false + }, + "minecraft:element_78": { + "runtime_id": -89, + "component_based": false + }, + "minecraft:element_79": { + "runtime_id": -90, + "component_based": false + }, + "minecraft:element_8": { + "runtime_id": -19, + "component_based": false + }, + "minecraft:element_80": { + "runtime_id": -91, + "component_based": false + }, + "minecraft:element_81": { + "runtime_id": -92, + "component_based": false + }, + "minecraft:element_82": { + "runtime_id": -93, + "component_based": false + }, + "minecraft:element_83": { + "runtime_id": -94, + "component_based": false + }, + "minecraft:element_84": { + "runtime_id": -95, + "component_based": false + }, + "minecraft:element_85": { + "runtime_id": -96, + "component_based": false + }, + "minecraft:element_86": { + "runtime_id": -97, + "component_based": false + }, + "minecraft:element_87": { + "runtime_id": -98, + "component_based": false + }, + "minecraft:element_88": { + "runtime_id": -99, + "component_based": false + }, + "minecraft:element_89": { + "runtime_id": -100, + "component_based": false + }, + "minecraft:element_9": { + "runtime_id": -20, + "component_based": false + }, + "minecraft:element_90": { + "runtime_id": -101, + "component_based": false + }, + "minecraft:element_91": { + "runtime_id": -102, + "component_based": false + }, + "minecraft:element_92": { + "runtime_id": -103, + "component_based": false + }, + "minecraft:element_93": { + "runtime_id": -104, + "component_based": false + }, + "minecraft:element_94": { + "runtime_id": -105, + "component_based": false + }, + "minecraft:element_95": { + "runtime_id": -106, + "component_based": false + }, + "minecraft:element_96": { + "runtime_id": -107, + "component_based": false + }, + "minecraft:element_97": { + "runtime_id": -108, + "component_based": false + }, + "minecraft:element_98": { + "runtime_id": -109, + "component_based": false + }, + "minecraft:element_99": { + "runtime_id": -110, + "component_based": false + }, + "minecraft:element_constructor": { + "runtime_id": -987, + "component_based": false + }, + "minecraft:elytra": { + "runtime_id": 597, + "component_based": false + }, + "minecraft:emerald": { + "runtime_id": 546, + "component_based": false + }, + "minecraft:emerald_block": { + "runtime_id": 133, + "component_based": false + }, + "minecraft:emerald_ore": { + "runtime_id": 129, + "component_based": false + }, + "minecraft:empty_map": { + "runtime_id": 549, + "component_based": false + }, + "minecraft:enchanted_book": { + "runtime_id": 554, + "component_based": false + }, + "minecraft:enchanted_golden_apple": { + "runtime_id": 281, + "component_based": false + }, + "minecraft:enchanting_table": { + "runtime_id": 116, + "component_based": false + }, + "minecraft:end_brick_stairs": { + "runtime_id": -178, + "component_based": false + }, + "minecraft:end_bricks": { + "runtime_id": 206, + "component_based": false + }, + "minecraft:end_crystal": { + "runtime_id": 796, + "component_based": false + }, + "minecraft:end_gateway": { + "runtime_id": 209, + "component_based": false + }, + "minecraft:end_portal": { + "runtime_id": 119, + "component_based": false + }, + "minecraft:end_portal_frame": { + "runtime_id": 120, + "component_based": false + }, + "minecraft:end_rod": { + "runtime_id": 208, + "component_based": false + }, + "minecraft:end_stone": { + "runtime_id": 121, + "component_based": false + }, + "minecraft:end_stone_brick_double_slab": { + "runtime_id": -167, + "component_based": false + }, + "minecraft:end_stone_brick_slab": { + "runtime_id": -162, + "component_based": false + }, + "minecraft:end_stone_brick_wall": { + "runtime_id": -980, + "component_based": false + }, + "minecraft:ender_chest": { + "runtime_id": 130, + "component_based": false + }, + "minecraft:ender_dragon_spawn_egg": { + "runtime_id": 535, + "component_based": false + }, + "minecraft:ender_eye": { + "runtime_id": 460, + "component_based": false + }, + "minecraft:ender_pearl": { + "runtime_id": 448, + "component_based": false + }, + "minecraft:enderman_spawn_egg": { + "runtime_id": 469, + "component_based": false + }, + "minecraft:endermite_spawn_egg": { + "runtime_id": 487, + "component_based": false + }, + "minecraft:evoker_spawn_egg": { + "runtime_id": 503, + "component_based": false + }, + "minecraft:experience_bottle": { + "runtime_id": 542, + "component_based": false + }, + "minecraft:explorer_pottery_sherd": { + "runtime_id": 701, + "component_based": false + }, + "minecraft:exposed_chiseled_copper": { + "runtime_id": -761, + "component_based": false + }, + "minecraft:exposed_copper": { + "runtime_id": -341, + "component_based": false + }, + "minecraft:exposed_copper_bulb": { + "runtime_id": -777, + "component_based": false + }, + "minecraft:exposed_copper_door": { + "runtime_id": -785, + "component_based": false + }, + "minecraft:exposed_copper_grate": { + "runtime_id": -769, + "component_based": false + }, + "minecraft:exposed_copper_trapdoor": { + "runtime_id": -793, + "component_based": false + }, + "minecraft:exposed_cut_copper": { + "runtime_id": -348, + "component_based": false + }, + "minecraft:exposed_cut_copper_slab": { + "runtime_id": -362, + "component_based": false + }, + "minecraft:exposed_cut_copper_stairs": { + "runtime_id": -355, + "component_based": false + }, + "minecraft:exposed_double_cut_copper_slab": { + "runtime_id": -369, + "component_based": false + }, + "minecraft:eye_armor_trim_smithing_template": { + "runtime_id": 724, + "component_based": false + }, + "minecraft:farmland": { + "runtime_id": 60, + "component_based": false + }, + "minecraft:feather": { + "runtime_id": 352, + "component_based": false + }, + "minecraft:fence": { + "runtime_id": 753, + "component_based": false + }, + "minecraft:fence_gate": { + "runtime_id": 107, + "component_based": false + }, + "minecraft:fermented_spider_eye": { + "runtime_id": 455, + "component_based": false + }, + "minecraft:fern": { + "runtime_id": -848, + "component_based": false + }, + "minecraft:field_masoned_banner_pattern": { + "runtime_id": 618, + "component_based": false + }, + "minecraft:filled_map": { + "runtime_id": 446, + "component_based": false + }, + "minecraft:fire": { + "runtime_id": 51, + "component_based": false + }, + "minecraft:fire_charge": { + "runtime_id": 543, + "component_based": false + }, + "minecraft:fire_coral": { + "runtime_id": -583, + "component_based": false + }, + "minecraft:fire_coral_block": { + "runtime_id": -851, + "component_based": false + }, + "minecraft:fire_coral_fan": { + "runtime_id": -842, + "component_based": false + }, + "minecraft:fire_coral_wall_fan": { + "runtime_id": -907, + "component_based": false + }, + "minecraft:firework_rocket": { + "runtime_id": 552, + "component_based": false + }, + "minecraft:firework_star": { + "runtime_id": 553, + "component_based": false + }, + "minecraft:fishing_rod": { + "runtime_id": 418, + "component_based": true + }, + "minecraft:fletching_table": { + "runtime_id": -201, + "component_based": false + }, + "minecraft:flint": { + "runtime_id": 381, + "component_based": false + }, + "minecraft:flint_and_steel": { + "runtime_id": 323, + "component_based": false + }, + "minecraft:flow_armor_trim_smithing_template": { + "runtime_id": 735, + "component_based": false + }, + "minecraft:flow_banner_pattern": { + "runtime_id": 622, + "component_based": false + }, + "minecraft:flow_pottery_sherd": { + "runtime_id": 702, + "component_based": false + }, + "minecraft:flower_banner_pattern": { + "runtime_id": 614, + "component_based": false + }, + "minecraft:flower_pot": { + "runtime_id": 548, + "component_based": true + }, + "minecraft:flowering_azalea": { + "runtime_id": -338, + "component_based": false + }, + "minecraft:flowing_lava": { + "runtime_id": 10, + "component_based": false + }, + "minecraft:flowing_water": { + "runtime_id": 8, + "component_based": false + }, + "minecraft:fox_spawn_egg": { + "runtime_id": 518, + "component_based": false + }, + "minecraft:frame": { + "runtime_id": 547, + "component_based": true + }, + "minecraft:friend_pottery_sherd": { + "runtime_id": 703, + "component_based": false + }, + "minecraft:frog_spawn": { + "runtime_id": -468, + "component_based": false + }, + "minecraft:frog_spawn_egg": { + "runtime_id": 666, + "component_based": false + }, + "minecraft:frosted_ice": { + "runtime_id": 207, + "component_based": false + }, + "minecraft:furnace": { + "runtime_id": 61, + "component_based": false + }, + "minecraft:ghast_spawn_egg": { + "runtime_id": 481, + "component_based": false + }, + "minecraft:ghast_tear": { + "runtime_id": 451, + "component_based": false + }, + "minecraft:gilded_blackstone": { + "runtime_id": -281, + "component_based": false + }, + "minecraft:glass": { + "runtime_id": 20, + "component_based": false + }, + "minecraft:glass_bottle": { + "runtime_id": 454, + "component_based": false + }, + "minecraft:glass_pane": { + "runtime_id": 102, + "component_based": false + }, + "minecraft:glistering_melon_slice": { + "runtime_id": 461, + "component_based": false + }, + "minecraft:globe_banner_pattern": { + "runtime_id": 621, + "component_based": false + }, + "minecraft:glow_berries": { + "runtime_id": 797, + "component_based": false + }, + "minecraft:glow_frame": { + "runtime_id": 661, + "component_based": true + }, + "minecraft:glow_ink_sac": { + "runtime_id": 537, + "component_based": false + }, + "minecraft:glow_lichen": { + "runtime_id": -411, + "component_based": false + }, + "minecraft:glow_squid_spawn_egg": { + "runtime_id": 532, + "component_based": false + }, + "minecraft:glow_stick": { + "runtime_id": 639, + "component_based": false + }, + "minecraft:glowingobsidian": { + "runtime_id": 246, + "component_based": false + }, + "minecraft:glowstone": { + "runtime_id": 89, + "component_based": false + }, + "minecraft:glowstone_dust": { + "runtime_id": 420, + "component_based": false + }, + "minecraft:goat_horn": { + "runtime_id": 665, + "component_based": false + }, + "minecraft:goat_spawn_egg": { + "runtime_id": 531, + "component_based": false + }, + "minecraft:gold_block": { + "runtime_id": 41, + "component_based": false + }, + "minecraft:gold_ingot": { + "runtime_id": 330, + "component_based": false + }, + "minecraft:gold_nugget": { + "runtime_id": 452, + "component_based": false + }, + "minecraft:gold_ore": { + "runtime_id": 14, + "component_based": false + }, + "minecraft:golden_apple": { + "runtime_id": 280, + "component_based": false + }, + "minecraft:golden_axe": { + "runtime_id": 350, + "component_based": false + }, + "minecraft:golden_boots": { + "runtime_id": 379, + "component_based": false + }, + "minecraft:golden_carrot": { + "runtime_id": 305, + "component_based": false + }, + "minecraft:golden_chestplate": { + "runtime_id": 377, + "component_based": false + }, + "minecraft:golden_helmet": { + "runtime_id": 376, + "component_based": false + }, + "minecraft:golden_hoe": { + "runtime_id": 358, + "component_based": false + }, + "minecraft:golden_horse_armor": { + "runtime_id": 565, + "component_based": false + }, + "minecraft:golden_leggings": { + "runtime_id": 378, + "component_based": false + }, + "minecraft:golden_pickaxe": { + "runtime_id": 349, + "component_based": false + }, + "minecraft:golden_rail": { + "runtime_id": 27, + "component_based": false + }, + "minecraft:golden_shovel": { + "runtime_id": 348, + "component_based": false + }, + "minecraft:golden_sword": { + "runtime_id": 347, + "component_based": false + }, + "minecraft:granite": { + "runtime_id": -590, + "component_based": false + }, + "minecraft:granite_double_slab": { + "runtime_id": -923, + "component_based": false + }, + "minecraft:granite_slab": { + "runtime_id": -896, + "component_based": false + }, + "minecraft:granite_stairs": { + "runtime_id": -169, + "component_based": false + }, + "minecraft:granite_wall": { + "runtime_id": -972, + "component_based": false + }, + "minecraft:grass_block": { + "runtime_id": 2, + "component_based": false + }, + "minecraft:grass_path": { + "runtime_id": 198, + "component_based": false + }, + "minecraft:gravel": { + "runtime_id": 13, + "component_based": false + }, + "minecraft:gray_bundle": { + "runtime_id": 268, + "component_based": true + }, + "minecraft:gray_candle": { + "runtime_id": -420, + "component_based": false + }, + "minecraft:gray_candle_cake": { + "runtime_id": -437, + "component_based": false + }, + "minecraft:gray_carpet": { + "runtime_id": -603, + "component_based": false + }, + "minecraft:gray_concrete": { + "runtime_id": -634, + "component_based": false + }, + "minecraft:gray_concrete_powder": { + "runtime_id": -715, + "component_based": false + }, + "minecraft:gray_dye": { + "runtime_id": 429, + "component_based": false + }, + "minecraft:gray_glazed_terracotta": { + "runtime_id": 227, + "component_based": false + }, + "minecraft:gray_shulker_box": { + "runtime_id": -619, + "component_based": false + }, + "minecraft:gray_stained_glass": { + "runtime_id": -679, + "component_based": false + }, + "minecraft:gray_stained_glass_pane": { + "runtime_id": -649, + "component_based": false + }, + "minecraft:gray_terracotta": { + "runtime_id": -730, + "component_based": false + }, + "minecraft:gray_wool": { + "runtime_id": -553, + "component_based": false + }, + "minecraft:green_bundle": { + "runtime_id": 269, + "component_based": true + }, + "minecraft:green_candle": { + "runtime_id": -426, + "component_based": false + }, + "minecraft:green_candle_cake": { + "runtime_id": -443, + "component_based": false + }, + "minecraft:green_carpet": { + "runtime_id": -609, + "component_based": false + }, + "minecraft:green_concrete": { + "runtime_id": -640, + "component_based": false + }, + "minecraft:green_concrete_powder": { + "runtime_id": -721, + "component_based": false + }, + "minecraft:green_dye": { + "runtime_id": 423, + "component_based": false + }, + "minecraft:green_glazed_terracotta": { + "runtime_id": 233, + "component_based": false + }, + "minecraft:green_shulker_box": { + "runtime_id": -625, + "component_based": false + }, + "minecraft:green_stained_glass": { + "runtime_id": -685, + "component_based": false + }, + "minecraft:green_stained_glass_pane": { + "runtime_id": -655, + "component_based": false + }, + "minecraft:green_terracotta": { + "runtime_id": -736, + "component_based": false + }, + "minecraft:green_wool": { + "runtime_id": -560, + "component_based": false + }, + "minecraft:grindstone": { + "runtime_id": -195, + "component_based": false + }, + "minecraft:guardian_spawn_egg": { + "runtime_id": 488, + "component_based": false + }, + "minecraft:gunpowder": { + "runtime_id": 353, + "component_based": false + }, + "minecraft:guster_banner_pattern": { + "runtime_id": 623, + "component_based": false + }, + "minecraft:guster_pottery_sherd": { + "runtime_id": 704, + "component_based": false + }, + "minecraft:hanging_roots": { + "runtime_id": -319, + "component_based": false + }, + "minecraft:hard_black_stained_glass": { + "runtime_id": -702, + "component_based": false + }, + "minecraft:hard_black_stained_glass_pane": { + "runtime_id": -672, + "component_based": false + }, + "minecraft:hard_blue_stained_glass": { + "runtime_id": -698, + "component_based": false + }, + "minecraft:hard_blue_stained_glass_pane": { + "runtime_id": -668, + "component_based": false + }, + "minecraft:hard_brown_stained_glass": { + "runtime_id": -699, + "component_based": false + }, + "minecraft:hard_brown_stained_glass_pane": { + "runtime_id": -669, + "component_based": false + }, + "minecraft:hard_cyan_stained_glass": { + "runtime_id": -696, + "component_based": false + }, + "minecraft:hard_cyan_stained_glass_pane": { + "runtime_id": -666, + "component_based": false + }, + "minecraft:hard_glass": { + "runtime_id": 253, + "component_based": false + }, + "minecraft:hard_glass_pane": { + "runtime_id": 190, + "component_based": false + }, + "minecraft:hard_gray_stained_glass": { + "runtime_id": -694, + "component_based": false + }, + "minecraft:hard_gray_stained_glass_pane": { + "runtime_id": -664, + "component_based": false + }, + "minecraft:hard_green_stained_glass": { + "runtime_id": -700, + "component_based": false + }, + "minecraft:hard_green_stained_glass_pane": { + "runtime_id": -670, + "component_based": false + }, + "minecraft:hard_light_blue_stained_glass": { + "runtime_id": -690, + "component_based": false + }, + "minecraft:hard_light_blue_stained_glass_pane": { + "runtime_id": -660, + "component_based": false + }, + "minecraft:hard_light_gray_stained_glass": { + "runtime_id": -695, + "component_based": false + }, + "minecraft:hard_light_gray_stained_glass_pane": { + "runtime_id": -665, + "component_based": false + }, + "minecraft:hard_lime_stained_glass": { + "runtime_id": -692, + "component_based": false + }, + "minecraft:hard_lime_stained_glass_pane": { + "runtime_id": -662, + "component_based": false + }, + "minecraft:hard_magenta_stained_glass": { + "runtime_id": -689, + "component_based": false + }, + "minecraft:hard_magenta_stained_glass_pane": { + "runtime_id": -659, + "component_based": false + }, + "minecraft:hard_orange_stained_glass": { + "runtime_id": -688, + "component_based": false + }, + "minecraft:hard_orange_stained_glass_pane": { + "runtime_id": -658, + "component_based": false + }, + "minecraft:hard_pink_stained_glass": { + "runtime_id": -693, + "component_based": false + }, + "minecraft:hard_pink_stained_glass_pane": { + "runtime_id": -663, + "component_based": false + }, + "minecraft:hard_purple_stained_glass": { + "runtime_id": -697, + "component_based": false + }, + "minecraft:hard_purple_stained_glass_pane": { + "runtime_id": -667, + "component_based": false + }, + "minecraft:hard_red_stained_glass": { + "runtime_id": -701, + "component_based": false + }, + "minecraft:hard_red_stained_glass_pane": { + "runtime_id": -671, + "component_based": false + }, + "minecraft:hard_stained_glass": { + "runtime_id": 787, + "component_based": false + }, + "minecraft:hard_stained_glass_pane": { + "runtime_id": 788, + "component_based": false + }, + "minecraft:hard_white_stained_glass": { + "runtime_id": 254, + "component_based": false + }, + "minecraft:hard_white_stained_glass_pane": { + "runtime_id": 191, + "component_based": false + }, + "minecraft:hard_yellow_stained_glass": { + "runtime_id": -691, + "component_based": false + }, + "minecraft:hard_yellow_stained_glass_pane": { + "runtime_id": -661, + "component_based": false + }, + "minecraft:hardened_clay": { + "runtime_id": 172, + "component_based": false + }, + "minecraft:hay_block": { + "runtime_id": 170, + "component_based": false + }, + "minecraft:heart_of_the_sea": { + "runtime_id": 604, + "component_based": false + }, + "minecraft:heart_pottery_sherd": { + "runtime_id": 705, + "component_based": false + }, + "minecraft:heartbreak_pottery_sherd": { + "runtime_id": 706, + "component_based": false + }, + "minecraft:heavy_core": { + "runtime_id": -316, + "component_based": false + }, + "minecraft:heavy_weighted_pressure_plate": { + "runtime_id": 148, + "component_based": false + }, + "minecraft:hoglin_spawn_egg": { + "runtime_id": 524, + "component_based": false + }, + "minecraft:honey_block": { + "runtime_id": -220, + "component_based": false + }, + "minecraft:honey_bottle": { + "runtime_id": 628, + "component_based": false + }, + "minecraft:honeycomb": { + "runtime_id": 627, + "component_based": false + }, + "minecraft:honeycomb_block": { + "runtime_id": -221, + "component_based": false + }, + "minecraft:hopper": { + "runtime_id": 560, + "component_based": true + }, + "minecraft:hopper_minecart": { + "runtime_id": 559, + "component_based": false + }, + "minecraft:horn_coral": { + "runtime_id": -584, + "component_based": false + }, + "minecraft:horn_coral_block": { + "runtime_id": -852, + "component_based": false + }, + "minecraft:horn_coral_fan": { + "runtime_id": -843, + "component_based": false + }, + "minecraft:horn_coral_wall_fan": { + "runtime_id": -137, + "component_based": false + }, + "minecraft:horse_spawn_egg": { + "runtime_id": 485, + "component_based": false + }, + "minecraft:host_armor_trim_smithing_template": { + "runtime_id": 734, + "component_based": false + }, + "minecraft:howl_pottery_sherd": { + "runtime_id": 707, + "component_based": false + }, + "minecraft:husk_spawn_egg": { + "runtime_id": 491, + "component_based": false + }, + "minecraft:ice": { + "runtime_id": 79, + "component_based": false + }, + "minecraft:ice_bomb": { + "runtime_id": 633, + "component_based": false + }, + "minecraft:infested_chiseled_stone_bricks": { + "runtime_id": -862, + "component_based": false + }, + "minecraft:infested_cobblestone": { + "runtime_id": -858, + "component_based": false + }, + "minecraft:infested_cracked_stone_bricks": { + "runtime_id": -861, + "component_based": false + }, + "minecraft:infested_deepslate": { + "runtime_id": -454, + "component_based": false + }, + "minecraft:infested_mossy_stone_bricks": { + "runtime_id": -860, + "component_based": false + }, + "minecraft:infested_stone": { + "runtime_id": 97, + "component_based": false + }, + "minecraft:infested_stone_bricks": { + "runtime_id": -859, + "component_based": false + }, + "minecraft:info_update": { + "runtime_id": 248, + "component_based": false + }, + "minecraft:info_update2": { + "runtime_id": 249, + "component_based": false + }, + "minecraft:ink_sac": { + "runtime_id": 439, + "component_based": false + }, + "minecraft:invisible_bedrock": { + "runtime_id": 95, + "component_based": false + }, + "minecraft:iron_axe": { + "runtime_id": 322, + "component_based": false + }, + "minecraft:iron_bars": { + "runtime_id": 101, + "component_based": false + }, + "minecraft:iron_block": { + "runtime_id": 42, + "component_based": false + }, + "minecraft:iron_boots": { + "runtime_id": 371, + "component_based": false + }, + "minecraft:iron_chestplate": { + "runtime_id": 369, + "component_based": false + }, + "minecraft:iron_door": { + "runtime_id": 397, + "component_based": false + }, + "minecraft:iron_golem_spawn_egg": { + "runtime_id": 533, + "component_based": false + }, + "minecraft:iron_helmet": { + "runtime_id": 368, + "component_based": false + }, + "minecraft:iron_hoe": { + "runtime_id": 356, + "component_based": false + }, + "minecraft:iron_horse_armor": { + "runtime_id": 564, + "component_based": false + }, + "minecraft:iron_ingot": { + "runtime_id": 329, + "component_based": false + }, + "minecraft:iron_leggings": { + "runtime_id": 370, + "component_based": false + }, + "minecraft:iron_nugget": { + "runtime_id": 602, + "component_based": false + }, + "minecraft:iron_ore": { + "runtime_id": 15, + "component_based": false + }, + "minecraft:iron_pickaxe": { + "runtime_id": 321, + "component_based": false + }, + "minecraft:iron_shovel": { + "runtime_id": 320, + "component_based": false + }, + "minecraft:iron_sword": { + "runtime_id": 331, + "component_based": false + }, + "minecraft:iron_trapdoor": { + "runtime_id": 167, + "component_based": false + }, + "minecraft:item.acacia_door": { + "runtime_id": 196, + "component_based": false + }, + "minecraft:item.bed": { + "runtime_id": 26, + "component_based": false + }, + "minecraft:item.beetroot": { + "runtime_id": 244, + "component_based": false + }, + "minecraft:item.birch_door": { + "runtime_id": 194, + "component_based": false + }, + "minecraft:item.brewing_stand": { + "runtime_id": 117, + "component_based": false + }, + "minecraft:item.cake": { + "runtime_id": 92, + "component_based": false + }, + "minecraft:item.camera": { + "runtime_id": 242, + "component_based": false + }, + "minecraft:item.campfire": { + "runtime_id": -209, + "component_based": false + }, + "minecraft:item.cauldron": { + "runtime_id": 118, + "component_based": false + }, + "minecraft:item.chain": { + "runtime_id": -286, + "component_based": false + }, + "minecraft:item.crimson_door": { + "runtime_id": -244, + "component_based": false + }, + "minecraft:item.dark_oak_door": { + "runtime_id": 197, + "component_based": false + }, + "minecraft:item.flower_pot": { + "runtime_id": 140, + "component_based": false + }, + "minecraft:item.frame": { + "runtime_id": 199, + "component_based": false + }, + "minecraft:item.glow_frame": { + "runtime_id": -339, + "component_based": false + }, + "minecraft:item.hopper": { + "runtime_id": 154, + "component_based": false + }, + "minecraft:item.iron_door": { + "runtime_id": 71, + "component_based": false + }, + "minecraft:item.jungle_door": { + "runtime_id": 195, + "component_based": false + }, + "minecraft:item.kelp": { + "runtime_id": -138, + "component_based": false + }, + "minecraft:item.mangrove_door": { + "runtime_id": -493, + "component_based": false + }, + "minecraft:item.nether_sprouts": { + "runtime_id": -238, + "component_based": false + }, + "minecraft:item.nether_wart": { + "runtime_id": 115, + "component_based": false + }, + "minecraft:item.reeds": { + "runtime_id": 83, + "component_based": false + }, + "minecraft:item.soul_campfire": { + "runtime_id": -290, + "component_based": false + }, + "minecraft:item.spruce_door": { + "runtime_id": 193, + "component_based": false + }, + "minecraft:item.warped_door": { + "runtime_id": -245, + "component_based": false + }, + "minecraft:item.wheat": { + "runtime_id": 59, + "component_based": false + }, + "minecraft:item.wooden_door": { + "runtime_id": 64, + "component_based": false + }, + "minecraft:jigsaw": { + "runtime_id": -211, + "component_based": false + }, + "minecraft:jukebox": { + "runtime_id": 84, + "component_based": false + }, + "minecraft:jungle_boat": { + "runtime_id": 403, + "component_based": false + }, + "minecraft:jungle_button": { + "runtime_id": -143, + "component_based": false + }, + "minecraft:jungle_chest_boat": { + "runtime_id": 678, + "component_based": false + }, + "minecraft:jungle_door": { + "runtime_id": 588, + "component_based": false + }, + "minecraft:jungle_double_slab": { + "runtime_id": -811, + "component_based": false + }, + "minecraft:jungle_fence": { + "runtime_id": -578, + "component_based": false + }, + "minecraft:jungle_fence_gate": { + "runtime_id": 185, + "component_based": false + }, + "minecraft:jungle_hanging_sign": { + "runtime_id": -503, + "component_based": false + }, + "minecraft:jungle_leaves": { + "runtime_id": -802, + "component_based": false + }, + "minecraft:jungle_log": { + "runtime_id": -571, + "component_based": false + }, + "minecraft:jungle_planks": { + "runtime_id": -741, + "component_based": false + }, + "minecraft:jungle_pressure_plate": { + "runtime_id": -153, + "component_based": false + }, + "minecraft:jungle_sapling": { + "runtime_id": -827, + "component_based": false + }, + "minecraft:jungle_sign": { + "runtime_id": 611, + "component_based": false + }, + "minecraft:jungle_slab": { + "runtime_id": -806, + "component_based": false + }, + "minecraft:jungle_stairs": { + "runtime_id": 136, + "component_based": false + }, + "minecraft:jungle_standing_sign": { + "runtime_id": -188, + "component_based": false + }, + "minecraft:jungle_trapdoor": { + "runtime_id": -148, + "component_based": false + }, + "minecraft:jungle_wall_sign": { + "runtime_id": -189, + "component_based": false + }, + "minecraft:jungle_wood": { + "runtime_id": -816, + "component_based": false + }, + "minecraft:kelp": { + "runtime_id": 408, + "component_based": true + }, + "minecraft:lab_table": { + "runtime_id": -988, + "component_based": false + }, + "minecraft:ladder": { + "runtime_id": 65, + "component_based": false + }, + "minecraft:lantern": { + "runtime_id": -208, + "component_based": false + }, + "minecraft:lapis_block": { + "runtime_id": 22, + "component_based": false + }, + "minecraft:lapis_lazuli": { + "runtime_id": 440, + "component_based": false + }, + "minecraft:lapis_ore": { + "runtime_id": 21, + "component_based": false + }, + "minecraft:large_amethyst_bud": { + "runtime_id": -330, + "component_based": false + }, + "minecraft:large_fern": { + "runtime_id": -865, + "component_based": false + }, + "minecraft:lava": { + "runtime_id": 11, + "component_based": false + }, + "minecraft:lava_bucket": { + "runtime_id": 388, + "component_based": false + }, + "minecraft:lead": { + "runtime_id": 580, + "component_based": false + }, + "minecraft:leather": { + "runtime_id": 407, + "component_based": false + }, + "minecraft:leather_boots": { + "runtime_id": 363, + "component_based": false + }, + "minecraft:leather_chestplate": { + "runtime_id": 361, + "component_based": false + }, + "minecraft:leather_helmet": { + "runtime_id": 360, + "component_based": false + }, + "minecraft:leather_horse_armor": { + "runtime_id": 563, + "component_based": false + }, + "minecraft:leather_leggings": { + "runtime_id": 362, + "component_based": false + }, + "minecraft:leaves": { + "runtime_id": 767, + "component_based": false + }, + "minecraft:leaves2": { + "runtime_id": 768, + "component_based": false + }, + "minecraft:lectern": { + "runtime_id": -194, + "component_based": false + }, + "minecraft:lever": { + "runtime_id": 69, + "component_based": false + }, + "minecraft:light_block": { + "runtime_id": 791, + "component_based": false + }, + "minecraft:light_block_0": { + "runtime_id": -215, + "component_based": false + }, + "minecraft:light_block_1": { + "runtime_id": -929, + "component_based": false + }, + "minecraft:light_block_10": { + "runtime_id": -938, + "component_based": false + }, + "minecraft:light_block_11": { + "runtime_id": -939, + "component_based": false + }, + "minecraft:light_block_12": { + "runtime_id": -940, + "component_based": false + }, + "minecraft:light_block_13": { + "runtime_id": -941, + "component_based": false + }, + "minecraft:light_block_14": { + "runtime_id": -942, + "component_based": false + }, + "minecraft:light_block_15": { + "runtime_id": -943, + "component_based": false + }, + "minecraft:light_block_2": { + "runtime_id": -930, + "component_based": false + }, + "minecraft:light_block_3": { + "runtime_id": -931, + "component_based": false + }, + "minecraft:light_block_4": { + "runtime_id": -932, + "component_based": false + }, + "minecraft:light_block_5": { + "runtime_id": -933, + "component_based": false + }, + "minecraft:light_block_6": { + "runtime_id": -934, + "component_based": false + }, + "minecraft:light_block_7": { + "runtime_id": -935, + "component_based": false + }, + "minecraft:light_block_8": { + "runtime_id": -936, + "component_based": false + }, + "minecraft:light_block_9": { + "runtime_id": -937, + "component_based": false + }, + "minecraft:light_blue_bundle": { + "runtime_id": 260, + "component_based": true + }, + "minecraft:light_blue_candle": { + "runtime_id": -416, + "component_based": false + }, + "minecraft:light_blue_candle_cake": { + "runtime_id": -433, + "component_based": false + }, + "minecraft:light_blue_carpet": { + "runtime_id": -599, + "component_based": false + }, + "minecraft:light_blue_concrete": { + "runtime_id": -630, + "component_based": false + }, + "minecraft:light_blue_concrete_powder": { + "runtime_id": -711, + "component_based": false + }, + "minecraft:light_blue_dye": { + "runtime_id": 433, + "component_based": false + }, + "minecraft:light_blue_glazed_terracotta": { + "runtime_id": 223, + "component_based": false + }, + "minecraft:light_blue_shulker_box": { + "runtime_id": -615, + "component_based": false + }, + "minecraft:light_blue_stained_glass": { + "runtime_id": -675, + "component_based": false + }, + "minecraft:light_blue_stained_glass_pane": { + "runtime_id": -645, + "component_based": false + }, + "minecraft:light_blue_terracotta": { + "runtime_id": -726, + "component_based": false + }, + "minecraft:light_blue_wool": { + "runtime_id": -562, + "component_based": false + }, + "minecraft:light_gray_bundle": { + "runtime_id": 263, + "component_based": true + }, + "minecraft:light_gray_candle": { + "runtime_id": -421, + "component_based": false + }, + "minecraft:light_gray_candle_cake": { + "runtime_id": -438, + "component_based": false + }, + "minecraft:light_gray_carpet": { + "runtime_id": -604, + "component_based": false + }, + "minecraft:light_gray_concrete": { + "runtime_id": -635, + "component_based": false + }, + "minecraft:light_gray_concrete_powder": { + "runtime_id": -716, + "component_based": false + }, + "minecraft:light_gray_dye": { + "runtime_id": 428, + "component_based": false + }, + "minecraft:light_gray_shulker_box": { + "runtime_id": -620, + "component_based": false + }, + "minecraft:light_gray_stained_glass": { + "runtime_id": -680, + "component_based": false + }, + "minecraft:light_gray_stained_glass_pane": { + "runtime_id": -650, + "component_based": false + }, + "minecraft:light_gray_terracotta": { + "runtime_id": -731, + "component_based": false + }, + "minecraft:light_gray_wool": { + "runtime_id": -552, + "component_based": false + }, + "minecraft:light_weighted_pressure_plate": { + "runtime_id": 147, + "component_based": false + }, + "minecraft:lightning_rod": { + "runtime_id": -312, + "component_based": false + }, + "minecraft:lilac": { + "runtime_id": -863, + "component_based": false + }, + "minecraft:lily_of_the_valley": { + "runtime_id": -839, + "component_based": false + }, + "minecraft:lime_bundle": { + "runtime_id": 270, + "component_based": true + }, + "minecraft:lime_candle": { + "runtime_id": -418, + "component_based": false + }, + "minecraft:lime_candle_cake": { + "runtime_id": -435, + "component_based": false + }, + "minecraft:lime_carpet": { + "runtime_id": -601, + "component_based": false + }, + "minecraft:lime_concrete": { + "runtime_id": -632, + "component_based": false + }, + "minecraft:lime_concrete_powder": { + "runtime_id": -713, + "component_based": false + }, + "minecraft:lime_dye": { + "runtime_id": 431, + "component_based": false + }, + "minecraft:lime_glazed_terracotta": { + "runtime_id": 225, + "component_based": false + }, + "minecraft:lime_shulker_box": { + "runtime_id": -617, + "component_based": false + }, + "minecraft:lime_stained_glass": { + "runtime_id": -677, + "component_based": false + }, + "minecraft:lime_stained_glass_pane": { + "runtime_id": -647, + "component_based": false + }, + "minecraft:lime_terracotta": { + "runtime_id": -728, + "component_based": false + }, + "minecraft:lime_wool": { + "runtime_id": -559, + "component_based": false + }, + "minecraft:lingering_potion": { + "runtime_id": 595, + "component_based": false + }, + "minecraft:lit_blast_furnace": { + "runtime_id": -214, + "component_based": false + }, + "minecraft:lit_deepslate_redstone_ore": { + "runtime_id": -404, + "component_based": false + }, + "minecraft:lit_furnace": { + "runtime_id": 62, + "component_based": false + }, + "minecraft:lit_pumpkin": { + "runtime_id": 91, + "component_based": false + }, + "minecraft:lit_redstone_lamp": { + "runtime_id": 124, + "component_based": false + }, + "minecraft:lit_redstone_ore": { + "runtime_id": 74, + "component_based": false + }, + "minecraft:lit_smoker": { + "runtime_id": -199, + "component_based": false + }, + "minecraft:llama_spawn_egg": { + "runtime_id": 501, + "component_based": false + }, + "minecraft:lodestone": { + "runtime_id": -222, + "component_based": false + }, + "minecraft:lodestone_compass": { + "runtime_id": 640, + "component_based": false + }, + "minecraft:log": { + "runtime_id": 752, + "component_based": false + }, + "minecraft:log2": { + "runtime_id": 775, + "component_based": false + }, + "minecraft:loom": { + "runtime_id": -204, + "component_based": false + }, + "minecraft:mace": { + "runtime_id": 344, + "component_based": false + }, + "minecraft:magenta_bundle": { + "runtime_id": 273, + "component_based": true + }, + "minecraft:magenta_candle": { + "runtime_id": -415, + "component_based": false + }, + "minecraft:magenta_candle_cake": { + "runtime_id": -432, + "component_based": false + }, + "minecraft:magenta_carpet": { + "runtime_id": -598, + "component_based": false + }, + "minecraft:magenta_concrete": { + "runtime_id": -629, + "component_based": false + }, + "minecraft:magenta_concrete_powder": { + "runtime_id": -710, + "component_based": false + }, + "minecraft:magenta_dye": { + "runtime_id": 434, + "component_based": false + }, + "minecraft:magenta_glazed_terracotta": { + "runtime_id": 222, + "component_based": false + }, + "minecraft:magenta_shulker_box": { + "runtime_id": -614, + "component_based": false + }, + "minecraft:magenta_stained_glass": { + "runtime_id": -674, + "component_based": false + }, + "minecraft:magenta_stained_glass_pane": { + "runtime_id": -644, + "component_based": false + }, + "minecraft:magenta_terracotta": { + "runtime_id": -725, + "component_based": false + }, + "minecraft:magenta_wool": { + "runtime_id": -565, + "component_based": false + }, + "minecraft:magma": { + "runtime_id": 213, + "component_based": false + }, + "minecraft:magma_cream": { + "runtime_id": 457, + "component_based": false + }, + "minecraft:magma_cube_spawn_egg": { + "runtime_id": 482, + "component_based": false + }, + "minecraft:mangrove_boat": { + "runtime_id": 673, + "component_based": false + }, + "minecraft:mangrove_button": { + "runtime_id": -487, + "component_based": false + }, + "minecraft:mangrove_chest_boat": { + "runtime_id": 682, + "component_based": false + }, + "minecraft:mangrove_door": { + "runtime_id": 671, + "component_based": false + }, + "minecraft:mangrove_double_slab": { + "runtime_id": -499, + "component_based": false + }, + "minecraft:mangrove_fence": { + "runtime_id": -491, + "component_based": false + }, + "minecraft:mangrove_fence_gate": { + "runtime_id": -492, + "component_based": false + }, + "minecraft:mangrove_hanging_sign": { + "runtime_id": -508, + "component_based": false + }, + "minecraft:mangrove_leaves": { + "runtime_id": -472, + "component_based": false + }, + "minecraft:mangrove_log": { + "runtime_id": -484, + "component_based": false + }, + "minecraft:mangrove_planks": { + "runtime_id": -486, + "component_based": false + }, + "minecraft:mangrove_pressure_plate": { + "runtime_id": -490, + "component_based": false + }, + "minecraft:mangrove_propagule": { + "runtime_id": -474, + "component_based": false + }, + "minecraft:mangrove_roots": { + "runtime_id": -482, + "component_based": false + }, + "minecraft:mangrove_sign": { + "runtime_id": 672, + "component_based": false + }, + "minecraft:mangrove_slab": { + "runtime_id": -489, + "component_based": false + }, + "minecraft:mangrove_stairs": { + "runtime_id": -488, + "component_based": false + }, + "minecraft:mangrove_standing_sign": { + "runtime_id": -494, + "component_based": false + }, + "minecraft:mangrove_trapdoor": { + "runtime_id": -496, + "component_based": false + }, + "minecraft:mangrove_wall_sign": { + "runtime_id": -495, + "component_based": false + }, + "minecraft:mangrove_wood": { + "runtime_id": -497, + "component_based": false + }, + "minecraft:material_reducer": { + "runtime_id": -986, + "component_based": false + }, + "minecraft:medicine": { + "runtime_id": 637, + "component_based": false + }, + "minecraft:medium_amethyst_bud": { + "runtime_id": -331, + "component_based": false + }, + "minecraft:melon_block": { + "runtime_id": 103, + "component_based": false + }, + "minecraft:melon_seeds": { + "runtime_id": 315, + "component_based": false + }, + "minecraft:melon_slice": { + "runtime_id": 294, + "component_based": false + }, + "minecraft:melon_stem": { + "runtime_id": 105, + "component_based": false + }, + "minecraft:milk_bucket": { + "runtime_id": 386, + "component_based": false + }, + "minecraft:minecart": { + "runtime_id": 395, + "component_based": false + }, + "minecraft:miner_pottery_sherd": { + "runtime_id": 708, + "component_based": false + }, + "minecraft:mob_spawner": { + "runtime_id": 52, + "component_based": false + }, + "minecraft:mojang_banner_pattern": { + "runtime_id": 617, + "component_based": false + }, + "minecraft:monster_egg": { + "runtime_id": 776, + "component_based": false + }, + "minecraft:mooshroom_spawn_egg": { + "runtime_id": 467, + "component_based": false + }, + "minecraft:moss_block": { + "runtime_id": -320, + "component_based": false + }, + "minecraft:moss_carpet": { + "runtime_id": -335, + "component_based": false + }, + "minecraft:mossy_cobblestone": { + "runtime_id": 48, + "component_based": false + }, + "minecraft:mossy_cobblestone_double_slab": { + "runtime_id": -915, + "component_based": false + }, + "minecraft:mossy_cobblestone_slab": { + "runtime_id": -888, + "component_based": false + }, + "minecraft:mossy_cobblestone_stairs": { + "runtime_id": -179, + "component_based": false + }, + "minecraft:mossy_cobblestone_wall": { + "runtime_id": -971, + "component_based": false + }, + "minecraft:mossy_stone_brick_double_slab": { + "runtime_id": -168, + "component_based": false + }, + "minecraft:mossy_stone_brick_slab": { + "runtime_id": -166, + "component_based": false + }, + "minecraft:mossy_stone_brick_stairs": { + "runtime_id": -175, + "component_based": false + }, + "minecraft:mossy_stone_brick_wall": { + "runtime_id": -978, + "component_based": false + }, + "minecraft:mossy_stone_bricks": { + "runtime_id": -868, + "component_based": false + }, + "minecraft:mourner_pottery_sherd": { + "runtime_id": 709, + "component_based": false + }, + "minecraft:moving_block": { + "runtime_id": 250, + "component_based": false + }, + "minecraft:mud": { + "runtime_id": -473, + "component_based": false + }, + "minecraft:mud_brick_double_slab": { + "runtime_id": -479, + "component_based": false + }, + "minecraft:mud_brick_slab": { + "runtime_id": -478, + "component_based": false + }, + "minecraft:mud_brick_stairs": { + "runtime_id": -480, + "component_based": false + }, + "minecraft:mud_brick_wall": { + "runtime_id": -481, + "component_based": false + }, + "minecraft:mud_bricks": { + "runtime_id": -475, + "component_based": false + }, + "minecraft:muddy_mangrove_roots": { + "runtime_id": -483, + "component_based": false + }, + "minecraft:mule_spawn_egg": { + "runtime_id": 494, + "component_based": false + }, + "minecraft:mushroom_stem": { + "runtime_id": -1008, + "component_based": false + }, + "minecraft:mushroom_stew": { + "runtime_id": 282, + "component_based": false + }, + "minecraft:music_disc_11": { + "runtime_id": 577, + "component_based": true + }, + "minecraft:music_disc_13": { + "runtime_id": 567, + "component_based": true + }, + "minecraft:music_disc_5": { + "runtime_id": 674, + "component_based": true + }, + "minecraft:music_disc_blocks": { + "runtime_id": 569, + "component_based": true + }, + "minecraft:music_disc_cat": { + "runtime_id": 568, + "component_based": true + }, + "minecraft:music_disc_chirp": { + "runtime_id": 570, + "component_based": true + }, + "minecraft:music_disc_creator": { + "runtime_id": 783, + "component_based": true + }, + "minecraft:music_disc_creator_music_box": { + "runtime_id": 784, + "component_based": true + }, + "minecraft:music_disc_far": { + "runtime_id": 571, + "component_based": true + }, + "minecraft:music_disc_mall": { + "runtime_id": 572, + "component_based": true + }, + "minecraft:music_disc_mellohi": { + "runtime_id": 573, + "component_based": true + }, + "minecraft:music_disc_otherside": { + "runtime_id": 664, + "component_based": true + }, + "minecraft:music_disc_pigstep": { + "runtime_id": 658, + "component_based": true + }, + "minecraft:music_disc_precipice": { + "runtime_id": 785, + "component_based": true + }, + "minecraft:music_disc_relic": { + "runtime_id": 737, + "component_based": true + }, + "minecraft:music_disc_stal": { + "runtime_id": 574, + "component_based": true + }, + "minecraft:music_disc_strad": { + "runtime_id": 575, + "component_based": true + }, + "minecraft:music_disc_wait": { + "runtime_id": 578, + "component_based": true + }, + "minecraft:music_disc_ward": { + "runtime_id": 576, + "component_based": true + }, + "minecraft:mutton": { + "runtime_id": 583, + "component_based": false + }, + "minecraft:mycelium": { + "runtime_id": 110, + "component_based": false + }, + "minecraft:name_tag": { + "runtime_id": 581, + "component_based": false + }, + "minecraft:nautilus_shell": { + "runtime_id": 603, + "component_based": false + }, + "minecraft:nether_brick": { + "runtime_id": 112, + "component_based": false + }, + "minecraft:nether_brick_double_slab": { + "runtime_id": -883, + "component_based": false + }, + "minecraft:nether_brick_fence": { + "runtime_id": 113, + "component_based": false + }, + "minecraft:nether_brick_slab": { + "runtime_id": -877, + "component_based": false + }, + "minecraft:nether_brick_stairs": { + "runtime_id": 114, + "component_based": false + }, + "minecraft:nether_brick_wall": { + "runtime_id": -979, + "component_based": false + }, + "minecraft:nether_gold_ore": { + "runtime_id": -288, + "component_based": false + }, + "minecraft:nether_sprouts": { + "runtime_id": 659, + "component_based": true + }, + "minecraft:nether_star": { + "runtime_id": 551, + "component_based": false + }, + "minecraft:nether_wart": { + "runtime_id": 316, + "component_based": false + }, + "minecraft:nether_wart_block": { + "runtime_id": 214, + "component_based": false + }, + "minecraft:netherbrick": { + "runtime_id": 556, + "component_based": false + }, + "minecraft:netherite_axe": { + "runtime_id": 644, + "component_based": false + }, + "minecraft:netherite_block": { + "runtime_id": -270, + "component_based": false + }, + "minecraft:netherite_boots": { + "runtime_id": 650, + "component_based": false + }, + "minecraft:netherite_chestplate": { + "runtime_id": 648, + "component_based": false + }, + "minecraft:netherite_helmet": { + "runtime_id": 647, + "component_based": false + }, + "minecraft:netherite_hoe": { + "runtime_id": 645, + "component_based": false + }, + "minecraft:netherite_ingot": { + "runtime_id": 646, + "component_based": false + }, + "minecraft:netherite_leggings": { + "runtime_id": 649, + "component_based": false + }, + "minecraft:netherite_pickaxe": { + "runtime_id": 643, + "component_based": false + }, + "minecraft:netherite_scrap": { + "runtime_id": 651, + "component_based": false + }, + "minecraft:netherite_shovel": { + "runtime_id": 642, + "component_based": false + }, + "minecraft:netherite_sword": { + "runtime_id": 641, + "component_based": false + }, + "minecraft:netherite_upgrade_smithing_template": { + "runtime_id": 718, + "component_based": false + }, + "minecraft:netherrack": { + "runtime_id": 87, + "component_based": false + }, + "minecraft:netherreactor": { + "runtime_id": 247, + "component_based": false + }, + "minecraft:normal_stone_double_slab": { + "runtime_id": -926, + "component_based": false + }, + "minecraft:normal_stone_slab": { + "runtime_id": -899, + "component_based": false + }, + "minecraft:normal_stone_stairs": { + "runtime_id": -180, + "component_based": false + }, + "minecraft:noteblock": { + "runtime_id": 25, + "component_based": false + }, + "minecraft:npc_spawn_egg": { + "runtime_id": 498, + "component_based": false + }, + "minecraft:oak_boat": { + "runtime_id": 401, + "component_based": false + }, + "minecraft:oak_chest_boat": { + "runtime_id": 676, + "component_based": false + }, + "minecraft:oak_double_slab": { + "runtime_id": 157, + "component_based": false + }, + "minecraft:oak_fence": { + "runtime_id": 85, + "component_based": false + }, + "minecraft:oak_hanging_sign": { + "runtime_id": -500, + "component_based": false + }, + "minecraft:oak_leaves": { + "runtime_id": 18, + "component_based": false + }, + "minecraft:oak_log": { + "runtime_id": 17, + "component_based": false + }, + "minecraft:oak_planks": { + "runtime_id": 5, + "component_based": false + }, + "minecraft:oak_sapling": { + "runtime_id": 6, + "component_based": false + }, + "minecraft:oak_sign": { + "runtime_id": 383, + "component_based": false + }, + "minecraft:oak_slab": { + "runtime_id": 158, + "component_based": false + }, + "minecraft:oak_stairs": { + "runtime_id": 53, + "component_based": false + }, + "minecraft:oak_wood": { + "runtime_id": -212, + "component_based": false + }, + "minecraft:observer": { + "runtime_id": 251, + "component_based": false + }, + "minecraft:obsidian": { + "runtime_id": 49, + "component_based": false + }, + "minecraft:ocelot_spawn_egg": { + "runtime_id": 478, + "component_based": false + }, + "minecraft:ochre_froglight": { + "runtime_id": -471, + "component_based": false + }, + "minecraft:ominous_bottle": { + "runtime_id": 629, + "component_based": false + }, + "minecraft:ominous_trial_key": { + "runtime_id": 275, + "component_based": true + }, + "minecraft:open_eyeblossom": { + "runtime_id": -1018, + "component_based": false + }, + "minecraft:orange_bundle": { + "runtime_id": 271, + "component_based": true + }, + "minecraft:orange_candle": { + "runtime_id": -414, + "component_based": false + }, + "minecraft:orange_candle_cake": { + "runtime_id": -431, + "component_based": false + }, + "minecraft:orange_carpet": { + "runtime_id": -597, + "component_based": false + }, + "minecraft:orange_concrete": { + "runtime_id": -628, + "component_based": false + }, + "minecraft:orange_concrete_powder": { + "runtime_id": -709, + "component_based": false + }, + "minecraft:orange_dye": { + "runtime_id": 435, + "component_based": false + }, + "minecraft:orange_glazed_terracotta": { + "runtime_id": 221, + "component_based": false + }, + "minecraft:orange_shulker_box": { + "runtime_id": -613, + "component_based": false + }, + "minecraft:orange_stained_glass": { + "runtime_id": -673, + "component_based": false + }, + "minecraft:orange_stained_glass_pane": { + "runtime_id": -643, + "component_based": false + }, + "minecraft:orange_terracotta": { + "runtime_id": -724, + "component_based": false + }, + "minecraft:orange_tulip": { + "runtime_id": -834, + "component_based": false + }, + "minecraft:orange_wool": { + "runtime_id": -557, + "component_based": false + }, + "minecraft:oxeye_daisy": { + "runtime_id": -837, + "component_based": false + }, + "minecraft:oxidized_chiseled_copper": { + "runtime_id": -763, + "component_based": false + }, + "minecraft:oxidized_copper": { + "runtime_id": -343, + "component_based": false + }, + "minecraft:oxidized_copper_bulb": { + "runtime_id": -779, + "component_based": false + }, + "minecraft:oxidized_copper_door": { + "runtime_id": -787, + "component_based": false + }, + "minecraft:oxidized_copper_grate": { + "runtime_id": -771, + "component_based": false + }, + "minecraft:oxidized_copper_trapdoor": { + "runtime_id": -795, + "component_based": false + }, + "minecraft:oxidized_cut_copper": { + "runtime_id": -350, + "component_based": false + }, + "minecraft:oxidized_cut_copper_slab": { + "runtime_id": -364, + "component_based": false + }, + "minecraft:oxidized_cut_copper_stairs": { + "runtime_id": -357, + "component_based": false + }, + "minecraft:oxidized_double_cut_copper_slab": { + "runtime_id": -371, + "component_based": false + }, + "minecraft:packed_ice": { + "runtime_id": 174, + "component_based": false + }, + "minecraft:packed_mud": { + "runtime_id": -477, + "component_based": false + }, + "minecraft:painting": { + "runtime_id": 382, + "component_based": false + }, + "minecraft:pale_hanging_moss": { + "runtime_id": -1011, + "component_based": false + }, + "minecraft:pale_moss_block": { + "runtime_id": -1009, + "component_based": false + }, + "minecraft:pale_moss_carpet": { + "runtime_id": -1010, + "component_based": false + }, + "minecraft:pale_oak_boat": { + "runtime_id": 745, + "component_based": false + }, + "minecraft:pale_oak_button": { + "runtime_id": -989, + "component_based": false + }, + "minecraft:pale_oak_chest_boat": { + "runtime_id": 746, + "component_based": false + }, + "minecraft:pale_oak_door": { + "runtime_id": -990, + "component_based": false + }, + "minecraft:pale_oak_double_slab": { + "runtime_id": -999, + "component_based": false + }, + "minecraft:pale_oak_fence": { + "runtime_id": -991, + "component_based": false + }, + "minecraft:pale_oak_fence_gate": { + "runtime_id": -992, + "component_based": false + }, + "minecraft:pale_oak_hanging_sign": { + "runtime_id": -993, + "component_based": false + }, + "minecraft:pale_oak_leaves": { + "runtime_id": -1007, + "component_based": false + }, + "minecraft:pale_oak_log": { + "runtime_id": -995, + "component_based": false + }, + "minecraft:pale_oak_planks": { + "runtime_id": -996, + "component_based": false + }, + "minecraft:pale_oak_pressure_plate": { + "runtime_id": -997, + "component_based": false + }, + "minecraft:pale_oak_sapling": { + "runtime_id": -1006, + "component_based": false + }, + "minecraft:pale_oak_sign": { + "runtime_id": 747, + "component_based": false + }, + "minecraft:pale_oak_slab": { + "runtime_id": -998, + "component_based": false + }, + "minecraft:pale_oak_stairs": { + "runtime_id": -1000, + "component_based": false + }, + "minecraft:pale_oak_standing_sign": { + "runtime_id": -1001, + "component_based": false + }, + "minecraft:pale_oak_trapdoor": { + "runtime_id": -1002, + "component_based": false + }, + "minecraft:pale_oak_wall_sign": { + "runtime_id": -1003, + "component_based": false + }, + "minecraft:pale_oak_wood": { + "runtime_id": -1005, + "component_based": false + }, + "minecraft:panda_spawn_egg": { + "runtime_id": 517, + "component_based": false + }, + "minecraft:paper": { + "runtime_id": 412, + "component_based": false + }, + "minecraft:parrot_spawn_egg": { + "runtime_id": 506, + "component_based": false + }, + "minecraft:pearlescent_froglight": { + "runtime_id": -469, + "component_based": false + }, + "minecraft:peony": { + "runtime_id": -867, + "component_based": false + }, + "minecraft:petrified_oak_double_slab": { + "runtime_id": -903, + "component_based": false + }, + "minecraft:petrified_oak_slab": { + "runtime_id": -902, + "component_based": false + }, + "minecraft:phantom_membrane": { + "runtime_id": 607, + "component_based": false + }, + "minecraft:phantom_spawn_egg": { + "runtime_id": 514, + "component_based": false + }, + "minecraft:pig_spawn_egg": { + "runtime_id": 464, + "component_based": false + }, + "minecraft:piglin_banner_pattern": { + "runtime_id": 620, + "component_based": false + }, + "minecraft:piglin_brute_spawn_egg": { + "runtime_id": 527, + "component_based": false + }, + "minecraft:piglin_head": { + "runtime_id": -970, + "component_based": false + }, + "minecraft:piglin_spawn_egg": { + "runtime_id": 525, + "component_based": false + }, + "minecraft:pillager_spawn_egg": { + "runtime_id": 519, + "component_based": false + }, + "minecraft:pink_bundle": { + "runtime_id": 264, + "component_based": true + }, + "minecraft:pink_candle": { + "runtime_id": -419, + "component_based": false + }, + "minecraft:pink_candle_cake": { + "runtime_id": -436, + "component_based": false + }, + "minecraft:pink_carpet": { + "runtime_id": -602, + "component_based": false + }, + "minecraft:pink_concrete": { + "runtime_id": -633, + "component_based": false + }, + "minecraft:pink_concrete_powder": { + "runtime_id": -714, + "component_based": false + }, + "minecraft:pink_dye": { + "runtime_id": 430, + "component_based": false + }, + "minecraft:pink_glazed_terracotta": { + "runtime_id": 226, + "component_based": false + }, + "minecraft:pink_petals": { + "runtime_id": -549, + "component_based": false + }, + "minecraft:pink_shulker_box": { + "runtime_id": -618, + "component_based": false + }, + "minecraft:pink_stained_glass": { + "runtime_id": -678, + "component_based": false + }, + "minecraft:pink_stained_glass_pane": { + "runtime_id": -648, + "component_based": false + }, + "minecraft:pink_terracotta": { + "runtime_id": -729, + "component_based": false + }, + "minecraft:pink_tulip": { + "runtime_id": -836, + "component_based": false + }, + "minecraft:pink_wool": { + "runtime_id": -566, + "component_based": false + }, + "minecraft:piston": { + "runtime_id": 33, + "component_based": false + }, + "minecraft:piston_arm_collision": { + "runtime_id": 34, + "component_based": false + }, + "minecraft:pitcher_crop": { + "runtime_id": -574, + "component_based": false + }, + "minecraft:pitcher_plant": { + "runtime_id": -612, + "component_based": false + }, + "minecraft:pitcher_pod": { + "runtime_id": 319, + "component_based": false + }, + "minecraft:planks": { + "runtime_id": 772, + "component_based": false + }, + "minecraft:player_head": { + "runtime_id": -967, + "component_based": false + }, + "minecraft:plenty_pottery_sherd": { + "runtime_id": 710, + "component_based": false + }, + "minecraft:podzol": { + "runtime_id": 243, + "component_based": false + }, + "minecraft:pointed_dripstone": { + "runtime_id": -308, + "component_based": false + }, + "minecraft:poisonous_potato": { + "runtime_id": 304, + "component_based": false + }, + "minecraft:polar_bear_spawn_egg": { + "runtime_id": 500, + "component_based": false + }, + "minecraft:polished_andesite": { + "runtime_id": -595, + "component_based": false + }, + "minecraft:polished_andesite_double_slab": { + "runtime_id": -919, + "component_based": false + }, + "minecraft:polished_andesite_slab": { + "runtime_id": -892, + "component_based": false + }, + "minecraft:polished_andesite_stairs": { + "runtime_id": -174, + "component_based": false + }, + "minecraft:polished_basalt": { + "runtime_id": -235, + "component_based": false + }, + "minecraft:polished_blackstone": { + "runtime_id": -291, + "component_based": false + }, + "minecraft:polished_blackstone_brick_double_slab": { + "runtime_id": -285, + "component_based": false + }, + "minecraft:polished_blackstone_brick_slab": { + "runtime_id": -284, + "component_based": false + }, + "minecraft:polished_blackstone_brick_stairs": { + "runtime_id": -275, + "component_based": false + }, + "minecraft:polished_blackstone_brick_wall": { + "runtime_id": -278, + "component_based": false + }, + "minecraft:polished_blackstone_bricks": { + "runtime_id": -274, + "component_based": false + }, + "minecraft:polished_blackstone_button": { + "runtime_id": -296, + "component_based": false + }, + "minecraft:polished_blackstone_double_slab": { + "runtime_id": -294, + "component_based": false + }, + "minecraft:polished_blackstone_pressure_plate": { + "runtime_id": -295, + "component_based": false + }, + "minecraft:polished_blackstone_slab": { + "runtime_id": -293, + "component_based": false + }, + "minecraft:polished_blackstone_stairs": { + "runtime_id": -292, + "component_based": false + }, + "minecraft:polished_blackstone_wall": { + "runtime_id": -297, + "component_based": false + }, + "minecraft:polished_deepslate": { + "runtime_id": -383, + "component_based": false + }, + "minecraft:polished_deepslate_double_slab": { + "runtime_id": -397, + "component_based": false + }, + "minecraft:polished_deepslate_slab": { + "runtime_id": -384, + "component_based": false + }, + "minecraft:polished_deepslate_stairs": { + "runtime_id": -385, + "component_based": false + }, + "minecraft:polished_deepslate_wall": { + "runtime_id": -386, + "component_based": false + }, + "minecraft:polished_diorite": { + "runtime_id": -593, + "component_based": false + }, + "minecraft:polished_diorite_double_slab": { + "runtime_id": -922, + "component_based": false + }, + "minecraft:polished_diorite_slab": { + "runtime_id": -895, + "component_based": false + }, + "minecraft:polished_diorite_stairs": { + "runtime_id": -173, + "component_based": false + }, + "minecraft:polished_granite": { + "runtime_id": -591, + "component_based": false + }, + "minecraft:polished_granite_double_slab": { + "runtime_id": -924, + "component_based": false + }, + "minecraft:polished_granite_slab": { + "runtime_id": -897, + "component_based": false + }, + "minecraft:polished_granite_stairs": { + "runtime_id": -172, + "component_based": false + }, + "minecraft:polished_tuff": { + "runtime_id": -748, + "component_based": false + }, + "minecraft:polished_tuff_double_slab": { + "runtime_id": -750, + "component_based": false + }, + "minecraft:polished_tuff_slab": { + "runtime_id": -749, + "component_based": false + }, + "minecraft:polished_tuff_stairs": { + "runtime_id": -751, + "component_based": false + }, + "minecraft:polished_tuff_wall": { + "runtime_id": -752, + "component_based": false + }, + "minecraft:popped_chorus_fruit": { + "runtime_id": 592, + "component_based": false + }, + "minecraft:poppy": { + "runtime_id": 38, + "component_based": false + }, + "minecraft:porkchop": { + "runtime_id": 284, + "component_based": false + }, + "minecraft:portal": { + "runtime_id": 90, + "component_based": false + }, + "minecraft:potato": { + "runtime_id": 302, + "component_based": false + }, + "minecraft:potatoes": { + "runtime_id": 142, + "component_based": false + }, + "minecraft:potion": { + "runtime_id": 453, + "component_based": false + }, + "minecraft:powder_snow": { + "runtime_id": -306, + "component_based": false + }, + "minecraft:powder_snow_bucket": { + "runtime_id": 393, + "component_based": false + }, + "minecraft:powered_comparator": { + "runtime_id": 150, + "component_based": false + }, + "minecraft:powered_repeater": { + "runtime_id": 94, + "component_based": false + }, + "minecraft:prismarine": { + "runtime_id": 168, + "component_based": false + }, + "minecraft:prismarine_brick_double_slab": { + "runtime_id": -914, + "component_based": false + }, + "minecraft:prismarine_brick_slab": { + "runtime_id": -887, + "component_based": false + }, + "minecraft:prismarine_bricks": { + "runtime_id": -948, + "component_based": false + }, + "minecraft:prismarine_bricks_stairs": { + "runtime_id": -4, + "component_based": false + }, + "minecraft:prismarine_crystals": { + "runtime_id": 582, + "component_based": false + }, + "minecraft:prismarine_double_slab": { + "runtime_id": -912, + "component_based": false + }, + "minecraft:prismarine_shard": { + "runtime_id": 598, + "component_based": false + }, + "minecraft:prismarine_slab": { + "runtime_id": -885, + "component_based": false + }, + "minecraft:prismarine_stairs": { + "runtime_id": -2, + "component_based": false + }, + "minecraft:prismarine_wall": { + "runtime_id": -981, + "component_based": false + }, + "minecraft:prize_pottery_sherd": { + "runtime_id": 711, + "component_based": false + }, + "minecraft:pufferfish": { + "runtime_id": 289, + "component_based": false + }, + "minecraft:pufferfish_bucket": { + "runtime_id": 392, + "component_based": false + }, + "minecraft:pufferfish_spawn_egg": { + "runtime_id": 509, + "component_based": false + }, + "minecraft:pumpkin": { + "runtime_id": 86, + "component_based": false + }, + "minecraft:pumpkin_pie": { + "runtime_id": 306, + "component_based": false + }, + "minecraft:pumpkin_seeds": { + "runtime_id": 314, + "component_based": false + }, + "minecraft:pumpkin_stem": { + "runtime_id": 104, + "component_based": false + }, + "minecraft:purple_bundle": { + "runtime_id": 266, + "component_based": true + }, + "minecraft:purple_candle": { + "runtime_id": -423, + "component_based": false + }, + "minecraft:purple_candle_cake": { + "runtime_id": -440, + "component_based": false + }, + "minecraft:purple_carpet": { + "runtime_id": -606, + "component_based": false + }, + "minecraft:purple_concrete": { + "runtime_id": -637, + "component_based": false + }, + "minecraft:purple_concrete_powder": { + "runtime_id": -718, + "component_based": false + }, + "minecraft:purple_dye": { + "runtime_id": 426, + "component_based": false + }, + "minecraft:purple_glazed_terracotta": { + "runtime_id": 219, + "component_based": false + }, + "minecraft:purple_shulker_box": { + "runtime_id": -622, + "component_based": false + }, + "minecraft:purple_stained_glass": { + "runtime_id": -682, + "component_based": false + }, + "minecraft:purple_stained_glass_pane": { + "runtime_id": -652, + "component_based": false + }, + "minecraft:purple_terracotta": { + "runtime_id": -733, + "component_based": false + }, + "minecraft:purple_wool": { + "runtime_id": -564, + "component_based": false + }, + "minecraft:purpur_block": { + "runtime_id": 201, + "component_based": false + }, + "minecraft:purpur_double_slab": { + "runtime_id": -911, + "component_based": false + }, + "minecraft:purpur_pillar": { + "runtime_id": -951, + "component_based": false + }, + "minecraft:purpur_slab": { + "runtime_id": -884, + "component_based": false + }, + "minecraft:purpur_stairs": { + "runtime_id": 203, + "component_based": false + }, + "minecraft:quartz": { + "runtime_id": 557, + "component_based": false + }, + "minecraft:quartz_block": { + "runtime_id": 155, + "component_based": false + }, + "minecraft:quartz_bricks": { + "runtime_id": -304, + "component_based": false + }, + "minecraft:quartz_double_slab": { + "runtime_id": -882, + "component_based": false + }, + "minecraft:quartz_ore": { + "runtime_id": 153, + "component_based": false + }, + "minecraft:quartz_pillar": { + "runtime_id": -954, + "component_based": false + }, + "minecraft:quartz_slab": { + "runtime_id": -876, + "component_based": false + }, + "minecraft:quartz_stairs": { + "runtime_id": 156, + "component_based": false + }, + "minecraft:rabbit": { + "runtime_id": 310, + "component_based": false + }, + "minecraft:rabbit_foot": { + "runtime_id": 561, + "component_based": false + }, + "minecraft:rabbit_hide": { + "runtime_id": 562, + "component_based": false + }, + "minecraft:rabbit_spawn_egg": { + "runtime_id": 486, + "component_based": false + }, + "minecraft:rabbit_stew": { + "runtime_id": 312, + "component_based": false + }, + "minecraft:rail": { + "runtime_id": 66, + "component_based": false + }, + "minecraft:raiser_armor_trim_smithing_template": { + "runtime_id": 732, + "component_based": false + }, + "minecraft:rapid_fertilizer": { + "runtime_id": 635, + "component_based": false + }, + "minecraft:ravager_spawn_egg": { + "runtime_id": 521, + "component_based": false + }, + "minecraft:raw_copper": { + "runtime_id": 541, + "component_based": false + }, + "minecraft:raw_copper_block": { + "runtime_id": -452, + "component_based": false + }, + "minecraft:raw_gold": { + "runtime_id": 540, + "component_based": false + }, + "minecraft:raw_gold_block": { + "runtime_id": -453, + "component_based": false + }, + "minecraft:raw_iron": { + "runtime_id": 539, + "component_based": false + }, + "minecraft:raw_iron_block": { + "runtime_id": -451, + "component_based": false + }, + "minecraft:recovery_compass": { + "runtime_id": 684, + "component_based": false + }, + "minecraft:red_bundle": { + "runtime_id": 272, + "component_based": true + }, + "minecraft:red_candle": { + "runtime_id": -427, + "component_based": false + }, + "minecraft:red_candle_cake": { + "runtime_id": -444, + "component_based": false + }, + "minecraft:red_carpet": { + "runtime_id": -610, + "component_based": false + }, + "minecraft:red_concrete": { + "runtime_id": -641, + "component_based": false + }, + "minecraft:red_concrete_powder": { + "runtime_id": -722, + "component_based": false + }, + "minecraft:red_dye": { + "runtime_id": 422, + "component_based": false + }, + "minecraft:red_flower": { + "runtime_id": 770, + "component_based": false + }, + "minecraft:red_glazed_terracotta": { + "runtime_id": 234, + "component_based": false + }, + "minecraft:red_mushroom": { + "runtime_id": 40, + "component_based": false + }, + "minecraft:red_mushroom_block": { + "runtime_id": 100, + "component_based": false + }, + "minecraft:red_nether_brick": { + "runtime_id": 215, + "component_based": false + }, + "minecraft:red_nether_brick_double_slab": { + "runtime_id": -917, + "component_based": false + }, + "minecraft:red_nether_brick_slab": { + "runtime_id": -890, + "component_based": false + }, + "minecraft:red_nether_brick_stairs": { + "runtime_id": -184, + "component_based": false + }, + "minecraft:red_nether_brick_wall": { + "runtime_id": -983, + "component_based": false + }, + "minecraft:red_sand": { + "runtime_id": -949, + "component_based": false + }, + "minecraft:red_sandstone": { + "runtime_id": 179, + "component_based": false + }, + "minecraft:red_sandstone_double_slab": { + "runtime_id": 181, + "component_based": false + }, + "minecraft:red_sandstone_slab": { + "runtime_id": 182, + "component_based": false + }, + "minecraft:red_sandstone_stairs": { + "runtime_id": 180, + "component_based": false + }, + "minecraft:red_sandstone_wall": { + "runtime_id": -982, + "component_based": false + }, + "minecraft:red_shulker_box": { + "runtime_id": -626, + "component_based": false + }, + "minecraft:red_stained_glass": { + "runtime_id": -686, + "component_based": false + }, + "minecraft:red_stained_glass_pane": { + "runtime_id": -656, + "component_based": false + }, + "minecraft:red_terracotta": { + "runtime_id": -737, + "component_based": false + }, + "minecraft:red_tulip": { + "runtime_id": -833, + "component_based": false + }, + "minecraft:red_wool": { + "runtime_id": -556, + "component_based": false + }, + "minecraft:redstone": { + "runtime_id": 398, + "component_based": false + }, + "minecraft:redstone_block": { + "runtime_id": 152, + "component_based": false + }, + "minecraft:redstone_lamp": { + "runtime_id": 123, + "component_based": false + }, + "minecraft:redstone_ore": { + "runtime_id": 73, + "component_based": false + }, + "minecraft:redstone_torch": { + "runtime_id": 76, + "component_based": false + }, + "minecraft:redstone_wire": { + "runtime_id": 55, + "component_based": false + }, + "minecraft:reinforced_deepslate": { + "runtime_id": -466, + "component_based": false + }, + "minecraft:repeater": { + "runtime_id": 445, + "component_based": true + }, + "minecraft:repeating_command_block": { + "runtime_id": 188, + "component_based": false + }, + "minecraft:reserved6": { + "runtime_id": 255, + "component_based": false + }, + "minecraft:resin_block": { + "runtime_id": -1021, + "component_based": false + }, + "minecraft:resin_brick": { + "runtime_id": 749, + "component_based": false + }, + "minecraft:resin_brick_double_slab": { + "runtime_id": -1015, + "component_based": false + }, + "minecraft:resin_brick_slab": { + "runtime_id": -1014, + "component_based": false + }, + "minecraft:resin_brick_stairs": { + "runtime_id": -1016, + "component_based": false + }, + "minecraft:resin_brick_wall": { + "runtime_id": -1017, + "component_based": false + }, + "minecraft:resin_bricks": { + "runtime_id": -1013, + "component_based": false + }, + "minecraft:resin_clump": { + "runtime_id": -1022, + "component_based": false + }, + "minecraft:respawn_anchor": { + "runtime_id": -272, + "component_based": false + }, + "minecraft:rib_armor_trim_smithing_template": { + "runtime_id": 728, + "component_based": false + }, + "minecraft:rose_bush": { + "runtime_id": -866, + "component_based": false + }, + "minecraft:rotten_flesh": { + "runtime_id": 299, + "component_based": false + }, + "minecraft:saddle": { + "runtime_id": 396, + "component_based": false + }, + "minecraft:salmon": { + "runtime_id": 287, + "component_based": false + }, + "minecraft:salmon_bucket": { + "runtime_id": 390, + "component_based": false + }, + "minecraft:salmon_spawn_egg": { + "runtime_id": 510, + "component_based": false + }, + "minecraft:sand": { + "runtime_id": 12, + "component_based": false + }, + "minecraft:sandstone": { + "runtime_id": 24, + "component_based": false + }, + "minecraft:sandstone_double_slab": { + "runtime_id": -878, + "component_based": false + }, + "minecraft:sandstone_slab": { + "runtime_id": -872, + "component_based": false + }, + "minecraft:sandstone_stairs": { + "runtime_id": 128, + "component_based": false + }, + "minecraft:sandstone_wall": { + "runtime_id": -975, + "component_based": false + }, + "minecraft:sapling": { + "runtime_id": 766, + "component_based": false + }, + "minecraft:scaffolding": { + "runtime_id": -165, + "component_based": false + }, + "minecraft:scrape_pottery_sherd": { + "runtime_id": 712, + "component_based": false + }, + "minecraft:sculk": { + "runtime_id": -458, + "component_based": false + }, + "minecraft:sculk_catalyst": { + "runtime_id": -460, + "component_based": false + }, + "minecraft:sculk_sensor": { + "runtime_id": -307, + "component_based": false + }, + "minecraft:sculk_shrieker": { + "runtime_id": -461, + "component_based": false + }, + "minecraft:sculk_vein": { + "runtime_id": -459, + "component_based": false + }, + "minecraft:sea_lantern": { + "runtime_id": 169, + "component_based": false + }, + "minecraft:sea_pickle": { + "runtime_id": -156, + "component_based": false + }, + "minecraft:seagrass": { + "runtime_id": -130, + "component_based": false + }, + "minecraft:sentry_armor_trim_smithing_template": { + "runtime_id": 719, + "component_based": false + }, + "minecraft:shaper_armor_trim_smithing_template": { + "runtime_id": 733, + "component_based": false + }, + "minecraft:sheaf_pottery_sherd": { + "runtime_id": 713, + "component_based": false + }, + "minecraft:shears": { + "runtime_id": 447, + "component_based": false + }, + "minecraft:sheep_spawn_egg": { + "runtime_id": 465, + "component_based": false + }, + "minecraft:shelter_pottery_sherd": { + "runtime_id": 714, + "component_based": false + }, + "minecraft:shield": { + "runtime_id": 380, + "component_based": false + }, + "minecraft:short_grass": { + "runtime_id": 31, + "component_based": false + }, + "minecraft:shroomlight": { + "runtime_id": -230, + "component_based": false + }, + "minecraft:shulker_box": { + "runtime_id": 781, + "component_based": false + }, + "minecraft:shulker_shell": { + "runtime_id": 599, + "component_based": false + }, + "minecraft:shulker_spawn_egg": { + "runtime_id": 497, + "component_based": false + }, + "minecraft:silence_armor_trim_smithing_template": { + "runtime_id": 730, + "component_based": false + }, + "minecraft:silver_glazed_terracotta": { + "runtime_id": 228, + "component_based": false + }, + "minecraft:silverfish_spawn_egg": { + "runtime_id": 470, + "component_based": false + }, + "minecraft:skeleton_horse_spawn_egg": { + "runtime_id": 495, + "component_based": false + }, + "minecraft:skeleton_skull": { + "runtime_id": 144, + "component_based": false + }, + "minecraft:skeleton_spawn_egg": { + "runtime_id": 471, + "component_based": false + }, + "minecraft:skull": { + "runtime_id": 738, + "component_based": false + }, + "minecraft:skull_banner_pattern": { + "runtime_id": 616, + "component_based": false + }, + "minecraft:skull_pottery_sherd": { + "runtime_id": 715, + "component_based": false + }, + "minecraft:slime": { + "runtime_id": 165, + "component_based": false + }, + "minecraft:slime_ball": { + "runtime_id": 414, + "component_based": false + }, + "minecraft:slime_spawn_egg": { + "runtime_id": 472, + "component_based": false + }, + "minecraft:small_amethyst_bud": { + "runtime_id": -332, + "component_based": false + }, + "minecraft:small_dripleaf_block": { + "runtime_id": -336, + "component_based": false + }, + "minecraft:smithing_table": { + "runtime_id": -202, + "component_based": false + }, + "minecraft:smoker": { + "runtime_id": -198, + "component_based": false + }, + "minecraft:smooth_basalt": { + "runtime_id": -377, + "component_based": false + }, + "minecraft:smooth_quartz": { + "runtime_id": -955, + "component_based": false + }, + "minecraft:smooth_quartz_double_slab": { + "runtime_id": -925, + "component_based": false + }, + "minecraft:smooth_quartz_slab": { + "runtime_id": -898, + "component_based": false + }, + "minecraft:smooth_quartz_stairs": { + "runtime_id": -185, + "component_based": false + }, + "minecraft:smooth_red_sandstone": { + "runtime_id": -958, + "component_based": false + }, + "minecraft:smooth_red_sandstone_double_slab": { + "runtime_id": -918, + "component_based": false + }, + "minecraft:smooth_red_sandstone_slab": { + "runtime_id": -891, + "component_based": false + }, + "minecraft:smooth_red_sandstone_stairs": { + "runtime_id": -176, + "component_based": false + }, + "minecraft:smooth_sandstone": { + "runtime_id": -946, + "component_based": false + }, + "minecraft:smooth_sandstone_double_slab": { + "runtime_id": -916, + "component_based": false + }, + "minecraft:smooth_sandstone_slab": { + "runtime_id": -889, + "component_based": false + }, + "minecraft:smooth_sandstone_stairs": { + "runtime_id": -177, + "component_based": false + }, + "minecraft:smooth_stone": { + "runtime_id": -183, + "component_based": false + }, + "minecraft:smooth_stone_double_slab": { + "runtime_id": 43, + "component_based": false + }, + "minecraft:smooth_stone_slab": { + "runtime_id": 44, + "component_based": false + }, + "minecraft:sniffer_egg": { + "runtime_id": -596, + "component_based": false + }, + "minecraft:sniffer_spawn_egg": { + "runtime_id": 528, + "component_based": false + }, + "minecraft:snort_pottery_sherd": { + "runtime_id": 716, + "component_based": false + }, + "minecraft:snout_armor_trim_smithing_template": { + "runtime_id": 727, + "component_based": false + }, + "minecraft:snow": { + "runtime_id": 80, + "component_based": false + }, + "minecraft:snow_golem_spawn_egg": { + "runtime_id": 534, + "component_based": false + }, + "minecraft:snow_layer": { + "runtime_id": 78, + "component_based": false + }, + "minecraft:snowball": { + "runtime_id": 399, + "component_based": true + }, + "minecraft:soul_campfire": { + "runtime_id": 660, + "component_based": true + }, + "minecraft:soul_fire": { + "runtime_id": -237, + "component_based": false + }, + "minecraft:soul_lantern": { + "runtime_id": -269, + "component_based": false + }, + "minecraft:soul_sand": { + "runtime_id": 88, + "component_based": false + }, + "minecraft:soul_soil": { + "runtime_id": -236, + "component_based": false + }, + "minecraft:soul_torch": { + "runtime_id": -268, + "component_based": false + }, + "minecraft:sparkler": { + "runtime_id": 638, + "component_based": false + }, + "minecraft:spawn_egg": { + "runtime_id": 795, + "component_based": false + }, + "minecraft:spider_eye": { + "runtime_id": 300, + "component_based": false + }, + "minecraft:spider_spawn_egg": { + "runtime_id": 473, + "component_based": false + }, + "minecraft:spire_armor_trim_smithing_template": { + "runtime_id": 729, + "component_based": false + }, + "minecraft:splash_potion": { + "runtime_id": 594, + "component_based": false + }, + "minecraft:sponge": { + "runtime_id": 19, + "component_based": false + }, + "minecraft:spore_blossom": { + "runtime_id": -321, + "component_based": false + }, + "minecraft:spruce_boat": { + "runtime_id": 404, + "component_based": false + }, + "minecraft:spruce_button": { + "runtime_id": -144, + "component_based": false + }, + "minecraft:spruce_chest_boat": { + "runtime_id": 679, + "component_based": false + }, + "minecraft:spruce_door": { + "runtime_id": 586, + "component_based": false + }, + "minecraft:spruce_double_slab": { + "runtime_id": -809, + "component_based": false + }, + "minecraft:spruce_fence": { + "runtime_id": -579, + "component_based": false + }, + "minecraft:spruce_fence_gate": { + "runtime_id": 183, + "component_based": false + }, + "minecraft:spruce_hanging_sign": { + "runtime_id": -501, + "component_based": false + }, + "minecraft:spruce_leaves": { + "runtime_id": -800, + "component_based": false + }, + "minecraft:spruce_log": { + "runtime_id": -569, + "component_based": false + }, + "minecraft:spruce_planks": { + "runtime_id": -739, + "component_based": false + }, + "minecraft:spruce_pressure_plate": { + "runtime_id": -154, + "component_based": false + }, + "minecraft:spruce_sapling": { + "runtime_id": -825, + "component_based": false + }, + "minecraft:spruce_sign": { + "runtime_id": 609, + "component_based": false + }, + "minecraft:spruce_slab": { + "runtime_id": -804, + "component_based": false + }, + "minecraft:spruce_stairs": { + "runtime_id": 134, + "component_based": false + }, + "minecraft:spruce_standing_sign": { + "runtime_id": -181, + "component_based": false + }, + "minecraft:spruce_trapdoor": { + "runtime_id": -149, + "component_based": false + }, + "minecraft:spruce_wall_sign": { + "runtime_id": -182, + "component_based": false + }, + "minecraft:spruce_wood": { + "runtime_id": -814, + "component_based": false + }, + "minecraft:spyglass": { + "runtime_id": 663, + "component_based": false + }, + "minecraft:squid_spawn_egg": { + "runtime_id": 477, + "component_based": false + }, + "minecraft:stained_glass": { + "runtime_id": 779, + "component_based": false + }, + "minecraft:stained_glass_pane": { + "runtime_id": 780, + "component_based": false + }, + "minecraft:stained_hardened_clay": { + "runtime_id": 739, + "component_based": false + }, + "minecraft:standing_banner": { + "runtime_id": 176, + "component_based": false + }, + "minecraft:standing_sign": { + "runtime_id": 63, + "component_based": false + }, + "minecraft:stick": { + "runtime_id": 345, + "component_based": false + }, + "minecraft:sticky_piston": { + "runtime_id": 29, + "component_based": false + }, + "minecraft:sticky_piston_arm_collision": { + "runtime_id": -217, + "component_based": false + }, + "minecraft:stone": { + "runtime_id": 1, + "component_based": false + }, + "minecraft:stone_axe": { + "runtime_id": 339, + "component_based": false + }, + "minecraft:stone_block_slab": { + "runtime_id": 756, + "component_based": false + }, + "minecraft:stone_block_slab2": { + "runtime_id": 757, + "component_based": false + }, + "minecraft:stone_block_slab3": { + "runtime_id": 758, + "component_based": false + }, + "minecraft:stone_block_slab4": { + "runtime_id": 759, + "component_based": false + }, + "minecraft:stone_brick_double_slab": { + "runtime_id": -881, + "component_based": false + }, + "minecraft:stone_brick_slab": { + "runtime_id": -875, + "component_based": false + }, + "minecraft:stone_brick_stairs": { + "runtime_id": 109, + "component_based": false + }, + "minecraft:stone_brick_wall": { + "runtime_id": -977, + "component_based": false + }, + "minecraft:stone_bricks": { + "runtime_id": 98, + "component_based": false + }, + "minecraft:stone_button": { + "runtime_id": 77, + "component_based": false + }, + "minecraft:stone_hoe": { + "runtime_id": 355, + "component_based": false + }, + "minecraft:stone_pickaxe": { + "runtime_id": 338, + "component_based": false + }, + "minecraft:stone_pressure_plate": { + "runtime_id": 70, + "component_based": false + }, + "minecraft:stone_shovel": { + "runtime_id": 337, + "component_based": false + }, + "minecraft:stone_stairs": { + "runtime_id": 67, + "component_based": false + }, + "minecraft:stone_sword": { + "runtime_id": 336, + "component_based": false + }, + "minecraft:stonebrick": { + "runtime_id": 754, + "component_based": false + }, + "minecraft:stonecutter": { + "runtime_id": 245, + "component_based": false + }, + "minecraft:stonecutter_block": { + "runtime_id": -197, + "component_based": false + }, + "minecraft:stray_spawn_egg": { + "runtime_id": 489, + "component_based": false + }, + "minecraft:strider_spawn_egg": { + "runtime_id": 523, + "component_based": false + }, + "minecraft:string": { + "runtime_id": 351, + "component_based": true + }, + "minecraft:stripped_acacia_log": { + "runtime_id": -8, + "component_based": false + }, + "minecraft:stripped_acacia_wood": { + "runtime_id": -823, + "component_based": false + }, + "minecraft:stripped_bamboo_block": { + "runtime_id": -528, + "component_based": false + }, + "minecraft:stripped_birch_log": { + "runtime_id": -6, + "component_based": false + }, + "minecraft:stripped_birch_wood": { + "runtime_id": -821, + "component_based": false + }, + "minecraft:stripped_cherry_log": { + "runtime_id": -535, + "component_based": false + }, + "minecraft:stripped_cherry_wood": { + "runtime_id": -545, + "component_based": false + }, + "minecraft:stripped_crimson_hyphae": { + "runtime_id": -300, + "component_based": false + }, + "minecraft:stripped_crimson_stem": { + "runtime_id": -240, + "component_based": false + }, + "minecraft:stripped_dark_oak_log": { + "runtime_id": -9, + "component_based": false + }, + "minecraft:stripped_dark_oak_wood": { + "runtime_id": -824, + "component_based": false + }, + "minecraft:stripped_jungle_log": { + "runtime_id": -7, + "component_based": false + }, + "minecraft:stripped_jungle_wood": { + "runtime_id": -822, + "component_based": false + }, + "minecraft:stripped_mangrove_log": { + "runtime_id": -485, + "component_based": false + }, + "minecraft:stripped_mangrove_wood": { + "runtime_id": -498, + "component_based": false + }, + "minecraft:stripped_oak_log": { + "runtime_id": -10, + "component_based": false + }, + "minecraft:stripped_oak_wood": { + "runtime_id": -819, + "component_based": false + }, + "minecraft:stripped_pale_oak_log": { + "runtime_id": -994, + "component_based": false + }, + "minecraft:stripped_pale_oak_wood": { + "runtime_id": -1004, + "component_based": false + }, + "minecraft:stripped_spruce_log": { + "runtime_id": -5, + "component_based": false + }, + "minecraft:stripped_spruce_wood": { + "runtime_id": -820, + "component_based": false + }, + "minecraft:stripped_warped_hyphae": { + "runtime_id": -301, + "component_based": false + }, + "minecraft:stripped_warped_stem": { + "runtime_id": -241, + "component_based": false + }, + "minecraft:structure_block": { + "runtime_id": 252, + "component_based": false + }, + "minecraft:structure_void": { + "runtime_id": 217, + "component_based": false + }, + "minecraft:sugar": { + "runtime_id": 442, + "component_based": false + }, + "minecraft:sugar_cane": { + "runtime_id": 411, + "component_based": true + }, + "minecraft:sunflower": { + "runtime_id": 175, + "component_based": false + }, + "minecraft:suspicious_gravel": { + "runtime_id": -573, + "component_based": false + }, + "minecraft:suspicious_sand": { + "runtime_id": -529, + "component_based": false + }, + "minecraft:suspicious_stew": { + "runtime_id": 625, + "component_based": false + }, + "minecraft:sweet_berries": { + "runtime_id": 309, + "component_based": false + }, + "minecraft:sweet_berry_bush": { + "runtime_id": -207, + "component_based": false + }, + "minecraft:tadpole_bucket": { + "runtime_id": 668, + "component_based": false + }, + "minecraft:tadpole_spawn_egg": { + "runtime_id": 667, + "component_based": false + }, + "minecraft:tall_grass": { + "runtime_id": -864, + "component_based": false + }, + "minecraft:tallgrass": { + "runtime_id": 774, + "component_based": false + }, + "minecraft:target": { + "runtime_id": -239, + "component_based": false + }, + "minecraft:tide_armor_trim_smithing_template": { + "runtime_id": 726, + "component_based": false + }, + "minecraft:tinted_glass": { + "runtime_id": -334, + "component_based": false + }, + "minecraft:tnt": { + "runtime_id": 46, + "component_based": false + }, + "minecraft:tnt_minecart": { + "runtime_id": 558, + "component_based": false + }, + "minecraft:torch": { + "runtime_id": 50, + "component_based": false + }, + "minecraft:torchflower": { + "runtime_id": -568, + "component_based": false + }, + "minecraft:torchflower_crop": { + "runtime_id": -567, + "component_based": false + }, + "minecraft:torchflower_seeds": { + "runtime_id": 318, + "component_based": false + }, + "minecraft:totem_of_undying": { + "runtime_id": 601, + "component_based": false + }, + "minecraft:trader_llama_spawn_egg": { + "runtime_id": 686, + "component_based": false + }, + "minecraft:trapdoor": { + "runtime_id": 96, + "component_based": false + }, + "minecraft:trapped_chest": { + "runtime_id": 146, + "component_based": false + }, + "minecraft:trial_key": { + "runtime_id": 276, + "component_based": true + }, + "minecraft:trial_spawner": { + "runtime_id": -315, + "component_based": false + }, + "minecraft:trident": { + "runtime_id": 579, + "component_based": false + }, + "minecraft:trip_wire": { + "runtime_id": 132, + "component_based": false + }, + "minecraft:tripwire_hook": { + "runtime_id": 131, + "component_based": false + }, + "minecraft:tropical_fish": { + "runtime_id": 288, + "component_based": false + }, + "minecraft:tropical_fish_bucket": { + "runtime_id": 391, + "component_based": false + }, + "minecraft:tropical_fish_spawn_egg": { + "runtime_id": 507, + "component_based": false + }, + "minecraft:tube_coral": { + "runtime_id": -131, + "component_based": false + }, + "minecraft:tube_coral_block": { + "runtime_id": -132, + "component_based": false + }, + "minecraft:tube_coral_fan": { + "runtime_id": -133, + "component_based": false + }, + "minecraft:tube_coral_wall_fan": { + "runtime_id": -135, + "component_based": false + }, + "minecraft:tuff": { + "runtime_id": -333, + "component_based": false + }, + "minecraft:tuff_brick_double_slab": { + "runtime_id": -756, + "component_based": false + }, + "minecraft:tuff_brick_slab": { + "runtime_id": -755, + "component_based": false + }, + "minecraft:tuff_brick_stairs": { + "runtime_id": -757, + "component_based": false + }, + "minecraft:tuff_brick_wall": { + "runtime_id": -758, + "component_based": false + }, + "minecraft:tuff_bricks": { + "runtime_id": -754, + "component_based": false + }, + "minecraft:tuff_double_slab": { + "runtime_id": -745, + "component_based": false + }, + "minecraft:tuff_slab": { + "runtime_id": -744, + "component_based": false + }, + "minecraft:tuff_stairs": { + "runtime_id": -746, + "component_based": false + }, + "minecraft:tuff_wall": { + "runtime_id": -747, + "component_based": false + }, + "minecraft:turtle_egg": { + "runtime_id": -159, + "component_based": false + }, + "minecraft:turtle_helmet": { + "runtime_id": 606, + "component_based": false + }, + "minecraft:turtle_scute": { + "runtime_id": 605, + "component_based": false + }, + "minecraft:turtle_spawn_egg": { + "runtime_id": 513, + "component_based": false + }, + "minecraft:twisting_vines": { + "runtime_id": -287, + "component_based": false + }, + "minecraft:underwater_tnt": { + "runtime_id": -985, + "component_based": false + }, + "minecraft:underwater_torch": { + "runtime_id": 239, + "component_based": false + }, + "minecraft:undyed_shulker_box": { + "runtime_id": 205, + "component_based": false + }, + "minecraft:unknown": { + "runtime_id": -305, + "component_based": false + }, + "minecraft:unlit_redstone_torch": { + "runtime_id": 75, + "component_based": false + }, + "minecraft:unpowered_comparator": { + "runtime_id": 149, + "component_based": false + }, + "minecraft:unpowered_repeater": { + "runtime_id": 93, + "component_based": false + }, + "minecraft:vault": { + "runtime_id": -314, + "component_based": false + }, + "minecraft:verdant_froglight": { + "runtime_id": -470, + "component_based": false + }, + "minecraft:vex_armor_trim_smithing_template": { + "runtime_id": 725, + "component_based": false + }, + "minecraft:vex_spawn_egg": { + "runtime_id": 504, + "component_based": false + }, + "minecraft:villager_spawn_egg": { + "runtime_id": 476, + "component_based": false + }, + "minecraft:vindicator_spawn_egg": { + "runtime_id": 502, + "component_based": false + }, + "minecraft:vine": { + "runtime_id": 106, + "component_based": false + }, + "minecraft:wall_banner": { + "runtime_id": 177, + "component_based": false + }, + "minecraft:wall_sign": { + "runtime_id": 68, + "component_based": false + }, + "minecraft:wandering_trader_spawn_egg": { + "runtime_id": 520, + "component_based": false + }, + "minecraft:ward_armor_trim_smithing_template": { + "runtime_id": 723, + "component_based": false + }, + "minecraft:warden_spawn_egg": { + "runtime_id": 670, + "component_based": false + }, + "minecraft:warped_button": { + "runtime_id": -261, + "component_based": false + }, + "minecraft:warped_door": { + "runtime_id": 655, + "component_based": false + }, + "minecraft:warped_double_slab": { + "runtime_id": -267, + "component_based": false + }, + "minecraft:warped_fence": { + "runtime_id": -257, + "component_based": false + }, + "minecraft:warped_fence_gate": { + "runtime_id": -259, + "component_based": false + }, + "minecraft:warped_fungus": { + "runtime_id": -229, + "component_based": false + }, + "minecraft:warped_fungus_on_a_stick": { + "runtime_id": 656, + "component_based": true + }, + "minecraft:warped_hanging_sign": { + "runtime_id": -507, + "component_based": false + }, + "minecraft:warped_hyphae": { + "runtime_id": -298, + "component_based": false + }, + "minecraft:warped_nylium": { + "runtime_id": -233, + "component_based": false + }, + "minecraft:warped_planks": { + "runtime_id": -243, + "component_based": false + }, + "minecraft:warped_pressure_plate": { + "runtime_id": -263, + "component_based": false + }, + "minecraft:warped_roots": { + "runtime_id": -224, + "component_based": false + }, + "minecraft:warped_sign": { + "runtime_id": 653, + "component_based": false + }, + "minecraft:warped_slab": { + "runtime_id": -265, + "component_based": false + }, + "minecraft:warped_stairs": { + "runtime_id": -255, + "component_based": false + }, + "minecraft:warped_standing_sign": { + "runtime_id": -251, + "component_based": false + }, + "minecraft:warped_stem": { + "runtime_id": -226, + "component_based": false + }, + "minecraft:warped_trapdoor": { + "runtime_id": -247, + "component_based": false + }, + "minecraft:warped_wall_sign": { + "runtime_id": -253, + "component_based": false + }, + "minecraft:warped_wart_block": { + "runtime_id": -227, + "component_based": false + }, + "minecraft:water": { + "runtime_id": 9, + "component_based": false + }, + "minecraft:water_bucket": { + "runtime_id": 387, + "component_based": false + }, + "minecraft:waterlily": { + "runtime_id": 111, + "component_based": false + }, + "minecraft:waxed_chiseled_copper": { + "runtime_id": -764, + "component_based": false + }, + "minecraft:waxed_copper": { + "runtime_id": -344, + "component_based": false + }, + "minecraft:waxed_copper_bulb": { + "runtime_id": -780, + "component_based": false + }, + "minecraft:waxed_copper_door": { + "runtime_id": -788, + "component_based": false + }, + "minecraft:waxed_copper_grate": { + "runtime_id": -772, + "component_based": false + }, + "minecraft:waxed_copper_trapdoor": { + "runtime_id": -796, + "component_based": false + }, + "minecraft:waxed_cut_copper": { + "runtime_id": -351, + "component_based": false + }, + "minecraft:waxed_cut_copper_slab": { + "runtime_id": -365, + "component_based": false + }, + "minecraft:waxed_cut_copper_stairs": { + "runtime_id": -358, + "component_based": false + }, + "minecraft:waxed_double_cut_copper_slab": { + "runtime_id": -372, + "component_based": false + }, + "minecraft:waxed_exposed_chiseled_copper": { + "runtime_id": -765, + "component_based": false + }, + "minecraft:waxed_exposed_copper": { + "runtime_id": -345, + "component_based": false + }, + "minecraft:waxed_exposed_copper_bulb": { + "runtime_id": -781, + "component_based": false + }, + "minecraft:waxed_exposed_copper_door": { + "runtime_id": -789, + "component_based": false + }, + "minecraft:waxed_exposed_copper_grate": { + "runtime_id": -773, + "component_based": false + }, + "minecraft:waxed_exposed_copper_trapdoor": { + "runtime_id": -797, + "component_based": false + }, + "minecraft:waxed_exposed_cut_copper": { + "runtime_id": -352, + "component_based": false + }, + "minecraft:waxed_exposed_cut_copper_slab": { + "runtime_id": -366, + "component_based": false + }, + "minecraft:waxed_exposed_cut_copper_stairs": { + "runtime_id": -359, + "component_based": false + }, + "minecraft:waxed_exposed_double_cut_copper_slab": { + "runtime_id": -373, + "component_based": false + }, + "minecraft:waxed_oxidized_chiseled_copper": { + "runtime_id": -766, + "component_based": false + }, + "minecraft:waxed_oxidized_copper": { + "runtime_id": -446, + "component_based": false + }, + "minecraft:waxed_oxidized_copper_bulb": { + "runtime_id": -783, + "component_based": false + }, + "minecraft:waxed_oxidized_copper_door": { + "runtime_id": -791, + "component_based": false + }, + "minecraft:waxed_oxidized_copper_grate": { + "runtime_id": -775, + "component_based": false + }, + "minecraft:waxed_oxidized_copper_trapdoor": { + "runtime_id": -799, + "component_based": false + }, + "minecraft:waxed_oxidized_cut_copper": { + "runtime_id": -447, + "component_based": false + }, + "minecraft:waxed_oxidized_cut_copper_slab": { + "runtime_id": -449, + "component_based": false + }, + "minecraft:waxed_oxidized_cut_copper_stairs": { + "runtime_id": -448, + "component_based": false + }, + "minecraft:waxed_oxidized_double_cut_copper_slab": { + "runtime_id": -450, + "component_based": false + }, + "minecraft:waxed_weathered_chiseled_copper": { + "runtime_id": -767, + "component_based": false + }, + "minecraft:waxed_weathered_copper": { + "runtime_id": -346, + "component_based": false + }, + "minecraft:waxed_weathered_copper_bulb": { + "runtime_id": -782, + "component_based": false + }, + "minecraft:waxed_weathered_copper_door": { + "runtime_id": -790, + "component_based": false + }, + "minecraft:waxed_weathered_copper_grate": { + "runtime_id": -774, + "component_based": false + }, + "minecraft:waxed_weathered_copper_trapdoor": { + "runtime_id": -798, + "component_based": false + }, + "minecraft:waxed_weathered_cut_copper": { + "runtime_id": -353, + "component_based": false + }, + "minecraft:waxed_weathered_cut_copper_slab": { + "runtime_id": -367, + "component_based": false + }, + "minecraft:waxed_weathered_cut_copper_stairs": { + "runtime_id": -360, + "component_based": false + }, + "minecraft:waxed_weathered_double_cut_copper_slab": { + "runtime_id": -374, + "component_based": false + }, + "minecraft:wayfinder_armor_trim_smithing_template": { + "runtime_id": 731, + "component_based": false + }, + "minecraft:weathered_chiseled_copper": { + "runtime_id": -762, + "component_based": false + }, + "minecraft:weathered_copper": { + "runtime_id": -342, + "component_based": false + }, + "minecraft:weathered_copper_bulb": { + "runtime_id": -778, + "component_based": false + }, + "minecraft:weathered_copper_door": { + "runtime_id": -786, + "component_based": false + }, + "minecraft:weathered_copper_grate": { + "runtime_id": -770, + "component_based": false + }, + "minecraft:weathered_copper_trapdoor": { + "runtime_id": -794, + "component_based": false + }, + "minecraft:weathered_cut_copper": { + "runtime_id": -349, + "component_based": false + }, + "minecraft:weathered_cut_copper_slab": { + "runtime_id": -363, + "component_based": false + }, + "minecraft:weathered_cut_copper_stairs": { + "runtime_id": -356, + "component_based": false + }, + "minecraft:weathered_double_cut_copper_slab": { + "runtime_id": -370, + "component_based": false + }, + "minecraft:web": { + "runtime_id": 30, + "component_based": false + }, + "minecraft:weeping_vines": { + "runtime_id": -231, + "component_based": false + }, + "minecraft:wet_sponge": { + "runtime_id": -984, + "component_based": false + }, + "minecraft:wheat": { + "runtime_id": 359, + "component_based": false + }, + "minecraft:wheat_seeds": { + "runtime_id": 313, + "component_based": false + }, + "minecraft:white_bundle": { + "runtime_id": 261, + "component_based": true + }, + "minecraft:white_candle": { + "runtime_id": -413, + "component_based": false + }, + "minecraft:white_candle_cake": { + "runtime_id": -430, + "component_based": false + }, + "minecraft:white_carpet": { + "runtime_id": 171, + "component_based": false + }, + "minecraft:white_concrete": { + "runtime_id": 236, + "component_based": false + }, + "minecraft:white_concrete_powder": { + "runtime_id": 237, + "component_based": false + }, + "minecraft:white_dye": { + "runtime_id": 436, + "component_based": false + }, + "minecraft:white_glazed_terracotta": { + "runtime_id": 220, + "component_based": false + }, + "minecraft:white_shulker_box": { + "runtime_id": 218, + "component_based": false + }, + "minecraft:white_stained_glass": { + "runtime_id": 241, + "component_based": false + }, + "minecraft:white_stained_glass_pane": { + "runtime_id": 160, + "component_based": false + }, + "minecraft:white_terracotta": { + "runtime_id": 159, + "component_based": false + }, + "minecraft:white_tulip": { + "runtime_id": -835, + "component_based": false + }, + "minecraft:white_wool": { + "runtime_id": 35, + "component_based": false + }, + "minecraft:wild_armor_trim_smithing_template": { + "runtime_id": 722, + "component_based": false + }, + "minecraft:wind_charge": { + "runtime_id": 277, + "component_based": true + }, + "minecraft:witch_spawn_egg": { + "runtime_id": 479, + "component_based": false + }, + "minecraft:wither_rose": { + "runtime_id": -216, + "component_based": false + }, + "minecraft:wither_skeleton_skull": { + "runtime_id": -965, + "component_based": false + }, + "minecraft:wither_skeleton_spawn_egg": { + "runtime_id": 492, + "component_based": false + }, + "minecraft:wither_spawn_egg": { + "runtime_id": 536, + "component_based": false + }, + "minecraft:wolf_armor": { + "runtime_id": 742, + "component_based": true + }, + "minecraft:wolf_spawn_egg": { + "runtime_id": 466, + "component_based": false + }, + "minecraft:wood": { + "runtime_id": 782, + "component_based": false + }, + "minecraft:wooden_axe": { + "runtime_id": 335, + "component_based": false + }, + "minecraft:wooden_button": { + "runtime_id": 143, + "component_based": false + }, + "minecraft:wooden_door": { + "runtime_id": 384, + "component_based": false + }, + "minecraft:wooden_hoe": { + "runtime_id": 354, + "component_based": false + }, + "minecraft:wooden_pickaxe": { + "runtime_id": 334, + "component_based": false + }, + "minecraft:wooden_pressure_plate": { + "runtime_id": 72, + "component_based": false + }, + "minecraft:wooden_shovel": { + "runtime_id": 333, + "component_based": false + }, + "minecraft:wooden_slab": { + "runtime_id": 769, + "component_based": false + }, + "minecraft:wooden_sword": { + "runtime_id": 332, + "component_based": false + }, + "minecraft:wool": { + "runtime_id": 750, + "component_based": false + }, + "minecraft:writable_book": { + "runtime_id": 544, + "component_based": false + }, + "minecraft:written_book": { + "runtime_id": 545, + "component_based": false + }, + "minecraft:yellow_bundle": { + "runtime_id": 267, + "component_based": true + }, + "minecraft:yellow_candle": { + "runtime_id": -417, + "component_based": false + }, + "minecraft:yellow_candle_cake": { + "runtime_id": -434, + "component_based": false + }, + "minecraft:yellow_carpet": { + "runtime_id": -600, + "component_based": false + }, + "minecraft:yellow_concrete": { + "runtime_id": -631, + "component_based": false + }, + "minecraft:yellow_concrete_powder": { + "runtime_id": -712, + "component_based": false + }, + "minecraft:yellow_dye": { + "runtime_id": 432, + "component_based": false + }, + "minecraft:yellow_glazed_terracotta": { + "runtime_id": 224, + "component_based": false + }, + "minecraft:yellow_shulker_box": { + "runtime_id": -616, + "component_based": false + }, + "minecraft:yellow_stained_glass": { + "runtime_id": -676, + "component_based": false + }, + "minecraft:yellow_stained_glass_pane": { + "runtime_id": -646, + "component_based": false + }, + "minecraft:yellow_terracotta": { + "runtime_id": -727, + "component_based": false + }, + "minecraft:yellow_wool": { + "runtime_id": -558, + "component_based": false + }, + "minecraft:zoglin_spawn_egg": { + "runtime_id": 526, + "component_based": false + }, + "minecraft:zombie_head": { + "runtime_id": -966, + "component_based": false + }, + "minecraft:zombie_horse_spawn_egg": { + "runtime_id": 496, + "component_based": false + }, + "minecraft:zombie_pigman_spawn_egg": { + "runtime_id": 475, + "component_based": false + }, + "minecraft:zombie_spawn_egg": { + "runtime_id": 474, + "component_based": false + }, + "minecraft:zombie_villager_spawn_egg": { + "runtime_id": 505, + "component_based": false + } +} diff --git a/legacyver/v748.go b/legacyver/v748.go new file mode 100644 index 0000000..3e2a667 --- /dev/null +++ b/legacyver/v748.go @@ -0,0 +1,36 @@ +package legacyver + +import ( + _ "embed" + "github.com/akmalfairuz/legacy-version/internal/chunk" + "github.com/akmalfairuz/legacy-version/legacyver/proto" + "github.com/akmalfairuz/legacy-version/mapping" +) + +const ( + // ItemVersion748 ... + ItemVersion748 = 221 + // BlockVersion748 ... + BlockVersion748 int32 = (1 << 24) | (21 << 16) | (40 << 8) +) + +var ( + //go:embed item_runtime_ids_748.nbt + itemRuntimeIDData748 []byte + //go:embed required_item_list_748.json + requiredItemList748 []byte + //go:embed block_states_748.nbt + blockStateData748 []byte +) + +func New748(direct bool) *Protocol { + itemMapping := mapping.NewItemMapping(itemRuntimeIDData748, requiredItemList748, ItemVersion748, false) + blockMapping := mapping.NewBlockMapping(blockStateData748) + + return &Protocol{ + ver: "1.21.40", + id: proto.ID748, + blockTranslator: NewBlockTranslator(blockMapping, latestBlockMapping, chunk.NewNetworkPersistentEncoding(blockMapping, BlockVersion748), chunk.NewBlockPaletteEncoding(blockMapping, BlockVersion748), false), + itemTranslator: NewItemTranslator(itemMapping, itemMappingLatest, blockMapping, blockMappingLatest), + } +} diff --git a/legacyver/v766.go b/legacyver/v766.go new file mode 100644 index 0000000..b9d32ae --- /dev/null +++ b/legacyver/v766.go @@ -0,0 +1,25 @@ +package legacyver + +import ( + _ "embed" + "github.com/akmalfairuz/legacy-version/mapping" +) + +const ( + // ItemVersion766 ... + ItemVersion766 = 231 + // BlockVersion766 ... + BlockVersion766 int32 = (1 << 24) | (21 << 16) | (50 << 8) +) + +var ( + //go:embed item_runtime_ids_766.nbt + itemRuntimeIDData766 []byte + //go:embed required_item_list_766.json + requiredItemList766 []byte + //go:embed block_states_766.nbt + blockStateData766 []byte + + itemMappingLatest = mapping.NewItemMapping(itemRuntimeIDData766, requiredItemList766, ItemVersion766, false) + blockMappingLatest = mapping.NewBlockMapping(blockStateData766) +) diff --git a/main.go b/main.go new file mode 100644 index 0000000..ab714ec --- /dev/null +++ b/main.go @@ -0,0 +1,146 @@ +package main + +import ( + "errors" + "github.com/akmalfairuz/legacy-version/legacyver" + "github.com/pelletier/go-toml" + "github.com/sandertv/gophertunnel/minecraft" + "github.com/sandertv/gophertunnel/minecraft/auth" + "golang.org/x/oauth2" + "log" + "os" + "sync" +) + +// The following program implements a proxy that forwards players from one local address to a remote address. +func main() { + config := readConfig() + token, err := auth.RequestLiveToken() + if err != nil { + panic(err) + } + src := auth.RefreshTokenSource(token) + + p, err := minecraft.NewForeignStatusProvider(config.Connection.RemoteAddress) + if err != nil { + panic(err) + } + listener, err := minecraft.ListenConfig{ + StatusProvider: p, + AcceptedProtocols: []minecraft.Protocol{ + legacyver.New748(false), + }, + }.Listen("raknet", config.Connection.LocalAddress) + if err != nil { + panic(err) + } + defer listener.Close() + for { + c, err := listener.Accept() + if err != nil { + panic(err) + } + go handleConn(c.(*minecraft.Conn), listener, config, src) + } +} + +// handleConn handles a new incoming minecraft.Conn from the minecraft.Listener passed. +func handleConn(conn *minecraft.Conn, listener *minecraft.Listener, config config, src oauth2.TokenSource) { + serverConn, err := minecraft.Dialer{ + TokenSource: src, + ClientData: conn.ClientData(), + }.Dial("raknet", config.Connection.RemoteAddress) + if err != nil { + panic(err) + } + var g sync.WaitGroup + g.Add(2) + go func() { + if err := conn.StartGame(serverConn.GameData()); err != nil { + panic(err) + } + g.Done() + }() + go func() { + if err := serverConn.DoSpawn(); err != nil { + panic(err) + } + g.Done() + }() + g.Wait() + + go func() { + defer listener.Disconnect(conn, "connection lost") + defer serverConn.Close() + for { + pk, err := conn.ReadPacket() + if err != nil { + return + } + if err := serverConn.WritePacket(pk); err != nil { + var disc minecraft.DisconnectError + if ok := errors.As(err, &disc); ok { + _ = listener.Disconnect(conn, disc.Error()) + } + return + } + } + }() + go func() { + defer serverConn.Close() + defer listener.Disconnect(conn, "connection lost") + for { + pk, err := serverConn.ReadPacket() + if err != nil { + var disc minecraft.DisconnectError + if ok := errors.As(err, &disc); ok { + _ = listener.Disconnect(conn, disc.Error()) + } + return + } + if err := conn.WritePacket(pk); err != nil { + return + } + } + }() +} + +type config struct { + Connection struct { + LocalAddress string + RemoteAddress string + } +} + +func readConfig() config { + c := config{} + if _, err := os.Stat("config.toml"); os.IsNotExist(err) { + f, err := os.Create("config.toml") + if err != nil { + log.Fatalf("create config: %v", err) + } + data, err := toml.Marshal(c) + if err != nil { + log.Fatalf("encode default config: %v", err) + } + if _, err := f.Write(data); err != nil { + log.Fatalf("write default config: %v", err) + } + _ = f.Close() + } + data, err := os.ReadFile("config.toml") + if err != nil { + log.Fatalf("read config: %v", err) + } + if err := toml.Unmarshal(data, &c); err != nil { + log.Fatalf("decode config: %v", err) + } + if c.Connection.LocalAddress == "" { + c.Connection.LocalAddress = "0.0.0.0:19132" + } + data, _ = toml.Marshal(c) + if err := os.WriteFile("config.toml", data, 0644); err != nil { + log.Fatalf("write config: %v", err) + } + return c +} diff --git a/mapping/block.go b/mapping/block.go new file mode 100644 index 0000000..1a5d466 --- /dev/null +++ b/mapping/block.go @@ -0,0 +1,136 @@ +package mapping + +import ( + "bytes" + "github.com/akmalfairuz/legacy-version/internal" + "sort" + + "github.com/df-mc/worldupgrader/blockupgrader" + "github.com/sandertv/gophertunnel/minecraft/nbt" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "github.com/segmentio/fasthash/fnv1" +) + +type Block interface { + // StateToRuntimeID converts a block state to a runtime ID. + StateToRuntimeID(blockupgrader.BlockState) (uint32, bool) + // RuntimeIDToState converts a runtime ID to a name and its state properties. + RuntimeIDToState(uint32) (blockupgrader.BlockState, bool) + // DowngradeBlockActorData downgrades the input sub chunk to a legacy block actor. + DowngradeBlockActorData(map[string]any) + // UpgradeBlockActorData upgrades the input sub chunk to the latest block actor. + UpgradeBlockActorData(map[string]any) + // Adjust adjusts the latest mappings to account for custom states. + Adjust([]protocol.BlockEntry) + Air() uint32 +} + +type DefaultBlockMapping struct { + // states holds a list of all possible vanilla block states. + states []blockupgrader.BlockState + // stateRuntimeIDs holds a map for looking up the runtime ID of a block by the stateHash it produces. + stateRuntimeIDs map[internal.StateHash]uint32 + // runtimeIDToState holds a map for looking up the blockState of a block by its runtime ID. + runtimeIDToState map[uint32]blockupgrader.BlockState + upgrader, downgrader func(map[string]any) map[string]any + + // airRID is the runtime ID of the air block in the latest version of the game. + airRID uint32 +} + +func NewBlockMapping(raw []byte) *DefaultBlockMapping { + dec := nbt.NewDecoder(bytes.NewBuffer(raw)) + + var states []blockupgrader.BlockState + stateRuntimeIDs := make(map[internal.StateHash]uint32) + runtimeIDToState := make(map[uint32]blockupgrader.BlockState) + var airRID *uint32 + + var s blockupgrader.BlockState + for { + if err := dec.Decode(&s); err != nil { + break + } + + rid := uint32(len(states)) + states = append(states, s) + if s.Name == "minecraft:air" { + airRID = &rid + } + + stateRuntimeIDs[internal.HashState(blockupgrader.Upgrade(s))] = rid + runtimeIDToState[rid] = s + } + if airRID == nil { + panic("couldn't find air") + } + + return &DefaultBlockMapping{ + states: states, + stateRuntimeIDs: stateRuntimeIDs, + runtimeIDToState: runtimeIDToState, + airRID: *airRID, + } +} + +func (m *DefaultBlockMapping) WithBlockActorRemapper(downgrader, upgrader func(map[string]any) map[string]any) *DefaultBlockMapping { + m.downgrader = downgrader + m.upgrader = upgrader + return m +} + +func (m *DefaultBlockMapping) StateToRuntimeID(state blockupgrader.BlockState) (uint32, bool) { + rid, ok := m.stateRuntimeIDs[internal.HashState(blockupgrader.Upgrade(state))] + return rid, ok +} + +func (m *DefaultBlockMapping) RuntimeIDToState(runtimeId uint32) (blockupgrader.BlockState, bool) { + state, found := m.runtimeIDToState[runtimeId] + return state, found +} + +func (m *DefaultBlockMapping) DowngradeBlockActorData(actorData map[string]any) { + if m.downgrader != nil { + m.downgrader(actorData) + } +} + +func (m *DefaultBlockMapping) UpgradeBlockActorData(actorData map[string]any) { + if m.upgrader != nil { + m.upgrader(actorData) + } +} + +func (m *DefaultBlockMapping) Adjust(entries []protocol.BlockEntry) { + if len(entries) == 0 { + return + } + + customStates := convert(entries) + var newStates []blockupgrader.BlockState + for _, state := range customStates { + if _, ok := m.StateToRuntimeID(state); !ok { + newStates = append(newStates, state) + } + } + if len(newStates) == 0 { + return + } + + adjustedStates := append(m.states, customStates...) + sort.SliceStable(adjustedStates, func(i, j int) bool { + stateOne, stateTwo := adjustedStates[i], adjustedStates[j] + return stateOne.Name != stateTwo.Name && fnv1.HashString64(stateOne.Name) < fnv1.HashString64(stateTwo.Name) + }) + + m.stateRuntimeIDs = make(map[internal.StateHash]uint32, len(adjustedStates)) + m.runtimeIDToState = make(map[uint32]blockupgrader.BlockState, len(adjustedStates)) + for rid, state := range adjustedStates { + m.stateRuntimeIDs[internal.HashState(blockupgrader.Upgrade(state))] = uint32(rid) + m.runtimeIDToState[uint32(rid)] = state + } +} + +func (m *DefaultBlockMapping) Air() uint32 { + return m.airRID +} diff --git a/mapping/custom_blocks.go b/mapping/custom_blocks.go new file mode 100644 index 0000000..d86f1dc --- /dev/null +++ b/mapping/custom_blocks.go @@ -0,0 +1,84 @@ +package mapping + +import ( + "github.com/akmalfairuz/legacy-version/internal" + "github.com/df-mc/worldupgrader/blockupgrader" + "github.com/sandertv/gophertunnel/minecraft/protocol" + "golang.org/x/exp/maps" +) + +func convert(entries []protocol.BlockEntry) (states []blockupgrader.BlockState) { + for _, entry := range entries { + propertiesMap := map[string][]any{} + if props := jsonCheck[[]any](entry.Properties, "properties"); props != nil { + for _, prop := range *props { + prop := prop.(map[string]any) + name := jsonCheck[string](prop, "name") + enum := jsonCheck[[]any](prop, "enum") + if enum == nil { + int32Enum := jsonCheck[[]int32](prop, "enum") + if int32Enum != nil { + enum = &[]any{} + for _, i := range *int32Enum { + *enum = append(*enum, i) + } + } + } + if name == nil || enum == nil { + panic("could not find field `name` and `enum`") + } + propertiesMap[*name] = *enum + } + } + + combinations := make([]map[string]any, 0) + generateCombinationsRecursively(propertiesMap, internal.NewIterator(maps.Keys(propertiesMap)), map[string]any{}, &combinations) + if len(combinations) == 0 { + combinations = append(combinations, map[string]any{}) + } + + for _, combination := range combinations { + blockState := blockupgrader.BlockState{ + Name: entry.Name, + Properties: combination, + } + + states = append(states, blockState) + } + } + return +} + +func generateCombinationsRecursively[K comparable, V any](all map[K][]V, iterator *internal.Iterator[K], current map[K]V, output *[]map[K]V) { + if !iterator.HasNext() { + entry := map[K]V{} + for k, v := range current { + entry[k] = v + } + out := append(*output, entry) + *output = out + } else { + key := iterator.Next() + set := all[key] + + for _, value := range set { + current[key] = value + generateCombinationsRecursively(all, iterator, current, output) + delete(current, key) + } + + iterator.Previous() + } +} + +func jsonCheck[T any](json map[string]any, field string) *T { + fieldValue, found := json[field] + if !found { + return nil + } + castedValue, ok := fieldValue.(T) + if !ok { + return nil + } + return &castedValue +} diff --git a/mapping/item.go b/mapping/item.go new file mode 100644 index 0000000..e3babde --- /dev/null +++ b/mapping/item.go @@ -0,0 +1,109 @@ +package mapping + +import ( + "encoding/json" + "github.com/sandertv/gophertunnel/minecraft/nbt" + "sync" +) + +type Item interface { + // ItemRuntimeIDToName converts an item runtime ID to a string ID. + ItemRuntimeIDToName(int32) (string, bool) + // ItemNameToRuntimeID converts a string ID to an item runtime ID. + ItemNameToRuntimeID(string) (int32, bool) + RegisterEntry(string) int32 + Air() int32 + ItemVersion() uint16 +} + +type DefaultItemMapping struct { + mu sync.Mutex + // itemRuntimeIDsToNames holds a map to translate item runtime IDs to string IDs. + itemRuntimeIDsToNames map[int32]string + // itemNamesToRuntimeIDs holds a map to translate item string IDs to runtime IDs. + itemNamesToRuntimeIDs map[string]int32 + airRID int32 + itemVersion uint16 +} + +func NewItemMapping(itemRuntimeIDData []byte, requiredItemList []byte, itemVersion uint16, direct bool) *DefaultItemMapping { + itemRuntimeIDsToNames := make(map[int32]string) + itemNamesToRuntimeIDs := make(map[string]int32) + var airRID *int32 + + if direct { + var items map[string]int32 + if err := nbt.Unmarshal(itemRuntimeIDData, &items); err != nil { + panic(err) + } + for name, rid := range items { + if name == "minecraft:air" { + airRID = &rid + } + + itemNamesToRuntimeIDs[name] = rid + itemRuntimeIDsToNames[rid] = name + } + } else { + var m map[string]struct { + RuntimeID int16 `json:"runtime_id"` + ComponentBased bool `json:"component_based"` + } + if err := json.Unmarshal(requiredItemList, &m); err != nil { + panic(err) + } + for name, data := range m { + rid := int32(data.RuntimeID) + if name == "minecraft:air" { + airRID = &rid + } + + itemNamesToRuntimeIDs[name] = rid + itemRuntimeIDsToNames[rid] = name + } + } + + if airRID == nil { + panic("couldn't find air") + } + + return &DefaultItemMapping{itemRuntimeIDsToNames: itemRuntimeIDsToNames, itemNamesToRuntimeIDs: itemNamesToRuntimeIDs, itemVersion: itemVersion} +} + +func (m *DefaultItemMapping) ItemRuntimeIDToName(runtimeID int32) (name string, found bool) { + defer m.mu.Unlock() + m.mu.Lock() + name, ok := m.itemRuntimeIDsToNames[runtimeID] + return name, ok +} + +func (m *DefaultItemMapping) ItemNameToRuntimeID(name string) (runtimeID int32, found bool) { + defer m.mu.Unlock() + m.mu.Lock() + rid, ok := m.itemNamesToRuntimeIDs[name] + return rid, ok +} + +func (m *DefaultItemMapping) RegisterEntry(name string) int32 { + defer m.mu.Unlock() + m.mu.Lock() + if rid, ok := m.itemNamesToRuntimeIDs[name]; ok { + return rid + } + nextRID := int32(len(m.itemRuntimeIDsToNames)) + m.itemNamesToRuntimeIDs[name] = nextRID + m.itemRuntimeIDsToNames[nextRID] = name + return nextRID +} + +func (m *DefaultItemMapping) Air() int32 { + defer m.mu.Unlock() + m.mu.Lock() + return m.airRID +} + +func (m *DefaultItemMapping) ItemVersion() uint16 { + defer m.mu.Unlock() + m.mu.Lock() + return m.itemVersion +} diff --git a/packbuilder/builder.go b/packbuilder/builder.go new file mode 100644 index 0000000..b9effd9 --- /dev/null +++ b/packbuilder/builder.go @@ -0,0 +1,71 @@ +package packbuilder + +import ( + "github.com/df-mc/dragonfly/server/item/category" + "golang.org/x/exp/maps" + "strings" +) + +// ComponentBuilder represents a builder that can be used to construct an item components map to be sent to a client. +type ComponentBuilder struct { + name string + identifier string + category category.Category + + properties map[string]any + components map[string]any +} + +// NewComponentBuilder returns a new component builder with the provided item data. +func NewComponentBuilder(name, identifier string, category category.Category) *ComponentBuilder { + return &ComponentBuilder{ + name: name, + identifier: identifier, + category: category, + + properties: make(map[string]any), + components: make(map[string]any), + } +} + +// AddProperty adds the provided property to the builder. +func (builder *ComponentBuilder) AddProperty(name string, value any) { + builder.properties[name] = value +} + +// AddComponent adds the provided component to the builder. +func (builder *ComponentBuilder) AddComponent(name string, value any) { + builder.components[name] = value +} + +// Construct constructs the final item components map and returns it. It also applies the default properties required +// for the item to work without modifying the original maps in the builder. +func (builder *ComponentBuilder) Construct() map[string]any { + properties := maps.Clone(builder.properties) + components := maps.Clone(builder.components) + builder.applyDefaultProperties(properties) + builder.applyDefaultComponents(components, properties) + return map[string]any{"components": components} +} + +// applyDefaultProperties applies the default properties to the provided map. It is important that this method does +// not modify the builder's properties map directly otherwise Empty() will return false in future use of the builder. +func (builder *ComponentBuilder) applyDefaultProperties(x map[string]any) { + x["minecraft:icon"] = map[string]any{ + "texture": strings.Split(builder.identifier, ":")[1], + } + x["creative_group"] = builder.category.Group() + x["creative_category"] = int32(builder.category.Uint8()) + if _, ok := x["max_stack_size"]; !ok { + x["max_stack_size"] = int32(64) + } +} + +// applyDefaultComponents applies the default components to the provided map. It is important that this method does not +// modify the builder's components map directly otherwise Empty() will return false in future use of the builder. +func (builder *ComponentBuilder) applyDefaultComponents(x, properties map[string]any) { + x["item_properties"] = properties + x["minecraft:display_name"] = map[string]any{ + "value": builder.name, + } +} diff --git a/packbuilder/components.go b/packbuilder/components.go new file mode 100644 index 0000000..bee89f9 --- /dev/null +++ b/packbuilder/components.go @@ -0,0 +1,119 @@ +package packbuilder + +import ( + "github.com/df-mc/dragonfly/server/item" + "github.com/df-mc/dragonfly/server/world" + "strings" +) + +// Components returns all the components of the given custom item. If the item has no components, a nil map and false +// are returned. +func Components(it world.CustomItem) map[string]any { + category := it.Category() + identifier, _ := it.EncodeItem() + name := strings.Split(identifier, ":")[1] + + builder := NewComponentBuilder(it.Name(), identifier, category) + + if x, ok := it.(item.Armour); ok { + builder.AddComponent("minecraft:armor", map[string]any{ + "protection": int32(x.DefencePoints()), + }) + builder.AddComponent("minecraft:knockback_resistance", map[string]any{ + "protection": float32(x.KnockBackResistance()), + }) + + var slot string + switch it.(type) { + case item.HelmetType: + slot = "slot.armor.head" + case item.ChestplateType: + slot = "slot.armor.chest" + case item.LeggingsType: + slot = "slot.armor.legs" + case item.BootsType: + slot = "slot.armor.feet" + } + builder.AddComponent("minecraft:wearable", map[string]any{ + "slot": slot, + }) + } + if x, ok := it.(item.Consumable); ok { + builder.AddProperty("use_duration", int32(x.ConsumeDuration().Seconds()*20)) + builder.AddComponent("minecraft:food", map[string]any{ + "can_always_eat": x.AlwaysConsumable(), + }) + + if y, ok := it.(item.Drinkable); ok && y.Drinkable() { + builder.AddProperty("use_animation", int32(2)) + } else { + builder.AddProperty("use_animation", int32(1)) + } + } + if x, ok := it.(item.Cooldown); ok { + builder.AddComponent("minecraft:cooldown", map[string]any{ + "category": name, + "duration": float32(x.Cooldown().Seconds()), + }) + } + if x, ok := it.(item.Durable); ok { + builder.AddComponent("minecraft:durability", map[string]any{ + "max_durability": int32(x.DurabilityInfo().MaxDurability), + }) + } + if x, ok := it.(item.MaxCounter); ok { + builder.AddProperty("max_stack_size", int32(x.MaxCount())) + } + if x, ok := it.(item.OffHand); ok { + builder.AddProperty("allow_off_hand", x.OffHand()) + } + if x, ok := it.(item.Throwable); ok { + // The data in minecraft:projectile is only used by vanilla server-side, but we must send at least an empty map + // so the client will play the throwing animation. + builder.AddComponent("minecraft:projectile", map[string]any{}) + builder.AddComponent("minecraft:throwable", map[string]any{ + "do_swing_animation": x.SwingAnimation(), + }) + } + if x, ok := it.(item.Glinted); ok { + builder.AddProperty("foil", x.Glinted()) + } + if x, ok := it.(item.HandEquipped); ok { + builder.AddProperty("hand_equipped", x.HandEquipped()) + } + itemScale := calculateItemScale(it) + builder.AddComponent("minecraft:render_offsets", map[string]any{ + "main_hand": map[string]any{ + "first_person": map[string]any{ + "scale": itemScale, + }, + "third_person": map[string]any{ + "scale": itemScale, + }, + }, + "off_hand": map[string]any{ + "first_person": map[string]any{ + "scale": itemScale, + }, + "third_person": map[string]any{ + "scale": itemScale, + }, + }, + }) + + return builder.Construct() +} + +// calculateItemScale calculates the scale of the item to be rendered to the player according to the given size. +func calculateItemScale(it world.CustomItem) []float32 { + width := float32(it.Texture().Bounds().Dx()) + height := float32(it.Texture().Bounds().Dy()) + var x, y, z float32 = 0.1, 0.1, 0.1 + if _, ok := it.(item.HandEquipped); ok { + x, y, z = 0.075, 0.125, 0.075 + } + newX := x / (width / 16) + newY := y / (height / 16) + newZ := z / (width / 16) + return []float32{newX, newY, newZ} +} diff --git a/packbuilder/items.go b/packbuilder/items.go new file mode 100644 index 0000000..b3e70d5 --- /dev/null +++ b/packbuilder/items.go @@ -0,0 +1,81 @@ +package packbuilder + +import ( + "encoding/json" + "fmt" + "github.com/df-mc/dragonfly/server/world" + "golang.org/x/image/colornames" + "image" + "image/png" + "os" + "path/filepath" + "strings" + _ "unsafe" // Imported for compiler directives. +) + +// buildItems builds all the item-related files for the resource pack. This includes textures, language +// entries and item atlas. +func buildItems(dir string, customItems []world.CustomItem) (count int, lang []string) { + if err := os.Mkdir(filepath.Join(dir, "items"), os.ModePerm); err != nil { + panic(err) + } + if err := os.MkdirAll(filepath.Join(dir, "textures/items"), os.ModePerm); err != nil { + panic(err) + } + + textureData := make(map[string]any) + for _, item := range customItems { + identifier, _ := item.EncodeItem() + lang = append(lang, fmt.Sprintf("item.%s.name=%s", identifier, item.Name())) + + name := strings.Split(identifier, ":")[1] + textureData[name] = map[string]string{"textures": fmt.Sprintf("textures/items/%s.png", name)} + + buildItemTexture(dir, name, item.Texture()) + + count++ + } + + buildItemAtlas(dir, map[string]any{ + "resource_pack_name": "vanilla", + "texture_name": "atlas.items", + "texture_data": textureData, + }) + return +} + +// buildItemTexture creates a PNG file for the item from the provided image and name and writes it to the pack. +func buildItemTexture(dir, name string, img image.Image) { + texture, err := os.Create(filepath.Join(dir, "textures/items", name+".png")) + if err != nil { + panic(err) + } + if img == nil { + im := image.NewAlpha(image.Rect(0, 0, 64, 64)) + for x := 0; x < im.Bounds().Dx(); x++ { + for y := 0; y < im.Bounds().Dy(); y++ { + im.Set(x, y, colornames.Goldenrod) + } + } + img = im + } + + if err := png.Encode(texture, img); err != nil { + _ = texture.Close() + panic(err) + } + if err := texture.Close(); err != nil { + panic(err) + } +} + +// buildItemAtlas creates the identifier to texture mapping and writes it to the pack. +func buildItemAtlas(dir string, atlas map[string]any) { + b, err := json.Marshal(atlas) + if err != nil { + panic(err) + } + if err := os.WriteFile(filepath.Join(dir, "textures/item_texture.json"), b, 0666); err != nil { + panic(err) + } +} diff --git a/packbuilder/lang.go b/packbuilder/lang.go new file mode 100644 index 0000000..d47e586 --- /dev/null +++ b/packbuilder/lang.go @@ -0,0 +1,17 @@ +package packbuilder + +import ( + "os" + "path/filepath" + "strings" +) + +// buildLanguageFile creates a lang file and writes all of the language entries to the pack. +func buildLanguageFile(dir string, lang []string) { + if err := os.Mkdir(filepath.Join(dir, "texts"), os.ModePerm); err != nil { + panic(err) + } + if err := os.WriteFile(filepath.Join(dir, "texts/en_US.lang"), []byte(strings.Join(lang, "\n")), 0666); err != nil { + panic(err) + } +} diff --git a/packbuilder/manifest.go b/packbuilder/manifest.go new file mode 100644 index 0000000..ce438ef --- /dev/null +++ b/packbuilder/manifest.go @@ -0,0 +1,52 @@ +package packbuilder + +import ( + "encoding/json" + "github.com/google/uuid" + "github.com/sandertv/gophertunnel/minecraft/resource" + "os" + "path/filepath" + "strconv" + "strings" +) + +// buildManifest creates a JSON manifest file for the client to be able to read the resource pack. It creates +// basic information and writes it to the pack. +func buildManifest(dir, version string, headerUUID, moduleUUID uuid.UUID) { + m, err := json.Marshal(resource.Manifest{ + FormatVersion: 2, + Header: resource.Header{ + Name: "dragonfly auto-generated resource pack", + Description: "This resource pack contains auto-generated content from dragonfly", + UUID: headerUUID, + Version: [3]int{0, 0, 1}, + MinimumGameVersion: parseVersion(version), + }, + Modules: []resource.Module{ + { + UUID: moduleUUID.String(), + Description: "This resource pack contains auto-generated content from dragonfly", + Type: "resources", + Version: [3]int{0, 0, 1}, + }, + }, + }) + if err != nil { + panic(err) + } + if err := os.WriteFile(filepath.Join(dir, "manifest.json"), m, 0666); err != nil { + panic(err) + } +} + +// parseVersion parses the version passed in the format of a.b.c as a [3]int. +func parseVersion(ver string) [3]int { + frag := strings.Split(ver, ".") + if len(frag) != 3 { + panic("invalid version number " + ver) + } + a, _ := strconv.ParseInt(frag[0], 10, 64) + b, _ := strconv.ParseInt(frag[1], 10, 64) + c, _ := strconv.ParseInt(frag[2], 10, 64) + return [3]int{int(a), int(b), int(c)} +} diff --git a/packbuilder/resource_pack.go b/packbuilder/resource_pack.go new file mode 100644 index 0000000..f8c1fbb --- /dev/null +++ b/packbuilder/resource_pack.go @@ -0,0 +1,40 @@ +package packbuilder + +import ( + "github.com/df-mc/dragonfly/server/world" + "github.com/rogpeppe/go-internal/dirhash" + "github.com/sandertv/gophertunnel/minecraft/resource" + "os" +) + +// BuildResourcePack builds a resource pack based on custom features that have been registered to the server. +// It creates a UUID based on the hash of the directory so the client will only be prompted to download it +// once it is changed. +func BuildResourcePack(customItems []world.CustomItem, version string) (*resource.Pack, bool) { + dir, err := os.MkdirTemp("", "dragonfly_resource_pack-") + if err != nil { + panic(err) + } + defer os.RemoveAll(dir) + + var assets int + var lang []string + + itemCount, itemLang := buildItems(dir, customItems) + assets += itemCount + lang = append(lang, itemLang...) + + if assets > 0 { + buildLanguageFile(dir, lang) + hash, err := dirhash.HashDir(dir, "", dirhash.Hash1) + if err != nil { + panic(err) + } + var header, module [16]byte + copy(header[:], hash) + copy(module[:], hash[16:]) + buildManifest(dir, version, header, module) + return resource.MustReadPath(dir), true + } + return nil, false +}