182 Commits
Author SHA1 Message Date
adman ede9a47ca2 add placeholder replacement and formatting utility functions 2026-05-12 16:31:00 +02:00
adman 2fb290572a add mutex for thread-safe XORKeyStream in CFB8 2026-05-11 23:27:14 +02:00
adman 021b8ddc1a add support for initial state configuration in print_replay tool 2026-05-10 20:35:58 +02:00
adman 05e8da2ff4 add packet id lookup and write to replay writer 2026-05-10 20:35:49 +02:00
adman a8936d92a5 add replay reader and writer for handling tmcpr files 2026-05-10 18:41:04 +02:00
adman c56898e787 refactor print_replay to improve unprocessable packet test creation 2026-05-10 17:29:52 +02:00
adman c483bf9553 if ctx is nil, set it to background context 2026-05-10 14:30:28 +02:00
adman b5ee17d1ae remove uncodeable_packet_hunter_proxy tool and integrate its functionality into print_replay 2026-05-10 14:09:24 +02:00
adman 57cef25e27 manage state transitions in print_replay tool 2026-05-10 13:01:40 +02:00
adman 148302c94d medium sized replay test data 2026-05-09 23:07:27 +02:00
adman 02c402251d add packet-info subcommand 2026-05-09 21:56:50 +02:00
adman c800c5d471 improve chunk section palette handling for blocks 2026-05-09 16:34:31 +02:00
adman 477f51cce7 fix biome palette initialization in chunk sections 2026-05-08 22:17:32 +02:00
adman 60103ebf47 enable Git LFS in checkout step 2026-05-08 21:41:46 +02:00
adman 21eeebf0f7 fix lighting 2026-05-08 21:33:05 +02:00
adman bb6f6548d5 serve world tool 2026-05-08 20:58:08 +02:00
adman d6c07cf428 replay testdata 2026-05-08 20:50:42 +02:00
adman e98921755d replay testdata 2026-05-08 20:50:37 +02:00
adman 60383fede1 replay testdata 2026-05-08 20:50:34 +02:00
adman 3bfa70d384 replay testdata 2026-05-08 19:17:09 +02:00
adman 60147fd4b6 correct "Properties" field case 2026-05-08 19:16:42 +02:00
adman fe51287cc6 add FIXME comments for mapstructure usage in go.mod and text.go 2026-05-08 12:23:27 +02:00
adman a44c5f8606 ci(workflows): add go vet step to CI pipeline 2026-05-08 12:11:36 +02:00
adman d5979b2c3d feat(util, anvil): add FloorDiv utility and nil-check in ChunkAt 2026-05-06 22:38:24 +02:00
admin-elseandGitHub 4b95ea9ae2 Merge pull request #1 from admin-else/feat/mca2packet
start work on mca to packet conversion
2026-05-06 21:14:53 +02:00
admin-elseandGitHub a80fd29297 Merge branch 'master' into feat/mca2packet 2026-05-06 21:13:49 +02:00
adman 589f35d147 delete the failing test because it works now i tested in game 2026-05-06 21:13:02 +02:00
adman c7b5f6ba0f refactor(util): remove unused utility functions 2026-05-06 18:47:18 +02:00
adman 0600315e69 refactor: move utility functions to dedicated util package and adjust references 2026-05-06 16:51:45 +02:00
adman 12005df68b Merge remote-tracking branch 'origin/feat/mca2packet' into feat/mca2packet 2026-05-06 16:48:48 +02:00
adman 600842a679 refactor storage format and bpe handling; add redirecting bpe support and utility function for next largest number 2026-05-06 16:48:39 +02:00
adman c93d907d46 refactor storage format and bpe handling; add redirecting bpe support and utility function for next largest number 2026-05-06 16:47:50 +02:00
adman be6d2fb461 update Go version to 1.26.2 in go.mod and CI workflow 2026-05-06 15:55:54 +02:00
adman b2df88203d fix block count calculation in chunk sections; improve variable naming in tests 2026-05-05 23:12:02 +02:00
admin-elseandGitHub 2ed4498181 Merge pull request #2 from admin-else/feat/data-cli
add `data` command and utility functions for type assertion and map k…
2026-05-05 15:32:03 +02:00
adman 0316b0aa09 add data command and utility functions for type assertion and map key access 2026-05-05 15:28:40 +02:00
adman 62d12386e1 improve chunk comparison by adding custom storage comparer and ignoring unexported fields 2026-05-05 13:57:02 +02:00
adman 00ea02a529 refactor chunk version handling; improve logging in equality checks and storage import logic 2026-05-05 13:30:21 +02:00
adman e5231dfdb6 improve chunk palette handling and logging; fix biome format and storage comparison logic 2026-05-04 00:27:00 +02:00
adman 3b1b436ecf refactor block state handling and storage initialization in litematic structures 2026-05-03 22:26:02 +02:00
adman 47180bf650 fix incorrect equality check in storage comparison logic 2026-05-03 19:02:06 +02:00
adman 325db98b99 add fuzz test data for chunk reading validation 2026-05-03 18:59:49 +02:00
adman ceae543352 read chunk section pallet fix 2026-05-03 18:59:42 +02:00
adman aef9615476 add equality checks and fuzz testing for chunk and storage data comparison 2026-05-03 18:34:21 +02:00
adman 5d3860b91e start work on mca to packet conversion 2026-05-03 18:20:36 +02:00
adman 94d15258d8 change Proxy.Data to pointer for consistency with nbt.Tag usage 2026-05-03 16:31:14 +02:00
adman ab03b36b4f add bounds checking for ChunkAt and add TimeAt function to ChunkHeader 2026-05-03 16:28:50 +02:00
adman da0c3c6f14 add bounds checking for ChunkAt and add TimeAt function to ChunkHeader 2026-05-03 16:28:37 +02:00
adman b01e482bc5 add file validation to print_nbt command 2026-05-03 16:23:01 +02:00
adman c560966177 add WriteUnstructuredFilePath function to simplify file writing logic 2026-05-03 16:22:17 +02:00
adman 66f86c5599 update Go version to 1.25 in GitHub Actions workflow 2026-05-03 15:32:58 +02:00
adman 5a2bfcb1c1 Merge remote-tracking branch 'origin/master' 2026-05-03 15:30:06 +02:00
admin-elseandGitHub b34f8d68ff Create Go CI workflow in GitHub Actions
Add GitHub Actions workflow for Go project build and test
2026-05-03 15:29:52 +02:00
adman c98472165b update connection initialization logic 2026-05-03 15:14:47 +02:00
adman 4888a07ebb update connection initialization to use LatestVersion instead of EarliestVersion 2026-05-03 15:11:08 +02:00
adman a9bf30a609 remove unused TestStorageImportBpeNotAvailable test because there is resizing for mca level storage to block format 2026-05-03 15:00:05 +02:00
adman 35030601e1 fix PrettyToNbt test to include empty text field and improve error formatting 2026-05-03 14:58:04 +02:00
adman 66f32b4cd2 update minecraft data binding to make binary smaller 2026-05-03 14:39:31 +02:00
adman e6d08dccbb working on disk to chunk packet test 2026-05-03 14:33:13 +02:00
adman 8a4f203621 add WithoutOnlineMode setting to login server and update usage in packet inspector 2026-05-02 16:16:54 +02:00
adman 69e230a79c add 'version' subcommand to display build information 2026-05-02 16:07:31 +02:00
adman 1a5f4f4f8e remove unused address parameter from LoginRaw and fix biome palette length calculation 2026-05-02 15:52:06 +02:00
adman d0844dd6b5 anvil chunk to real chunk conversion things 2026-05-02 01:36:29 +02:00
adman d8e36aa6fa make login server respect online mode settings 2026-05-02 00:21:26 +02:00
adman 6781e4c16d support upsizing storage on import if bpe not available 2026-05-02 00:21:17 +02:00
adman fccba0248a this makes errors that happen during login display 2026-05-01 22:17:51 +02:00
adman 52b3c1ce17 Revert "add export-ignore rules for proto_generator and tools directories in .gitattributes"
This reverts commit 3511cd2699.
2026-05-01 16:49:10 +02:00
adman 3511cd2699 add export-ignore rules for proto_generator and tools directories in .gitattributes 2026-05-01 16:48:26 +02:00
adman 6dddccab7f fix gitattributes 2026-05-01 16:45:58 +02:00
adman 9109d77f98 add export-ignore rules for test files in .gitattributes 2026-05-01 16:44:08 +02:00
adman 9eec1e8370 clone only needed minecraft-data 2026-05-01 16:33:28 +02:00
adman 96481da0a4 refactor: add context propagation to connection and event systems 2026-04-29 23:38:24 +02:00
adman 159437c1ca fix: handle empty kick status message properly in Status protocol state 2026-04-29 18:48:10 +02:00
adman 3d34ad59e9 allow for custom kick status message 2026-04-29 18:31:36 +02:00
adman 4878c6cc7b fix logger not being and other thing maybe 2026-04-28 22:25:36 +02:00
adman 719a3bacd8 Add fuzz testing for Section encoding/decoding with multiple edge cases 2026-04-28 09:31:35 +02:00
adman ce0c58e7c5 refactor shit 2026-04-27 01:50:45 +02:00
adman 8a4e44760e fix: TestRealStorageResizeDirect and TestRealStorageDirectModeNoPalette bugs
- resize() was writing to wrong array (r.data instead of newData) and using
  wrong elementsPerLong during resize loop
- TestRealStorageDirectModeNoPalette had invalid test data (0x1FFFF needs
  bpe>=17 but test used bpe=9)
2026-04-27 01:45:41 +02:00
adman e810a60848 111111 2026-04-27 01:26:56 +02:00
adman 0981339028 1111 2026-04-27 01:03:47 +02:00
adman 7746dd8ee9 real storage 2026-04-27 00:17:56 +02:00
adman 378b78312e storage=????? 2026-04-25 18:00:10 +02:00
adman bd3139754d add import storage and test 2026-04-23 22:36:34 +02:00
adman 841d91b91d storage 2026-04-23 21:30:17 +02:00
adman 895ec53698 parse the world 2026-04-21 22:24:12 +02:00
adman f6001c8b22 mojang cant get their cases straight
i had to implement like 4 cases just  to parse that file
2026-04-21 09:38:14 +02:00
adman d87c362270 anvil testdata 2026-04-21 08:35:40 +02:00
adman 236e414242 anvil start 2026-04-21 08:35:24 +02:00
adman 5222390b65 nbt changes 2026-04-21 08:35:18 +02:00
adman dc04fdc7d0 remove redundant bool arg 2026-04-20 23:38:02 +02:00
adman 8de34dfda1 mapstructure 2026-04-20 23:16:01 +02:00
adman 997594d7c3 fix chunk sections being one 2026-04-20 20:23:25 +02:00
adman c83a777eac mojang is weird i tell them 1 and they turn it into 4 2026-04-20 18:12:25 +02:00
adman 65fea61667 chunk builder 2026-04-19 17:41:13 +02:00
adman c2777f2ca9 chunk serialization fixes and fuzzies 2026-04-19 16:10:09 +02:00
adman dcb42f1970 chunk serialization 2026-04-19 11:04:37 +02:00
adman 7a2081f0a0 support kicker status 2026-04-17 21:51:47 +02:00
adman acc583f694 more logging 2026-04-14 09:20:00 +02:00
adman 76409d07a3 fix smart convert panic 2026-04-12 23:16:36 +02:00
adman bb89730781 fix bug with treshold 0 never compressing instead of always compressing 2026-04-12 23:16:19 +02:00
adman 9f6b1f6bcf more logging for status cli so you can debug address resolution 2026-04-12 23:15:50 +02:00
adman 1b8a9677c6 reduce binary size by not bundling bedrock data 2026-04-12 23:15:16 +02:00
adman 79ab13ca4b server encryption and online mode 2026-04-10 17:28:13 +02:00
adman 3cc414185a implement compression threshold setting 2026-04-10 14:30:35 +02:00
adman fe4a17dce2 Shutdownserver error 2026-04-08 00:31:05 +02:00
adman 891551f9dd simple api cli 2026-04-06 00:34:28 +02:00
adman 8fb48c6ea9 add version flag to status cmd 2026-04-05 23:39:08 +02:00
adman ec25c28061 Remove unused import 2026-04-05 23:38:57 +02:00
adman 45287f47d2 Expose lower register functions
Added RegisterLow and RegisterUntilLow

this gives more power to the user
2026-04-05 16:07:05 +02:00
adman 4cc4b6af5b fix earlies version
It was the latest version i dunno what i was thinking?
2026-04-05 16:05:33 +02:00
adman 09e6760d61 fix timer drifting off and delte old code 2026-04-05 16:04:53 +02:00
adman ca74a3c3d4 more explicit asyncPackets switch 2026-04-04 19:32:46 +02:00
adman fbc3693219 Revert "Send event"
This reverts commit abb0fa4d37.
2026-04-04 15:31:30 +02:00
Admin Else fb69fd93ec my code broke after i changed this last time and this fixed it 2026-04-03 19:01:33 +02:00
Admin Else a3a3c3714e Maybe fix contex done err 2026-04-03 19:00:52 +02:00
Admin Else 9294631c6c fix race condition 2026-04-03 09:05:24 +02:00
Admin Else 293f0b1eed this makes debugging easier trust me 2026-04-03 09:05:10 +02:00
Admin Else 272dcb4d36 warn instead of crash on unexpected packet 2026-04-02 18:49:50 +02:00
Admin Else abb0fa4d37 Send event 2026-04-02 18:49:30 +02:00
Admin Else e5212624af text components prints with tags 2026-04-01 16:43:47 +02:00
Admin Else 35772aca03 Cancle and signal errors shouldnt be voided 2026-03-31 21:57:04 +02:00
Admin Else 819d89b26e Delte schematic server 2026-03-31 17:04:44 +02:00
Admin Else 958102e43c fixes for config in 1.21.11 2026-03-31 16:51:07 +02:00
Admin Else f749d3bfc5 Add support for empty registry serving 2026-03-29 21:16:28 +02:00
Admin Else d207cf52cf 1.21.11 data registry 2026-03-29 21:09:05 +02:00
Admin Else 420ec5611c Fix register(critical)?untilLatest being inverted 2026-03-29 21:08:48 +02:00
Admin Else 4bfaf9b7c5 Remove redundant return 2026-03-29 21:07:23 +02:00
Admin Else 48beb861e8 Add vscode folder to gitignore 2026-03-29 17:50:33 +02:00
Admin Else 9fd2f517d9 Fix SmartConver for slices 2026-03-29 17:34:41 +02:00
Admin Else 1b5af63b75 Fix packet inspector 2026-03-29 17:13:11 +02:00
Admin Else dfb847eb3e Fix registry hunter 2026-03-29 17:11:40 +02:00
Admin Else 322bd77f7f Remove redundant return statement 2026-03-29 14:35:46 +02:00
Admin Else aefe850281 Fix send debug message 2026-03-29 14:21:54 +02:00
Admin Else 57f88f2176 Fix debug message 2026-03-29 14:20:02 +02:00
Admin Else 8dd566c0da Add DebugPrintPackets and fix not translating packet id 2026-03-29 14:15:31 +02:00
Admin Else e386a45d96 Add basic README.md 2026-03-28 18:14:41 +01:00
adman 8f771166a6 better unknown command text 2026-03-27 13:16:16 +01:00
adman 5d6a1a25ea fix packet spy 2026-03-27 13:09:07 +01:00
adman ca33185f20 fix LookupPacketInfoByType for undecoable 2026-03-27 12:59:10 +01:00
adman e921e9e9d2 fix routine thing 2026-03-27 00:03:01 +01:00
adman 7337068d86 more performance 2026-03-26 23:34:30 +01:00
adman 9983062522 fix timer 2026-03-26 22:39:48 +01:00
adman 4fd5324064 new event system (again) 2026-03-26 22:19:03 +01:00
adman df0e5e354b more srv stuff and packet inspetor 2026-03-25 19:00:18 +01:00
adman 23b5a5d9b7 move cmd to more sensible location 2026-03-25 14:53:38 +01:00
adman 46770ed980 Account changes
- now supports custom enviorments/servers
- cleaner code imo
2026-03-25 14:48:42 +01:00
adman 6179c5f6b6 fix proxy 2026-03-24 22:36:14 +01:00
adman f758a10575 performance fix 2026-03-24 21:50:52 +01:00
adman 41d1ab4c45 performance 2026-03-24 17:46:23 +01:00
adman 032fa26927 fix some race conditions 2026-03-22 22:51:29 +01:00
adman f7401a287e minecraft data raw code 2026-03-22 19:49:37 +01:00
adman 2d1e8ef4f6 go get does not support git submodules 2026-03-22 19:48:21 +01:00
adman 2802cc36ce litematic format 2026-03-22 19:45:05 +01:00
adman ea024fe808 look at the code if you want to know what i did 2026-03-22 00:35:07 +01:00
adman a6102b7ec9 working srv status 2026-03-20 22:19:07 +01:00
adman 254b75e76b remove onstart handler thing in favor of the user doing that themselves 2026-03-20 22:10:40 +01:00
adman 33cec6ecc9 mark lpvec3d as todo 2026-03-20 18:53:51 +01:00
adman fbf9bacd05 go vet fixup 2026-03-20 18:51:17 +01:00
adman 29baf8da9f test fixup 2026-03-20 17:57:03 +01:00
adman 43fea40d08 dns fix 2026-03-20 17:08:54 +01:00
adman b107eba37c dns 2026-03-19 23:50:28 +01:00
adman abc0f6aebb move some stuff and add registercritical 2026-03-19 22:28:20 +01:00
adman 8c6172dcda cleanup protodef type locations 2026-03-19 21:57:05 +01:00
adman 57e78478cd fix status cli 2026-03-18 21:23:48 +01:00
adman f554e91354 move a few tools to a more central utility cli 2026-03-18 20:45:54 +01:00
adman e0cf1834f1 items and struture loading 2026-03-12 23:13:25 +01:00
adman 047c4d02ff version compat system 2026-03-11 09:18:58 +01:00
adman c516cc5283 version compat system start 2026-03-09 21:30:31 +01:00
adman 165075ea02 Refactor event system 2026-03-08 13:56:36 +01:00
adman 2eee7bde24 refactor event systems 2026-03-08 11:52:25 +01:00
adman 73d4e07b06 block state 2026-03-06 21:24:08 +01:00
adman 5dfd8fc499 accidentally regen again and block state early work 2026-03-03 09:31:44 +01:00
adman 1b36949316 regenerate proto 2026-03-02 22:33:17 +01:00
adman 5c455bd2c8 regenerate proto 2026-03-02 22:26:40 +01:00
adman 8d1a4b581b shitty bitfield packing code 2026-03-02 22:24:26 +01:00
adman 085b83cb71 fix stupid protodef stuff 2026-03-02 21:40:36 +01:00
adman 65bf63d67e Update unCodable packet hunter to new scheme 2026-03-02 11:08:22 +01:00
adman d8cc9cab48 stuff 2026-03-02 00:14:57 +01:00
adman f7d7a72b7c nbt files 2026-03-01 13:28:49 +01:00
adman 29b1b92113 Add server infrastructure with login, status, and kick handlers 2026-02-24 23:28:25 +01:00
adman bd83b9689e Refactor server modules into main package and improve error handling 2026-02-24 23:27:56 +01:00
adman 85529b965b egg 2026-01-25 12:55:27 +01:00
508 changed files with 969584 additions and 11957 deletions
+6
View File
@@ -0,0 +1,6 @@
**/*_test.go export-ignore
**/testdata export-ignore
*.zip filter=lfs diff=lfs merge=lfs -text
*.tmcpr filter=lfs diff=lfs merge=lfs -text
*.mcpr filter=lfs diff=lfs merge=lfs -text
*.mca filter=lfs diff=lfs merge=lfs -text
+35
View File
@@ -0,0 +1,35 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go
name: Go
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout with LFS
uses: actions/checkout@v4
with:
lfs: true
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.26.2'
- name: Build
run: go build -v ./...
- name: Vet
run: go vet -v ./...
- name: Test
run: go test -v ./...
+2
View File
@@ -1,3 +1,5 @@
.devres/ .devres/
.idea/ .idea/
.failed_packets/ .failed_packets/
tools/.*/
.vscode/
-3
View File
@@ -1,3 +0,0 @@
[submodule "data/minecraft-data"]
path = data/minecraft-data
url = git@github.com:PrismarineJS/minecraft-data.git
+37 -178
View File
@@ -1,202 +1,61 @@
Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
Apache License Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below.
0. Additional Definitions.
1. Definitions. As used herein, “this License” refers to version 3 of the GNU Lesser General Public License, and the “GNU GPL” refers to version 3 of the GNU General Public License.
"License" shall mean the terms and conditions for use, reproduction, “The Library” refers to a covered work governed by this License, other than an Application or a Combined Work as defined below.
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by An “Application” is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library.
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all A “Combined Work” is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the “Linked Version”.
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity The “Minimal Corresponding Source” for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version.
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, The “Corresponding Application Code” for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work.
including but not limited to software source code, documentation 1. Exception to Section 3 of the GNU GPL.
source, and configuration files.
"Object" form shall mean any form resulting from mechanical You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL.
transformation or translation of a Source form, including but 2. Conveying Modified Versions.
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version:
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or
form, that is based on (or derived from) the Work and for which the b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including 3. Object Code Incorporating Material from Library Header Files.
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following:
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License.
this License, each Contributor hereby grants to You a perpetual, b) Accompany the object code with a copy of the GNU GPL and this license document.
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of 4. Combined Works.
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following:
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License.
Derivative Works a copy of this License; and b) Accompany the Combined Work with a copy of the GNU GPL and this license document.
c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version.
e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.)
(b) You must cause any modified files to carry prominent notices 5. Combined Libraries.
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following:
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License.
distribution, then any Derivative Works that You distribute must b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and 6. Revised Versions of the GNU Lesser General Public License.
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation.
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+5
View File
@@ -0,0 +1,5 @@
# STROM
# THIS IS WORK IN PROGRESS AND THE API WILL BREAK AS LONG AS THE THE PACKAGE VERSION IS v0.x.x
feel free to contact me on [discord](https://discord.gg/n2Vjc2vcMf)
+64 -37
View File
@@ -9,32 +9,40 @@ import (
"strings" "strings"
"time" "time"
"github.com/admin-else/strom/crypto"
"github.com/google/uuid" "github.com/google/uuid"
) )
type Servers struct {
ServicesHost string
SessionHost string
ProfilesHost string
}
var DefaultServers = &Servers{
ServicesHost: "https://api.minecraftservices.com",
SessionHost: "https://sessionserver.mojang.com",
ProfilesHost: "https://api.mojang.com",
}
type Account struct { type Account struct {
*Servers
Name string Name string
Uuid uuid.UUID Uuid uuid.UUID
Ygg string Ygg string
} }
const (
BaseUrlApi = "https://api.minecraftservices.com"
)
func (a *Account) doMcApiRequest(method string, url string, from any, to any) (err error) { func (a *Account) doMcApiRequest(method string, url string, from any, to any) (err error) {
var b []byte var b []byte
if method != "GET" { if method != "GET" {
b, err = json.Marshal(from) b, err = json.Marshal(from)
if err != nil { if err != nil {
return err return
} }
} }
r, err := http.NewRequest(method, url, bytes.NewReader(b)) r, err := http.NewRequest(method, url, bytes.NewReader(b))
if err != nil { if err != nil {
return err return
} }
r.Header.Set("Content-Type", "application/json") r.Header.Set("Content-Type", "application/json")
@@ -44,21 +52,22 @@ func (a *Account) doMcApiRequest(method string, url string, from any, to any) (e
resp, err := http.DefaultClient.Do(r) resp, err := http.DefaultClient.Do(r)
if err != nil { if err != nil {
return err return
} }
defer resp.Body.Close()
if !(resp.StatusCode >= 200 && resp.StatusCode <= 299) { if !(resp.StatusCode >= 200 && resp.StatusCode <= 299) {
return fmt.Errorf("bad status code %v", resp.StatusCode) return fmt.Errorf("bad status code %v", resp.StatusCode)
} }
b, err = io.ReadAll(resp.Body) b, err = io.ReadAll(resp.Body)
if err != nil { if err != nil {
return err return
} }
err = json.Unmarshal(b, to) err = json.Unmarshal(b, to)
if err != nil { if err != nil {
return err return
} }
return nil return
} }
type PlayerKeys struct { type PlayerKeys struct {
@@ -73,7 +82,7 @@ type PlayerKeys struct {
} }
func (a *Account) FetchKeys() (keys PlayerKeys, err error) { func (a *Account) FetchKeys() (keys PlayerKeys, err error) {
err = a.doMcApiRequest("POST", BaseUrlApi+"/player/certificates", nil, &keys) err = a.doMcApiRequest("POST", a.ServicesHost+"/player/certificates", nil, &keys)
return return
} }
@@ -90,10 +99,12 @@ func (a *Account) JoinServer(serverId string) (err error) {
if err != nil { if err != nil {
return return
} }
resp, err := http.Post("https://sessionserver.mojang.com/session/minecraft/join", "application/json", bytes.NewReader(body)) resp, err := http.Post(a.SessionHost+"/session/minecraft/join", "application/json", bytes.NewReader(body))
if err != nil { if err != nil {
return return
} }
defer resp.Body.Close()
if resp.StatusCode != 204 { if resp.StatusCode != 204 {
body, err = io.ReadAll(resp.Body) body, err = io.ReadAll(resp.Body)
if err != nil { if err != nil {
@@ -112,17 +123,10 @@ type NameChangResp struct {
} }
func (a *Account) NameChangeInfo() (r NameChangResp, err error) { func (a *Account) NameChangeInfo() (r NameChangResp, err error) {
err = a.doMcApiRequest("GET", "https://api.minecraftservices.com/minecraft/profile/namechange", nil, &r) err = a.doMcApiRequest("GET", a.ServicesHost+"/minecraft/profile/namechange", nil, &r)
return return
} }
func NewOfflineAccount(name string) *Account {
return &Account{
Name: name,
Uuid: crypto.FromOfflinePlayer(name),
}
}
// PlayerProfile represents the player's profile information // PlayerProfile represents the player's profile information
type PlayerProfile struct { type PlayerProfile struct {
ID string `json:"id"` ID string `json:"id"`
@@ -143,7 +147,7 @@ type PlayerProfile struct {
// QueryProfile queries the player's profile // QueryProfile queries the player's profile
func (a *Account) QueryProfile() (profile PlayerProfile, err error) { func (a *Account) QueryProfile() (profile PlayerProfile, err error) {
err = a.doMcApiRequest("GET", BaseUrlApi+"/minecraft/profile", nil, &profile) err = a.doMcApiRequest("GET", a.ServicesHost+"/minecraft/profile", nil, &profile)
return return
} }
@@ -181,7 +185,7 @@ type PlayerAttributes struct {
// QueryAttributes queries the player's attributes // QueryAttributes queries the player's attributes
func (a *Account) QueryAttributes() (attrs PlayerAttributes, err error) { func (a *Account) QueryAttributes() (attrs PlayerAttributes, err error) {
err = a.doMcApiRequest("GET", BaseUrlApi+"/player/attributes", nil, &attrs) err = a.doMcApiRequest("GET", a.ServicesHost+"/player/attributes", nil, &attrs)
return return
} }
@@ -194,7 +198,7 @@ type ModifyAttributesRequest struct {
// ModifyAttributes modifies the player's attributes // ModifyAttributes modifies the player's attributes
func (a *Account) ModifyAttributes(req ModifyAttributesRequest) (attrs PlayerAttributes, err error) { func (a *Account) ModifyAttributes(req ModifyAttributesRequest) (attrs PlayerAttributes, err error) {
err = a.doMcApiRequest("POST", BaseUrlApi+"/player/attributes", req, &attrs) err = a.doMcApiRequest("POST", a.ServicesHost+"/player/attributes", req, &attrs)
return return
} }
@@ -205,24 +209,23 @@ type BlockedUsers struct {
// GetBlocklist gets the list of blocked users // GetBlocklist gets the list of blocked users
func (a *Account) GetBlocklist() (blocklist BlockedUsers, err error) { func (a *Account) GetBlocklist() (blocklist BlockedUsers, err error) {
err = a.doMcApiRequest("GET", BaseUrlApi+"/privacy/blocklist", nil, &blocklist) err = a.doMcApiRequest("GET", a.ServicesHost+"/privacy/blocklist", nil, &blocklist)
return return
} }
// CheckNameAvailability checks if a name is available
type NameAvailability struct { type NameAvailability struct {
Status string `json:"status"` // DUPLICATE, AVAILABLE, NOT_ALLOWED Status string `json:"status"` // DUPLICATE, AVAILABLE, NOT_ALLOWED
} }
// CheckNameAvailability checks if a name is available // CheckNameAvailability checks if a name is available
func (a *Account) CheckNameAvailability(name string) (avail NameAvailability, err error) { func (a *Account) CheckNameAvailability(name string) (avail NameAvailability, err error) {
err = a.doMcApiRequest("GET", BaseUrlApi+"/minecraft/profile/name/"+name+"/available", nil, &avail) err = a.doMcApiRequest("GET", a.ServicesHost+"/minecraft/profile/name/"+name+"/available", nil, &avail)
return return
} }
// ChangeName changes the player's name // ChangeName changes the player's name
func (a *Account) ChangeName(newName string) (profile PlayerProfile, err error) { func (a *Account) ChangeName(newName string) (profile PlayerProfile, err error) {
err = a.doMcApiRequest("PUT", BaseUrlApi+"/minecraft/profile/name/"+newName, nil, &profile) err = a.doMcApiRequest("PUT", a.ServicesHost+"/minecraft/profile/name/"+newName, nil, &profile)
return return
} }
@@ -234,19 +237,19 @@ type ChangeSkinRequest struct {
// ChangeSkin changes the player's skin // ChangeSkin changes the player's skin
func (a *Account) ChangeSkin(req ChangeSkinRequest) (profile PlayerProfile, err error) { func (a *Account) ChangeSkin(req ChangeSkinRequest) (profile PlayerProfile, err error) {
err = a.doMcApiRequest("POST", BaseUrlApi+"/minecraft/profile/skins", req, &profile) err = a.doMcApiRequest("POST", a.ServicesHost+"/minecraft/profile/skins", req, &profile)
return return
} }
// ResetSkin resets the player's skin to default // ResetSkin resets the player's skin to default
func (a *Account) ResetSkin() (profile PlayerProfile, err error) { func (a *Account) ResetSkin() (profile PlayerProfile, err error) {
err = a.doMcApiRequest("DELETE", BaseUrlApi+"/minecraft/profile/skins/active", nil, &profile) err = a.doMcApiRequest("DELETE", a.ServicesHost+"/minecraft/profile/skins/active", nil, &profile)
return return
} }
// HideCape hides the player's active cape // HideCape hides the player's active cape
func (a *Account) HideCape() (profile PlayerProfile, err error) { func (a *Account) HideCape() (profile PlayerProfile, err error) {
err = a.doMcApiRequest("DELETE", BaseUrlApi+"/minecraft/profile/capes/active", nil, &profile) err = a.doMcApiRequest("DELETE", a.ServicesHost+"/minecraft/profile/capes/active", nil, &profile)
return return
} }
@@ -258,29 +261,53 @@ type ShowCapeRequest struct {
// ShowCape shows a specific cape // ShowCape shows a specific cape
func (a *Account) ShowCape(capeID string) (profile PlayerProfile, err error) { func (a *Account) ShowCape(capeID string) (profile PlayerProfile, err error) {
req := ShowCapeRequest{CapeID: capeID} req := ShowCapeRequest{CapeID: capeID}
err = a.doMcApiRequest("PUT", BaseUrlApi+"/minecraft/profile/capes/active", req, &profile) err = a.doMcApiRequest("PUT", a.ServicesHost+"/minecraft/profile/capes/active", req, &profile)
return return
} }
// CheckGiftCodeValidity checks if a gift code is valid // CheckGiftCodeValidity checks if a gift code is valid
func (a *Account) CheckGiftCodeValidity(giftCode string) (valid bool, err error) { func (a *Account) CheckGiftCodeValidity(giftCode string) (valid bool, err error) {
url := BaseUrlApi + "/productvoucher/giftcode" url := a.ServicesHost + "/productvoucher/" + giftCode
r, err := http.NewRequest("GET", url, nil) r, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
return false, err return
} }
r.Header.Set("Authorization", "Bearer "+a.Ygg) r.Header.Set("Authorization", "Bearer "+a.Ygg)
resp, err := http.DefaultClient.Do(r) resp, err := http.DefaultClient.Do(r)
if err != nil { if err != nil {
return false, err return
} }
defer resp.Body.Close() defer resp.Body.Close()
// Returns HTTP 200 or 204 if valid, 404 if invalid // Returns HTTP 200 or 204 if valid, 404 if invalid
if resp.StatusCode == 200 || resp.StatusCode == 204 { if resp.StatusCode == 200 || resp.StatusCode == 204 {
return true, nil valid = true
return
}
return
}
func NewAccountFromYGG(ygg string) (a *Account, err error) {
a = &Account{
Ygg: ygg,
Servers: DefaultServers,
}
p, err := a.QueryProfile()
if err != nil {
return
}
a.Name = p.Name
a.Uuid, err = uuid.Parse(strings.ReplaceAll(p.ID, "-", ""))
return
}
func NewAccount(name string, uuid uuid.UUID, ygg string) (a *Account) {
return &Account{
Name: name,
Uuid: uuid,
Ygg: ygg,
Servers: DefaultServers,
} }
return false, nil
} }
+10
View File
@@ -0,0 +1,10 @@
package api
import "github.com/admin-else/strom/crypto"
func NewOfflineAccount(name string) *Account {
return &Account{
Name: name,
Uuid: crypto.FromOfflinePlayer(name),
}
}
+130
View File
@@ -0,0 +1,130 @@
package api
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
)
func BlockedServers() (s []string, err error) {
resp, err := http.Get("https://sessionserver.mojang.com/blockedservers")
if err != nil {
return
}
defer resp.Body.Close()
d, err := io.ReadAll(resp.Body)
if err != nil {
return
}
s = strings.Split(string(d), "\n")
return
}
type ProfileProperty struct {
Name string `json:"name"`
Signature string `json:"signature,omitempty"`
Value string `json:"value"`
}
type ProfileResp struct {
Id string `json:"id"`
Name string `json:"name"`
Legacy bool `json:"legacy"`
Properties []ProfileProperty `json:"properties"`
}
func HasJoined(name, server, ip string) (p ProfileResp, err error) {
url := "https://sessionserver.mojang.com/session/minecraft/hasJoined?username=" + name + "&serverId=" + server
if ip != "" {
url += "&ip=" + ip
}
resp, err := http.Get(url)
if err != nil {
return
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
err = fmt.Errorf("bad status code %v", resp.StatusCode)
return
}
err = json.NewDecoder(resp.Body).Decode(&p)
return
}
type MojangPublicKeysResp struct {
ProfilePropertyKeys []string `json:"profilePropertyKeys"`
PlayerCertificateKeys []string `json:"playerCertificateKeys"`
// AuthenticationKeys are undocumented by wiki.vg but they exist as of the time of writing so ill include them
AuthenticationKeys []string `json:"authenticationKeys"`
}
func MojangPublicKeys() (keys MojangPublicKeysResp, err error) {
resp, err := http.Get("https://sessionserver.mojang.com/session/minecraft/profile/public_key_by_token")
if err != nil {
return
}
defer resp.Body.Close()
err = json.NewDecoder(resp.Body).Decode(&keys)
return
}
func Profile(id string, unsinged bool) (p ProfileResp, err error) {
url := "https://sessionserver.mojang.com/session/minecraft/profile/" + id
if !unsinged {
url += "?unsigned=false"
}
resp, err := http.Get(url)
if err != nil {
return
}
defer resp.Body.Close()
err = json.NewDecoder(resp.Body).Decode(&p)
return
}
type IdName struct {
Id string `json:"id"`
Name string `json:"name"`
}
func NameToId(name string) (idName IdName, err error) {
// may also use these:
//https://api.mojang.com/users/profiles/minecraft/<player name>
//https://api.minecraftservices.com/minecraft/profile/lookup/name/<player name>
//https://api.mojang.com/minecraft/profile/lookup/name/<player name>
resp, err := http.Get("https://api.minecraftservices.com/minecraft/profile/lookup/name/" + name)
if err != nil {
return
}
defer resp.Body.Close()
err = json.NewDecoder(resp.Body).Decode(&idName)
return
}
func NameToIdBulk(names []string) (idNames []IdName, err error) {
b := bytes.NewBuffer(nil)
err = json.NewEncoder(b).Encode(names)
if err != nil {
return
}
// may also use these:
//https://api.mojang.com/profiles/minecraft
//https://api.minecraftservices.com/minecraft/profile/lookup/bulk/byname
//https://api.mojang.com/minecraft/profile/lookup/bulk/byname
r, err := http.NewRequest("POST", "https://api.minecraftservices.com/minecraft/profile/lookup/bulk/byname", b)
if err != nil {
return
}
r.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(r)
if err != nil {
return
}
defer resp.Body.Close()
err = json.NewDecoder(resp.Body).Decode(&idNames)
return
}
+22 -5
View File
@@ -1,22 +1,39 @@
package client package client
import ( import (
"context"
"net" "net"
"github.com/admin-else/strom/proto" "github.com/admin-else/strom/proto"
"github.com/admin-else/strom/proto_base" "github.com/admin-else/strom/proto_base"
) )
// Connect connects to the given address note that it does not resolve the SRV records it's just a raw net.Dial
// You must close the connection when you're done with it
func Connect(addr string) (ret *proto.Conn, err error) { func Connect(addr string) (ret *proto.Conn, err error) {
ret = &proto.Conn{} s, err := Status(addr)
err = ret.SetVersion("1.21.8")
if err != nil { if err != nil {
return return
} }
ret.SetState(proto_base.Handshaking) ret, err = ConnectVersionLess(addr)
ret.CompressionThreshold = -1 if err != nil {
return
}
err = ret.SetProtocolVersion(s.Version.Protocol)
return
}
func ConnectVersionLess(addr string) (ret *proto.Conn, err error) {
return ConnectVersionLessCtx(context.Background(), addr)
}
// ConnectVersionLess connects to the given address without setting the version you should set it
// when using this function.
// You must close the connection when you're done with it
func ConnectVersionLessCtx(ctx context.Context, addr string) (ret *proto.Conn, err error) {
ret = proto.NewConnCtx(ctx)
ret.Actor = proto_base.Client ret.Actor = proto_base.Client
ret.Conn, err = net.Dial("tcp", addr) ret.Conn, err = (&net.Dialer{}).DialContext(ctx, "tcp", addr)
if err != nil { if err != nil {
return return
} }
@@ -1,4 +1,4 @@
package modules package client
import ( import (
"errors" "errors"
@@ -14,8 +14,12 @@ type ConfigIgnorer struct {
*proto.Conn *proto.Conn
} }
func (c *ConfigIgnorer) Default(event any) (err error) { func (c *ConfigIgnorer) OnStart() (err error) {
fmt.Printf("%#v\n", event) return
}
func (c *ConfigIgnorer) Default(e event.Anything) (err error) {
c.Log.Debug("Config ignorer", "packet", fmt.Sprintf("%#v", e))
return return
} }
@@ -23,7 +27,7 @@ func (c *ConfigIgnorer) OnKnownPacks(packet *v1_21_8.ConfigurationToClientPacket
return c.Send(&v1_21_8.ConfigurationToServerPacketCommonSelectKnownPacks{Packs: packet.Packs}) return c.Send(&v1_21_8.ConfigurationToServerPacketCommonSelectKnownPacks{Packs: packet.Packs})
} }
func (c *ConfigIgnorer) OnFinish(_ v1_21_8.ConfigurationToClientPacketFinishConfiguration) (err error) { func (c *ConfigIgnorer) OnFinish(_ *v1_21_8.ConfigurationToClientPacketFinishConfiguration) (err error) {
err = c.Send(&v1_21_8.ConfigurationToServerPacketFinishConfiguration{}) err = c.Send(&v1_21_8.ConfigurationToServerPacketFinishConfiguration{})
if err != nil { if err != nil {
return return
@@ -44,7 +48,14 @@ func (c *ConfigIgnorer) OnKeepAlive(packet *v1_21_8.ConfigurationToClientPacketK
} }
func IgnoreConfig(c *proto.Conn) (err error) { func IgnoreConfig(c *proto.Conn) (err error) {
err = c.Start(&ConfigIgnorer{c}) ci := &ConfigIgnorer{c}
ci.RegisterCritical(ci.Default)
ci.RegisterUntilLatest(ci.OnKnownPacks)
ci.RegisterUntilLatest(ci.OnFinish)
ci.RegisterUntilLatest(ci.OnPing)
ci.RegisterUntilLatest(ci.OnKeepAlive)
err = ci.StartConn()
if err != nil { if err != nil {
err = errors.Join(err, errors.New("failed to ignore config")) err = errors.Join(err, errors.New("failed to ignore config"))
} }
+113 -9
View File
@@ -1,22 +1,126 @@
package client package client
import ( import (
"context"
"errors"
"net" "net"
"strconv"
"strings" "strings"
"time"
) )
func LookupMinecraftSRV(host string, port uint16) (hostRet string, portRet uint16) { type DNSCheckFunc func(addr string) error
hostRet = host // in case of error
portRet = port // DoDns resolves a DNS name to an IP address
if port != 25565 { // It should resolve a minecraft compatible address into something net.Dial
func DoDns(in string) (out string, host string, portN uint16, err error) {
return DoDNSChecked(in, nil)
}
// DoDNSChecked resolves a DNS name to an IP address
// It should resolve a minecraft compatible address into something net.Dial
// It also optionally accepts a function to "check" the address
func DoDNSChecked(in string, f DNSCheckFunc) (connectTo string, host string, portN uint16, err error) {
// https://mcsrc.dev/1/26.1-pre-1/net/minecraft/client/multiplayer/resolver/ServerAddress#L34
host, port, err := net.SplitHostPort(in)
if err != nil {
var addrErr *net.AddrError
if errors.As(err, &addrErr) && addrErr.Err == "missing port in address" {
err = nil
host = in
port = "25565"
} else {
return
}
}
porti, err := strconv.Atoi(port)
if err != nil {
return return
} }
_, srvs, err := net.LookupSRV("minecraft", "tcp", host) if f == nil {
if err != nil || len(srvs) == 0 { f = func(addr string) error { return nil }
}
err = f(host)
if err != nil {
return return
} }
target := strings.TrimSuffix(srvs[0].Target, ".") portN = uint16(porti)
hostRet = target outIP, err := net.ResolveIPAddr("ip", host)
portRet = srvs[0].Port if err != nil {
return
}
err = f(outIP.String())
if err != nil {
return
}
connectTo = outIP.String() + ":" + port
if portN != 25565 {
return
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second) // otherwise this takes 10+ seconds
defer cancel()
r := &net.Resolver{}
_, srvs, _ := r.LookupSRV(ctx, "minecraft", "tcp", host)
if len(srvs) == 0 {
return
}
host = strings.TrimSuffix(srvs[0].Target, ".")
portN = srvs[0].Port
outIP, err = net.ResolveIPAddr("ip", host)
if err != nil {
return
}
err = f(outIP.String())
if err != nil {
return
}
connectTo = outIP.String() + ":" + port
return
}
// DoDnsSimple resolves a DNS name to an IP address
// It should resolve a minecraft compatible address into something net.Dial
// It does not check the address
func DoDnsSimple(in string) (out string, err error) {
host, port, err := net.SplitHostPort(in)
if err != nil {
var addrErr *net.AddrError
if errors.As(err, &addrErr) && addrErr.Err == "missing port in address" {
err = nil
host = in
port = "25565"
} else {
return
}
}
porti, err := strconv.Atoi(port)
if err != nil {
return
}
portN := uint16(porti)
_, err = net.ResolveIPAddr("ip", host)
if err != nil {
return
}
out = host + ":" + strconv.Itoa(int(portN))
if portN != 25565 {
return
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second) // otherwise this takes 10+ seconds
defer cancel()
r := &net.Resolver{}
_, srvs, _ := r.LookupSRV(ctx, "minecraft", "tcp", host)
if len(srvs) == 0 {
return
}
host = strings.TrimSuffix(srvs[0].Target, ".")
portN = srvs[0].Port
out = host + ":" + strconv.Itoa(int(portN))
return return
} }
+27
View File
@@ -0,0 +1,27 @@
package client
import "testing"
func TestDoDNS(t *testing.T) {
type Case struct {
Input string
Host string
portN uint16
}
cases := []Case{
{"localhost", "localhost", 25565},
{"play.hypixel.net", "play.hypixel.net", 25565},
{"1f2d.net", "tcpshield.1f2d.net", 25565},
}
for _, c := range cases {
t.Logf("Testing %s", c.Input)
_, host, portN, err := DoDns(c.Input)
if err != nil {
t.Error(err)
continue
}
if host != c.Host || portN != c.portN {
t.Errorf("expected %s:%d, got %s:%d", c.Host, c.portN, host, portN)
}
}
}
+31
View File
@@ -0,0 +1,31 @@
package client
import (
"net"
"strconv"
"github.com/admin-else/strom/proto"
"github.com/admin-else/strom/proto_base"
"github.com/admin-else/strom/proto_generated/v1_21_8"
)
func MakeHandshakePacket(c *proto.Conn, nextState proto_base.State) (p *v1_21_8.HandshakingToServerPacketSetProtocol, err error) {
return MakeHandshakePacketAddr(c, nextState, c.RemoteAddr().String())
}
// MakeHandshakePacketAddr gets a custom addr
func MakeHandshakePacketAddr(s *proto.Conn, nextState proto_base.State, addr string) (p *v1_21_8.HandshakingToServerPacketSetProtocol, err error) {
p = &v1_21_8.HandshakingToServerPacketSetProtocol{NextState: int32(nextState), ProtocolVersion: s.ProtocolVersion}
var portStr string
p.ServerHost, portStr, err = net.SplitHostPort(addr)
if err != nil {
return
}
var portUint uint64
portUint, err = strconv.ParseUint(portStr, 10, 16)
if err != nil {
return
}
p.ServerPort = uint16(portUint)
return
}
+59 -52
View File
@@ -1,4 +1,4 @@
package modules package client
import ( import (
"crypto/rand" "crypto/rand"
@@ -6,12 +6,8 @@ import (
"crypto/x509" "crypto/x509"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"net"
"strconv"
"github.com/admin-else/strom/api" "github.com/admin-else/strom/api"
"github.com/admin-else/strom/client"
"github.com/admin-else/strom/crypto" "github.com/admin-else/strom/crypto"
"github.com/admin-else/strom/event" "github.com/admin-else/strom/event"
"github.com/admin-else/strom/proto" "github.com/admin-else/strom/proto"
@@ -30,6 +26,12 @@ type LoginClient struct {
GivenAccount *v1_21_8.LoginToClientPacketSuccess GivenAccount *v1_21_8.LoginToClientPacketSuccess
} }
var (
NoTokenErr = errors.New("the account has no token so we cant join online servers")
BadPublicKeyTypeErr = errors.New("the public key is not rsa")
FailedToLoginErr = errors.New("failed to login")
)
type KickedDuringLoginErr struct { type KickedDuringLoginErr struct {
text.Component text.Component
} }
@@ -38,46 +40,20 @@ func (k KickedDuringLoginErr) Error() string {
return k.String() return k.String()
} }
func (s *LoginClient) Default(event event.Unhandled) (err error) { func (s *LoginClient) OnDefault(event event.Unhandled) (err error) {
err = fmt.Errorf("unexpected event: %#v", event) if _, ok := event.Val.(proto_base.EncodeDecodeAble); !ok {
return
}
func (s *LoginClient) OnCycle(_ event.Tick) (err error) {
return
}
func (s *LoginClient) OnStart(_ event.OnStart) (err error) {
if s.ServerHost == "" && s.ServerPort == 0 {
var portStr string
s.ServerHost, portStr, err = net.SplitHostPort(s.RemoteAddr().String())
if err != nil {
return
}
var portUint uint64
portUint, err = strconv.ParseUint(portStr, 10, 16)
if err != nil {
return
}
s.ServerPort = uint16(portUint)
}
err = s.Send(&v1_21_8.HandshakingToServerPacketSetProtocol{
ProtocolVersion: s.ProtocolVersion,
ServerHost: s.ServerHost,
ServerPort: s.ServerPort,
NextState: int32(proto_base.Login),
})
if err != nil {
return return
} }
s.SetState(proto_base.Login) s.Log.Warn("unexpected packet during login client", "packet", event.Val)
err = s.Send(&v1_21_8.LoginToServerPacketLoginStart{Username: s.Account.Name, PlayerUUID: s.Account.Uuid}) return
}
func (s *LoginClient) OnClose(_ event.Close) (err error) {
return return
} }
func (s *LoginClient) OnCompress(compress *v1_21_8.LoginToClientPacketCompress) (err error) { func (s *LoginClient) OnCompress(compress *v1_21_8.LoginToClientPacketCompress) (err error) {
s.CompressionThreshold = compress.Threshold s.SetCompressionThreshold(compress.Threshold)
return return
} }
@@ -87,7 +63,7 @@ func (s *LoginClient) OnEncrypt(packet *v1_21_8.LoginToClientPacketEncryptionBeg
if packet.ShouldAuthenticate { if packet.ShouldAuthenticate {
if s.Account.Ygg == "" { if s.Account.Ygg == "" {
err = fmt.Errorf("the account has no token so we cant join online servers") err = NoTokenErr
return return
} }
serverId := crypto.AuthDigest([]byte(packet.ServerId), sharedSecret, packet.PublicKey) serverId := crypto.AuthDigest([]byte(packet.ServerId), sharedSecret, packet.PublicKey)
@@ -103,7 +79,7 @@ func (s *LoginClient) OnEncrypt(packet *v1_21_8.LoginToClientPacketEncryptionBeg
} }
pub, ok := pubAny.(*rsa.PublicKey) pub, ok := pubAny.(*rsa.PublicKey)
if !ok { if !ok {
err = fmt.Errorf("public key is not rsa") err = BadPublicKeyTypeErr
return return
} }
verifyTokenEnc, err := rsa.EncryptPKCS1v15(rand.Reader, pub, packet.VerifyToken) verifyTokenEnc, err := rsa.EncryptPKCS1v15(rand.Reader, pub, packet.VerifyToken)
@@ -145,28 +121,59 @@ func (s *LoginClient) OnSuccess(success *v1_21_8.LoginToClientPacketSuccess) (er
return return
} }
func Login(c *proto.Conn, account *api.Account) (err error) { func (s *LoginClient) OnStart() (err error) {
err = c.Start(&LoginClient{ return
}
func LoginRaw(c *proto.Conn, account *api.Account) (err error) {
lc := &LoginClient{
Conn: c, Conn: c,
Account: account, Account: account,
}) }
lc.RegisterCritical(lc.OnDefault)
lc.RegisterCritical(lc.OnClose)
lc.RegisterCriticalUntilLatest(lc.OnCompress)
lc.RegisterCriticalUntilLatest(lc.OnEncrypt)
lc.RegisterCriticalUntilLatest(lc.OnDisconnect)
lc.RegisterCriticalUntilLatest(lc.OnSuccess)
p, err := MakeHandshakePacket(lc.Conn, proto_base.Login)
if err != nil { if err != nil {
err = errors.Join(err, errors.New("failed to login")) return
}
err = lc.Send(p)
if err != nil {
return
}
lc.SetState(proto_base.Login)
err = lc.Send(&v1_21_8.LoginToServerPacketLoginStart{Username: lc.Account.Name, PlayerUUID: lc.Account.Uuid})
err = lc.StartConn()
if err != nil {
err = errors.Join(FailedToLoginErr, err)
} }
return return
} }
func ConnectAndLogin(connectTo string, account *api.Account) (c *proto.Conn, err error) { func LoginNoSrv(connectTo string, account *api.Account) (c *proto.Conn, err error) {
c, err = client.Connect(connectTo) c, err = Connect(connectTo)
if err != nil { if err != nil {
return return
} }
err = c.Start(&LoginClient{ err = LoginRaw(c, account)
Conn: c, return
Account: account, }
})
func Login(connectTo string, account *api.Account) (c *proto.Conn, err error) {
connectTo, err = DoDnsSimple(connectTo)
if err != nil { if err != nil {
err = errors.Join(errors.New("failed to login"), err) return
} }
c, err = Connect(connectTo)
if err != nil {
return
}
err = LoginRaw(c, account)
return return
} }
-54
View File
@@ -1,54 +0,0 @@
package modules
import (
"fmt"
"strconv"
"strings"
"github.com/admin-else/strom/event"
"github.com/admin-else/strom/proto"
"github.com/admin-else/strom/proto_base"
"github.com/admin-else/strom/data"
"github.com/admin-else/strom/proto_generated/v1_21_8"
)
type StatusClient struct {
*proto.Conn
Status string
}
func (s *StatusClient) Default(event any) (err error) {
err = fmt.Errorf("unexpected event: %v", event)
return
}
func (s *StatusClient) OnStart(_ event.OnStart) (err error) {
parts := strings.Split(s.RemoteAddr().String(), ":")
versionData, err := data.LookUpProtocolVersionByName(s.Version)
if err != nil {
return
}
port, err := strconv.Atoi(parts[1])
if err != nil {
return
}
err = s.Send(&v1_21_8.HandshakingToServerPacketSetProtocol{
ProtocolVersion: int32(versionData.Version),
ServerHost: parts[0],
ServerPort: uint16(port),
NextState: int32(proto_base.Status),
})
if err != nil {
return
}
s.SetState(proto_base.Status)
err = s.Send(&v1_21_8.StatusToServerPacketPingStart{})
return
}
func (s *StatusClient) OnStatus(p v1_21_8.StatusToClientPacketServerInfo) (err error) {
s.Status = p.Response
err = event.HandlerDoneErr{}
return
}
-63
View File
@@ -1,63 +0,0 @@
package modules
import "time"
type IntervalTask struct {
F func() error
LastTrigger time.Time
Interval time.Duration
}
type OnceTask struct {
F func() error
Trigger time.Time
}
type Timer struct {
Once []OnceTask
Interval []IntervalTask
Active bool
}
func (t *Timer) Tick() (err error) {
if !t.Active {
return
}
for i, task := range t.Interval {
if time.Since(task.LastTrigger) >= task.Interval {
task.LastTrigger = time.Now()
err = task.F()
if err != nil {
return
}
}
t.Interval[i] = task
}
var triggerLater []OnceTask
for _, task := range t.Once {
if task.Trigger.After(time.Now()) {
err = task.F()
if err != nil {
return
}
} else {
triggerLater = append(triggerLater, task)
}
}
t.Once = triggerLater
return
}
func (t *Timer) Every(interval time.Duration, f func() error) {
t.Interval = append(t.Interval, IntervalTask{
F: f,
Interval: interval,
})
}
func (t *Timer) In(interval time.Duration, f func() error) {
t.Once = append(t.Once, OnceTask{
F: f,
Trigger: time.Now().Add(interval),
})
}
+91
View File
@@ -0,0 +1,91 @@
package client
import (
"context"
"encoding/json"
"time"
"github.com/admin-else/strom/event"
"github.com/admin-else/strom/proto"
"github.com/admin-else/strom/proto_base"
"github.com/admin-else/strom/server"
"github.com/admin-else/strom/proto_generated/v1_21_8"
)
type StatusClient struct {
*proto.Conn
Status string
PingSendTime, PingReceiveTime time.Time
DoPingRoundTripTime bool
}
func (s *StatusClient) OnStatus(p *v1_21_8.StatusToClientPacketServerInfo) (err error) {
s.Status = p.Response
s.PingSendTime = time.Now()
if s.DoPingRoundTripTime {
err = s.Send(&v1_21_8.StatusToServerPacketPing{Time: s.PingSendTime.UnixMilli()})
} else {
err = event.HandlerDoneErr{}
}
return
}
func (s *StatusClient) OnPong(p *v1_21_8.StatusToClientPacketPing) (err error) {
s.PingReceiveTime = time.Now()
err = event.HandlerDoneErr{}
return
}
// StatusRaw returns a StatusClient that is not connected to a server.
// So ignore the resource leak warning. And maybe attach a warn ignore comment.
// It does not resolve SRV records.
func StatusRaw(ctx context.Context, addr string) (s *StatusClient, err error) {
c, err := ConnectVersionLess(addr)
if err != nil {
return
}
defer c.Close()
err = c.SetVersion("1.21.8")
if err != nil {
return
}
s = &StatusClient{
Conn: c,
}
s.RegisterCriticalUntilLatest(s.OnStatus)
s.RegisterCriticalUntilLatest(s.OnPong)
p, err := MakeHandshakePacketAddr(s.Conn, proto_base.Status, addr)
if err != nil {
return
}
err = s.Send(p)
if err != nil {
return
}
s.SetState(proto_base.Status)
err = s.Send(&v1_21_8.StatusToServerPacketPingStart{})
err = s.StartConn()
return
}
// StatusNoDns is like Status but does not resolve SRV records.
func StatusNoDns(addr string) (status server.StatusResponse, err error) {
s, err := StatusRaw(context.Background(), addr)
if err != nil {
return
}
err = json.Unmarshal([]byte(s.Status), &status)
return
}
// Status resolves the status of the minecraft server at the given address.
func Status(addr string) (status server.StatusResponse, err error) {
addr, err = DoDnsSimple(addr)
if err != nil {
return
}
return StatusNoDns(addr)
}
+60
View File
@@ -0,0 +1,60 @@
package api
import (
"encoding/json"
"errors"
"flag"
"os"
"github.com/admin-else/strom/api"
)
var cmd = flag.NewFlagSet("api", flag.ContinueOnError)
var tokenFlag = cmd.String("token", os.Getenv("MC_TOKEN"), "token to use")
var renameFlag = cmd.String("rename", "", "rename the player")
var uuidFlag = cmd.String("uuid", "", "get data about player with uuid")
var nameFlag = cmd.String("name", "", "get data about player with name")
var unsignedFlag = cmd.Bool("unsigned", true, "use unsigned mode for properties signatures")
var PleaseProvideArgumentErr = errors.New("please provide an argument")
func Run(args []string) (err error) {
err = cmd.Parse(args)
if err != nil {
return
}
a := &api.Account{}
if *tokenFlag != "" {
a, err = api.NewAccountFromYGG(*tokenFlag)
if err != nil {
return
}
}
var data any
if *renameFlag != "" {
data, err = a.ChangeName(*renameFlag)
if err != nil {
return
}
} else if *uuidFlag != "" || *nameFlag != "" {
if *nameFlag != "" {
var idName api.IdName
idName, err = api.NameToId(*nameFlag)
if err != nil {
return
}
*uuidFlag = idName.Id
}
data, err = api.Profile(*uuidFlag, *unsignedFlag)
if err != nil {
return
}
} else {
err = PleaseProvideArgumentErr
return
}
err = json.NewEncoder(os.Stdout).Encode(data)
return
}
+118
View File
@@ -0,0 +1,118 @@
package data
import (
"encoding/json"
"fmt"
"maps"
"os"
"slices"
"github.com/admin-else/strom/data"
"github.com/admin-else/strom/proto_generated"
"github.com/admin-else/strom/util"
)
// strom data 1.21.11 blocks id 0 name => air
// {
// "id": 0,
// "name": "air",
// "displayName": "Air",
// "hardness": 0.0,
// "resistance": 0.0,
// "stackSize": 64,
// "diggable": false,
// "material": "default",
// "transparent": true,
// "emitLight": 0,
// "filterLight": 0,
// "defaultState": 0,
// "minStateId": 0,
// "maxStateId": 0,
// "states": [],
// "drops": [],
// "boundingBox": "empty"
// },
func Run(args []string) (err error) {
var dataValues any
switch len(args) {
case 0: // print available versions
dataValues = proto_generated.SupportedVersions
case 1: // print available data for version
dataValues = slices.Collect(maps.Keys(data.Paths.Data[args[0]]))
case 2:
err = data.LoadVersionedJson(args[0], args[1], &dataValues)
case 3:
err = data.LoadVersionedJson(args[0], args[1], &dataValues)
if err != nil {
return
}
var dataSlices []any
dataSlices, err = util.AssertTypeError[[]any](dataValues)
if err != nil {
return
}
var result = make([]any, len(dataSlices))
for _, v := range dataSlices {
var dataMap map[string]any
dataMap, err = util.AssertTypeError[map[string]any](v)
if err != nil {
return
}
var vToAppend any
vToAppend, err = util.MapGetError(dataMap, args[2])
if err != nil {
return
}
result = append(result, vToAppend)
}
dataValues = result
case 4, 5:
err = data.LoadVersionedJson(args[0], args[1], &dataValues)
if err != nil {
return
}
var dataSlices []any
dataSlices, err = util.AssertTypeError[[]any](dataValues)
if err != nil {
return
}
found := false
for _, v := range dataSlices {
var dataMap map[string]any
dataMap, err = util.AssertTypeError[map[string]any](v)
if err != nil {
return
}
if v2, ok := dataMap[args[2]]; ok {
if args[3] != fmt.Sprint(v2) {
continue
}
dataValues = dataMap
found = true
if len(args) == 5 {
dataValues, err = util.MapGetError(dataMap, args[4])
if err != nil {
return
}
}
break
}
}
if !found {
err = fmt.Errorf("not found")
return
}
default:
err = fmt.Errorf("too many arguments")
}
if err == nil {
e := json.NewEncoder(os.Stdout)
e.SetIndent("", " ")
err = e.Encode(dataValues)
return
}
return
}
+52
View File
@@ -0,0 +1,52 @@
package extract_mca
import (
"flag"
"fmt"
"log/slog"
"os"
"github.com/admin-else/strom/level/anvil"
"github.com/admin-else/strom/nbt"
)
var (
cmd = flag.NewFlagSet("print-nbt", flag.ContinueOnError)
FileFlag = cmd.String("file", "", "The MCA file to extract")
IndexXFlag = cmd.Int("x", 0, "The x chunk coordinate")
IndexZFlag = cmd.Int("z", 0, "The z chunk coordinate")
ToFlag = cmd.String("to", "mca-chunk.nbt", "The output file")
)
func Run(args []string) (err error) {
err = cmd.Parse(args)
if err != nil {
return
}
if *FileFlag == "" {
return fmt.Errorf("no file specified")
}
f, err := os.Open(*FileFlag)
if err != nil {
return
}
defer f.Close()
mca, err := anvil.ReadChunkHeader(f)
if err != nil {
return
}
t, err := mca.TimeAt(f, int32(*IndexXFlag), int32(*IndexZFlag))
if err != nil {
return
}
slog.Info("Chunk last written", "time", t)
n, err := mca.ChunkAt(f, int32(*IndexXFlag), int32(*IndexZFlag))
if err != nil {
return
}
err = nbt.WriteUnstructuredFilePath(*ToFlag, n)
if err != nil {
return
}
return
}
+82
View File
@@ -0,0 +1,82 @@
package main
import (
"debug/buildinfo"
"errors"
"fmt"
"log/slog"
"maps"
"os"
"slices"
"github.com/admin-else/strom/cmd/strom/api"
"github.com/admin-else/strom/cmd/strom/data"
"github.com/admin-else/strom/cmd/strom/extract_mca"
"github.com/admin-else/strom/cmd/strom/offline_uuid"
"github.com/admin-else/strom/cmd/strom/packet_info"
"github.com/admin-else/strom/cmd/strom/packet_inspector"
"github.com/admin-else/strom/cmd/strom/print_nbt"
"github.com/admin-else/strom/cmd/strom/print_replay"
"github.com/admin-else/strom/cmd/strom/status"
)
var ExpectedASubcommandErr = errors.New("expected a subcommand")
var UnknownSubcommandErr = errors.New("unknown subcommand try 'strom help' for a list of subcommands")
func Version(args []string) (err error) {
selfPath, err := os.Executable()
if err != nil {
return
}
info, err := buildinfo.ReadFile(selfPath)
if err != nil {
return
}
fmt.Println("strom cli ", info.Main.Version, " (", info.Main.Sum, ")")
return
}
var subcommands = map[string]func(args []string) error{
"offline-uuid": offline_uuid.Run,
"packet-info": packet_info.Run,
"print-nbt": print_nbt.Run,
"status": status.Run,
"packet-spy": packet_inspector.Run,
"api": api.Run,
"version": Version,
"extract-mca": extract_mca.Run,
"data": data.Run,
"print-replay": print_replay.Run,
}
func Help(args []string) (err error) {
subcommandNames := slices.Collect(maps.Keys(subcommands))
slices.Sort(subcommandNames)
fmt.Println("Available subcommands", subcommandNames)
return
}
func mainE() (err error) {
subcommands["help"] = Help
args := os.Args
if len(args) < 2 {
err = ExpectedASubcommandErr
return
}
f, ok := subcommands[args[1]]
if !ok {
err = UnknownSubcommandErr
return
}
err = f(args[2:])
return
}
func main() {
err := mainE()
if err != nil {
slog.Error("exiting", "err", err)
}
}
+20
View File
@@ -0,0 +1,20 @@
package offline_uuid
import (
"flag"
"fmt"
"github.com/admin-else/strom/crypto"
)
var cmd = flag.NewFlagSet("offline-uuid", flag.ContinueOnError)
var nameFlag = cmd.String("name", "Notch", "name of the player")
func Run(args []string) (err error) {
err = cmd.Parse(args)
if err != nil {
return
}
fmt.Println(crypto.FromOfflinePlayer(*nameFlag))
return
}
+169
View File
@@ -0,0 +1,169 @@
package packet_info
import (
"flag"
"fmt"
"strconv"
"github.com/admin-else/strom/data"
"github.com/admin-else/strom/proto"
"github.com/admin-else/strom/proto_base"
"github.com/admin-else/strom/proto_generated"
)
var cmd = flag.NewFlagSet("packet-info", flag.ContinueOnError)
var versionFlag = cmd.String("version", "", "protocol version or minecraft version name")
var stateFlag = cmd.String("state", "", "handshaking, status, login, configuration, play")
var directionFlag = cmd.String("direction", "", "toserver, toclient")
var idFlag = cmd.Int("id", -1, "packet id")
var nameFlag = cmd.String("name", "", "packet name")
func Run(args []string) (err error) {
err = cmd.Parse(args)
if err != nil {
return
}
var version int32
if *versionFlag != "" {
v, err := data.LookUpVersionByName(*versionFlag)
if err != nil {
v2, err := parseVersion(*versionFlag)
if err != nil {
return fmt.Errorf("invalid version: %s", *versionFlag)
}
v, err = data.LookUpVersionByProtocolVersion(v2)
if err != nil {
return err
}
}
version = v.Version
}
var state proto_base.State
if *stateFlag != "" {
state, err = parseState(*stateFlag)
if err != nil {
return
}
}
var direction proto_base.Direction
if *directionFlag != "" {
direction, err = parseDirection(*directionFlag)
if err != nil {
return
}
}
if *idFlag != -1 && *nameFlag != "" {
err = fmt.Errorf("cannot specify both id and name")
return
}
if *idFlag != -1 {
if *versionFlag == "" || *stateFlag == "" || *directionFlag == "" {
err = fmt.Errorf("version, state, and direction are required when looking up by id")
return
}
p, ok := proto.LookUpTypeByPacketInfo(direction, state, int32(*idFlag), version)
if !ok {
err = fmt.Errorf("packet not found")
return
}
printPacketInfo(p)
return
}
if *nameFlag != "" {
if *versionFlag == "" {
err = fmt.Errorf("version is required when looking up by name")
return
}
if state != 0 || direction != 0 {
p, ok := proto.LookupPacketInfoByNameProtocolVersionStateAndDirection(*nameFlag, version, state, direction)
if !ok {
err = fmt.Errorf("packet not found")
return
}
printPacketInfo(p)
} else {
var found bool
for _, p := range proto_generated.Packets {
if p.Name == *nameFlag && p.ProtocolVersion == version {
printPacketInfo(p)
found = true
}
}
if !found {
err = fmt.Errorf("packet not found")
}
}
return
}
err = fmt.Errorf("must specify either -id or -name")
return
}
func parseState(s string) (proto_base.State, error) {
switch s {
case "handshaking":
return proto_base.Handshaking, nil
case "status":
return proto_base.Status, nil
case "login":
return proto_base.Login, nil
case "configuration":
return proto_base.Configuration, nil
case "play":
return proto_base.Play, nil
default:
return 0, fmt.Errorf("unknown state: %s", s)
}
}
func parseDirection(s string) (proto_base.Direction, error) {
switch s {
case "toserver":
return proto_base.ToServer, nil
case "toclient":
return proto_base.ToClient, nil
default:
return 0, fmt.Errorf("unknown direction: %s", s)
}
}
func parseVersion(val string) (int32, error) {
v, err := strconv.ParseInt(val, 10, 32)
if err != nil {
return 0, err
}
return int32(v), nil
}
func printPacketInfo(p proto_base.PacketInfo) {
v, _ := data.LookUpVersionByProtocolVersion(p.ProtocolVersion)
fmt.Printf("Name: %s\n", p.Name)
fmt.Printf("ID: %d\n", p.PacketId)
fmt.Printf("State: %s\n", stateToString(p.State))
fmt.Printf("Direction: %s\n", p.Direction)
fmt.Printf("Version: %d (%s)\n", p.ProtocolVersion, v.MinecraftVersion)
}
func stateToString(s proto_base.State) string {
switch s {
case proto_base.Handshaking:
return "handshaking"
case proto_base.Status:
return "status"
case proto_base.Login:
return "login"
case proto_base.Configuration:
return "configuration"
case proto_base.Play:
return "play"
default:
return "unknown"
}
}
+129
View File
@@ -0,0 +1,129 @@
package packet_inspector
import (
"flag"
"log/slog"
"github.com/admin-else/strom/api"
"github.com/admin-else/strom/client"
"github.com/admin-else/strom/event"
"github.com/admin-else/strom/nbt"
"github.com/admin-else/strom/proto"
"github.com/admin-else/strom/proto_base"
"github.com/admin-else/strom/proto_generated/v1_21_11"
"github.com/admin-else/strom/server"
"github.com/admin-else/strom/text"
)
var Cmd = flag.NewFlagSet("packet-inspector", flag.ContinueOnError)
var OfflineNameFlag = Cmd.String("name", "packet_inspector", "offline player name")
var Token = Cmd.String("token", "", "token to use")
var TargetAddr = Cmd.String("addr", "127.0.0.1:25565", "address to connect to")
var ListenAddr = Cmd.String("listen", "127.0.0.1:25566", "address to listen on")
type Proxy struct {
Client, Servee *proto.Conn
Data nbt.Tag
}
func (p *Proxy) Start() (err error) {
p.Client.RegisterCritical(p.OnAnything)
p.Servee.RegisterCritical(p.OnAnything)
p.Servee.RegisterCriticalUntilLatest(p.OnFinishConfiguration)
errChan := make(chan error)
go func() {
errChan <- p.Client.StartConn()
}()
go func() {
errChan <- p.Servee.StartConn()
}()
err = <-errChan
return
}
func (p *Proxy) OnAnything(e event.Anything) (err error) {
packet, ok := e.Val.(proto_base.EncodeDecodeAble)
if !ok {
return
}
packetInfo, ok := proto.LookupPacketInfoByType(packet)
if !ok {
return
}
switch packetInfo.Direction {
case proto_base.ToServer:
err = p.Client.Send(packet)
case proto_base.ToClient:
err = p.Servee.Send(packet)
}
return
}
func (p *Proxy) OnFinishConfiguration(packet *v1_21_11.ConfigurationToServerPacketFinishConfiguration) (err error) {
err = p.Client.Send(packet)
if err != nil {
return
}
p.Servee.SetState(proto_base.Play)
p.Client.SetState(proto_base.Play)
err = event.DontForwardErr
return
}
var StatusResponse = server.StatusResponse{
Version: server.StatusResponseVersion{
Name: text.Pretty("STROM"),
Protocol: 772,
},
Players: server.StatusResponsePlayers{},
Description: text.Pretty("Packet spy forwards to " + *TargetAddr),
Favicon: "",
EnforcesSecureChat: false,
}
func Run(args []string) (err error) {
err = Cmd.Parse(args)
if err != nil {
return
}
slog.SetLogLoggerLevel(slog.LevelDebug)
slog.Info("Starting packet inspector", "listen", *ListenAddr)
err = server.StartServerWithOnConn(*ListenAddr, func(serveeConn *proto.Conn) (err error) {
serveeConn.DebugPrintPackets = []string{""}
p := &Proxy{Servee: serveeConn, Client: nil}
var acc = api.NewOfflineAccount(*OfflineNameFlag)
if *Token != "" {
acc, err = api.NewAccountFromYGG(*Token)
if err != nil {
return
}
}
_, err = server.ServeLogin(serveeConn, server.WithOtherAccount(acc), server.WithStatus(StatusResponse), server.WithoutOnlineMode())
if err != nil {
return
}
*TargetAddr, err = client.DoDnsSimple(*TargetAddr)
if err != nil {
return
}
c, err := client.Connect(*TargetAddr)
if err != nil {
return
}
c.DebugPrintPackets = []string{""}
err = client.LoginRaw(c, acc)
if err != nil {
return
}
defer c.Close()
p.Client = c
err = p.Start()
return
})
return
}
+53
View File
@@ -0,0 +1,53 @@
package print_nbt
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"os"
"github.com/admin-else/strom/nbt"
)
var (
cmd = flag.NewFlagSet("print-nbt", flag.ContinueOnError)
FileFlag = cmd.String("file", "", "The NBT file to print")
HashFormatFlag = cmd.Bool("snbt", false, "will print with go %#v")
)
func Run(args []string) (err error) {
err = cmd.Parse(args)
if err != nil {
return
}
if *FileFlag == "" {
return fmt.Errorf("no file specified")
}
f, err := os.Open(*FileFlag)
if err != nil {
return
}
defer f.Close()
n, err := nbt.ReadUnstructuredFile(f)
if err != nil {
return
}
var b []byte
if *HashFormatFlag {
bb := bytes.NewBuffer(nil)
err = nbt.PrintSNBTAny(n.Value, bb)
if err != nil {
return
}
b = bb.Bytes()
//b = []byte(strings.ReplaceAll(string(b), ",", ",\n"))
} else {
b, err = json.MarshalIndent(n, "", " ")
}
if err != nil {
return
}
_, err = os.Stdout.Write(b)
return
}
@@ -0,0 +1,18 @@
package failed_packets_test
import (
"bytes"
"testing"
generated "github.com/admin-else/strom/proto_generated/%v"
)
// Error: %v
func TestFailedPacket%10X(t *testing.T) {
p := &generated.%v{}
b := bytes.NewBuffer(%#v)
err := p.Decode(b)
if err != nil {
t.Fatal(err)
}
}
+161
View File
@@ -0,0 +1,161 @@
package print_replay
import (
"bytes"
"crypto/sha256"
_ "embed"
"encoding/binary"
"errors"
"flag"
"fmt"
"io"
"log/slog"
"os"
"reflect"
"strings"
"github.com/admin-else/strom/data"
"github.com/admin-else/strom/proto"
"github.com/admin-else/strom/proto_base"
)
var (
cmd = flag.NewFlagSet("print-replay", flag.ContinueOnError)
FileFlag = cmd.String("file", "", "The tmcpr file to print")
ProtocolVersion = cmd.Int("protocol", -1, "The protocol version")
CreateTestsPath = cmd.String("create-tests", "", "")
StateFlag = cmd.String("state", "login", "Initial state: login, config, play")
)
// TODO: maybe use the proto replay api
//go:embed failed_packet.go.tmpl
var TestSrcF string
func SaveUnCodeAbleAsTest(packet *proto.UnCodablePacket) {
hUntrimmed := sha256.Sum256(packet.Data)
h := hUntrimmed[:8]
f, err := os.Create(fmt.Sprintf(*CreateTestsPath+"/%v_%10x_test.go", len(packet.Data), h))
if err != nil {
panic(err)
}
ret, err := data.LookUpVersionByProtocolVersion(packet.Info.ProtocolVersion)
if err != nil {
panic(err)
}
goPackage := "v" + strings.ReplaceAll(ret.MinecraftVersion, ".", "_")
//goland:noinspection GoUnhandledErrorResult
defer f.Close()
_, err = fmt.Fprintf(f, TestSrcF, goPackage, packet.Err, h, reflect.TypeOf(packet.Info.Type).Elem().Name(), packet.Data)
if err != nil {
panic(err)
}
slog.Info("Packet failed to parse", "error", packet.Err, "saved", f.Name(), "data", fmt.Sprintf("%q", packet.Data))
}
var state = proto_base.Login
func UnpackPacket(r io.Reader) (packet proto_base.EncodeDecodeAble, err error) {
var timestamp, length uint32
err = binary.Read(r, binary.BigEndian, &timestamp)
if err != nil {
return
}
err = binary.Read(r, binary.BigEndian, &length)
if err != nil {
return
}
// Read the packet data into a byte slice
packetData := make([]byte, length)
_, err = io.ReadFull(r, packetData)
if err != nil {
return
}
// Use bytes.Reader instead of bytes.Buffer
b := bytes.NewReader(packetData)
packetId, err := proto_base.DecodeVarInt(b)
if err != nil {
return
}
// Calculate position after reading the packet ID
// indexafterid represents how many bytes we've read so far
indexafterid := int(b.Size()) - b.Len()
i, ok := proto.LookUpTypeByPacketInfo(proto_base.ToClient, state, packetId, int32(*ProtocolVersion))
if !ok {
packet = &proto.UnCodablePacket{Err: proto.BadPacketIdErr, Data: packetData, Info: i}
return
}
packet = reflect.New(reflect.TypeOf(i.Type).Elem()).Interface().(proto_base.EncodeDecodeAble)
err = packet.Decode(b)
if err != nil {
packet = &proto.UnCodablePacket{Err: err, Data: packetData[indexafterid:], Info: i}
return
}
switch i.Name {
case "success":
state = proto_base.Configuration
case "finish_configuration":
state = proto_base.Play
}
return
}
func Run(args []string) (err error) {
err = cmd.Parse(args)
if err != nil {
return
}
if *ProtocolVersion == -1 {
return fmt.Errorf("no protocol version specified")
}
if *FileFlag == "" {
return fmt.Errorf("no file specified")
}
switch *StateFlag {
case "login":
state = proto_base.Login
case "config":
state = proto_base.Configuration
case "play":
state = proto_base.Play
default:
return fmt.Errorf("unknown state: %s", *StateFlag)
}
f, err := os.Open(*FileFlag)
if err != nil {
return
}
defer f.Close()
var totalPackets, failedPackets int
for {
var packet proto_base.EncodeDecodeAble
packet, err = UnpackPacket(f)
unCodablePacket, ok := packet.(*proto.UnCodablePacket)
if ok {
if *CreateTestsPath != "" {
SaveUnCodeAbleAsTest(unCodablePacket)
}
failedPackets++
}
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Packet: %#v\n", packet)
}
if errors.Is(err, io.EOF) {
break
}
totalPackets++
}
fmt.Printf("Total packets: %d, failed packets: %d, %%failed: %.2f%%\n", totalPackets, failedPackets, float64(failedPackets)/float64(totalPackets)*100)
return
}
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2d90ee976987678593a6b1d09136bb9b4fd131390796ea6e413376a6ddc63226
size 75035693
+1
View File
@@ -0,0 +1 @@
[{"realTimestamp":9845034,"value":{"position":{"x":-31.946051078575692,"y":93.0,"z":29.523387113769626,"yaw":-627.44653,"pitch":37.573395,"roll":0.0}}},{"realTimestamp":9845138,"value":{"position":{"x":-31.946051078575692,"y":93.0,"z":29.523387113769626,"yaw":-627.44653,"pitch":37.573395,"roll":0.0}}},{"realTimestamp":9844902,"value":{"position":{"x":-31.946051078575692,"y":93.0,"z":29.523387113769626,"yaw":-627.44653,"pitch":37.573395,"roll":0.0}}},{"realTimestamp":9908896,"value":{"position":{"x":-1.6053634059630886,"y":91.672484820985,"z":-10.594536888795163,"yaw":-1151.6353,"pitch":16.142092,"roll":0.0}}},{"realTimestamp":9844750,"value":{"position":{"x":-31.946051078575692,"y":93.0,"z":29.523387113769626,"yaw":-627.44653,"pitch":37.573395,"roll":0.0}}},{"realTimestamp":9853735,"value":{"position":{"x":-31.05268144454021,"y":88.0,"z":-25.371850030366133,"yaw":-624.37897,"pitch":16.105839,"roll":0.0}}},{"realTimestamp":9845690,"value":{"position":{"x":-31.946051078575692,"y":93.0,"z":29.523387113769626,"yaw":-627.44653,"pitch":37.573395,"roll":0.0}}},{"realTimestamp":9938194,"value":{"position":{"x":39.88206777447001,"y":103.87657142499006,"z":58.09267383764874,"yaw":-1781.1023,"pitch":37.354122,"roll":0.0}}},{"realTimestamp":9846991,"value":{"position":{"x":-31.946051078575692,"y":93.0,"z":29.523387113769626,"yaw":-628.46875,"pitch":36.04,"roll":0.0}}},{"realTimestamp":9908638,"value":{"position":{"x":-1.5870303355717672,"y":91.672484820985,"z":-11.359450846926011,"yaw":-1142.6902,"pitch":20.997843,"roll":0.0}}},{"realTimestamp":9845490,"value":{"position":{"x":-31.946051078575692,"y":93.0,"z":29.523387113769626,"yaw":-627.44653,"pitch":37.573395,"roll":0.0}}},{"realTimestamp":9845990,"value":{"position":{"x":-31.946051078575692,"y":93.0,"z":29.523387113769626,"yaw":-627.44653,"pitch":37.573395,"roll":0.0}}}]
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d972b9b5f9d962199fe262eccef32a4b94504283fae97f9963702e7ab1550129
size 437123
+1
View File
@@ -0,0 +1 @@
{"singleplayer":false,"serverName":"protect-test-server.anygate.cloud","customServerName":"proxied test server","duration":3368,"date":1776531741320,"mcversion":"1.21.11","fileFormat":"MCPR","fileFormatVersion":14,"protocol":774,"generator":"ReplayMod v1.21.11-2.6.26","selfId":-1,"players":[]}
+1
View File
@@ -0,0 +1 @@
{"requiredMods":[{"modID":"viafabricplus","modName":"ViaFabricPlus","modVersion":"4.4.4"}]}
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cef58ec0e3d1d25e34c2effc5c09241ee4c1b39c085ed9e11b7097dfd5c2d033
size 3429878
@@ -0,0 +1 @@
234002168
+1
View File
@@ -0,0 +1 @@
{"singleplayer":false,"serverName":"protect-beta.anygate.cloud","customServerName":"protect-beta.anygate.cloud","duration":10198341,"date":1776535673280,"mcversion":"1.21.11","fileFormat":"MCPR","fileFormatVersion":14,"protocol":774,"generator":"ReplayMod v1.21.11-2.6.26","selfId":-1,"players":["fe2d6f64-7ab0-3373-a526-af097abbcb39"]}
+1
View File
@@ -0,0 +1 @@
{"requiredMods":[{"modID":"viafabricplus","modName":"ViaFabricPlus","modVersion":"4.4.4"}]}
+3
View File
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:be007aa681f7959708e89e39e05390e228753291823a18274068d310a50aa78b
size 526306397
+1
View File
@@ -0,0 +1 @@
270566013
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0da58f5cdd65ef241df8c61f9e633af7317faa77034183d4fb648b039c1e14ed
size 842
+1
View File
@@ -0,0 +1 @@
{"singleplayer":false,"serverName":"protect-test-server.anygate.cloud","customServerName":"proxied test server","duration":476,"date":1776803431635,"mcversion":"1.21.11","fileFormat":"MCPR","fileFormatVersion":14,"protocol":774,"generator":"ReplayMod v1.21.11-2.6.26","selfId":-1,"players":[]}
+1
View File
@@ -0,0 +1 @@
{"requiredMods":[{"modID":"viafabricplus","modName":"ViaFabricPlus","modVersion":"4.4.4"}]}
+3
View File
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:52fa049f97918289e018fa4c3bf5ff789d4f99f44f590ad875ce1f65e5fa9563
size 37
@@ -0,0 +1 @@
1105715802
+98
View File
@@ -0,0 +1,98 @@
package status
import (
"flag"
"fmt"
"log/slog"
"time"
"github.com/admin-else/strom/client"
"github.com/admin-else/strom/event"
"github.com/admin-else/strom/proto"
"github.com/admin-else/strom/proto_base"
"github.com/admin-else/strom/proto_generated/v1_21_8"
)
var cmd = flag.NewFlagSet("status", flag.ContinueOnError)
var addrFlag = cmd.String("addr", "localhost:25565", "address to connect to")
var srvFlag = cmd.Bool("srv", false, "use SRV records to resolve the address")
var versionFlag = cmd.String("version", "1.21.8", "version to use")
type StatusClient struct {
*proto.Conn
Status string
PingSendTime, PingReceiveTime time.Time
DoPingRoundTripTime bool
}
func (s *StatusClient) OnStatus(p *v1_21_8.StatusToClientPacketServerInfo) (err error) {
s.Status = p.Response
s.PingSendTime = time.Now()
if s.DoPingRoundTripTime {
err = s.Send(&v1_21_8.StatusToServerPacketPing{Time: s.PingSendTime.UnixMilli()})
} else {
err = event.HandlerDoneErr{}
}
return
}
func (s *StatusClient) OnPong(p *v1_21_8.StatusToClientPacketPing) (err error) {
s.PingReceiveTime = time.Now()
err = event.HandlerDoneErr{}
return
}
// StatusRaw returns a StatusClient that is not connected to a server.
// So ignore the resource leak warning. And maybe attach a warn ignore comment.
// It does not resolve SRV records.
func StatusRaw(addr string) (s *StatusClient, err error) {
c, err := client.ConnectVersionLess(addr)
if err != nil {
return
}
defer c.Close()
err = c.SetVersion(*versionFlag)
if err != nil {
return
}
s = &StatusClient{
Conn: c,
}
s.RegisterCriticalUntilLatest(s.OnStatus)
s.RegisterCriticalUntilLatest(s.OnPong)
p, err := client.MakeHandshakePacketAddr(s.Conn, proto_base.Status, addr)
if err != nil {
return
}
err = s.Send(p)
if err != nil {
return
}
s.SetState(proto_base.Status)
err = s.Send(&v1_21_8.StatusToServerPacketPingStart{})
err = s.StartConn()
return
}
func Run(args []string) (err error) {
err = cmd.Parse(args)
if err != nil {
return
}
if *srvFlag {
*addrFlag, err = client.DoDnsSimple(*addrFlag)
if err != nil {
return
}
}
slog.Debug("resolved address to ", "addr", *addrFlag)
status, err := StatusRaw(*addrFlag)
if err != nil {
return
}
fmt.Println(status.Status)
return
}
+4
View File
@@ -28,6 +28,7 @@ package crypto
import ( import (
"crypto/cipher" "crypto/cipher"
"crypto/subtle" "crypto/subtle"
"sync"
"unsafe" "unsafe"
) )
@@ -37,6 +38,7 @@ type CFB8 struct {
ivPos int ivPos int
iv []byte iv []byte
de bool de bool
mutex sync.Mutex
} }
func NewCFB8Decrypt(c cipher.Block, iv []byte) *CFB8 { func NewCFB8Decrypt(c cipher.Block, iv []byte) *CFB8 {
@@ -59,6 +61,8 @@ func newCFB8(c cipher.Block, iv []byte, de bool) *CFB8 {
} }
func (cf *CFB8) XORKeyStream(dst, src []byte) { func (cf *CFB8) XORKeyStream(dst, src []byte) {
cf.mutex.Lock()
defer cf.mutex.Unlock()
if len(src) == 0 { if len(src) == 0 {
return return
} }
+21 -6
View File
@@ -1,5 +1,7 @@
package data package data
import "errors"
// [ // [
// //
// { // {
@@ -14,7 +16,7 @@ package data
// }, // },
type Biome struct { type Biome struct {
Id int Id int32
Name string Name string
Category string Category string
Temperature float64 Temperature float64
@@ -24,22 +26,35 @@ type Biome struct {
Color int Color int
} }
var BiomesCache = make(map[string][]Biome) var BiomesCache = make(map[string][]*Biome)
func BiomesForVersion(v string) (ret []Biome) { func BiomesForVersion(v string) (ret []*Biome) {
var ok bool var ok bool
if ret, ok = BiomesCache[v]; ok { if ret, ok = BiomesCache[v]; ok {
return return
} }
var b []Biome var b []*Biome
must(LoadVersionedJson(v, "biomes", &b)) must(LoadVersionedJson(v, "biomes", &b))
BiomesCache[v] = b BiomesCache[v] = b
return b return b
} }
func LookupBiomeById(version string, id int32) (biome Biome, ok bool) { func LookupBiomeById(version string, id int32) (biome *Biome, ok bool) {
for _, b := range BiomesForVersion(version) { for _, b := range BiomesForVersion(version) {
if b.Id == int(id) { if b.Id == id {
biome = b
ok = true
return
}
}
return
}
var UnknownBiomeNameErr = errors.New("unknown biome Name")
func LookupBiomeByName(version string, name string) (biome *Biome, ok bool) {
for _, b := range BiomesForVersion(version) {
if b.Name == name {
biome = b biome = b
ok = true ok = true
return return
+171 -13
View File
@@ -1,6 +1,14 @@
package data package data
// { import (
"errors"
"slices"
"strconv"
"github.com/admin-else/strom/util"
)
// {
// "id": 0, // "id": 0,
// "name": "air", // "name": "air",
// "displayName": "Air", // "displayName": "Air",
@@ -35,34 +43,184 @@ type Block struct {
DefaultState int32 DefaultState int32
MinStateId int32 MinStateId int32
MaxStateId int32 MaxStateId int32
States []struct { States []BlockState
Name string Drops []int
Type string BoundingBox string
NumValues int
}
Drops []int
BoundingBox string
} }
var BlocksCache = make(map[string][]Block) type BlockState struct {
Name string
Type string
MinValue int32 // this is generated on load and used for state value calculations
NumValues int32 `json:"num_values"`
Values []string
}
func BlocksForVersion(v string) (ret []Block) { var BlocksCache = make(map[string][]*Block)
var BlocksCacheIdMap = make(map[string]map[int32]*Block)
func BlocksForVersion(v string) (ret []*Block) {
var ok bool var ok bool
if ret, ok = BlocksCache[v]; ok { if ret, ok = BlocksCache[v]; ok {
return return
} }
var b []Block var b []*Block
must(LoadVersionedJson(v, "blocks", &b)) must(LoadVersionedJson(v, "blocks", &b))
BlocksCache[v] = b BlocksCache[v] = b
for _, block := range b {
for i, state := range block.States {
if state.Type != "int" {
continue
}
values := make([]int32, state.NumValues)
for j, stateValue := range state.Values {
n := util.MustT(strconv.Atoi(stateValue))
values[j] = int32(n)
}
block.States[i].MinValue = slices.Min(values)
}
}
return b return b
} }
func LookupBlockByStateId(version string, stateId int32) (block Block, ok bool) { func LookupBlockByStateId(version string, stateId int32) (block *Block, ok bool) {
idmap, found := BlocksCacheIdMap[version]
if !found {
idmap = make(map[int32]*Block)
for _, b := range BlocksForVersion(version) {
for i := range b.MaxStateId - b.MinStateId + 1 {
idmap[b.MinStateId+i] = b
}
}
BlocksCacheIdMap[version] = idmap
}
block, ok = idmap[stateId]
return
}
var UnknownBlockNameErr = errors.New("unknown block Name")
func LookupBlockByName(version string, name string) (block *Block, ok bool) {
for _, b := range BlocksForVersion(version) { for _, b := range BlocksForVersion(version) {
if b.MinStateId <= stateId && stateId <= b.MaxStateId { if b.Name == name {
block = b block = b
ok = true ok = true
} }
} }
return return
} }
func StateIdFromBlocKAndStateMap(version string, name string, stateMap map[string]string) (stateId int32, err error) {
b, ok := LookupBlockByName(version, name)
if !ok {
err = BlockNotFoundErr
return
}
if stateMap == nil {
stateId = b.DefaultState
} else {
stateId, err = b.IdFromStateMap(stateMap)
}
if b.MinStateId > stateId || b.MaxStateId < stateId {
err = BlockStateOutOfRangeErr
}
return
}
var BlockStateOutOfRangeErr = errors.New("stateId out of range")
var BlockNotFoundErr = errors.New("block not found")
var InvalidBoolValueErr = errors.New("invalid bool value")
var BadBlockStateTypeErr = errors.New("bad block state type")
var BadEnumErr = errors.New("bad enum")
var SupplyAllStatesErr = errors.New("supply all states")
func FromBlockState(version string, stateId int32) (b *Block, stateData map[string]string, err error) {
b, ok := LookupBlockByStateId(version, stateId)
if !ok {
err = BlockNotFoundErr
}
stateData, err = b.StateMapFromId(stateId)
return
}
func mcDataBlockStateTypeParse(n int32, s *BlockState) (v string, err error) {
switch s.Type {
case "int":
v = strconv.Itoa(int(n))
case "enum":
v = s.Values[n]
case "bool":
if n == 0 { // MOJANK: 0 is true, 1 is false
v = "true"
} else if n == 1 {
v = "false"
} else {
err = InvalidBoolValueErr
}
default:
err = BadBlockStateTypeErr
}
return
}
func mcDataBlockStateTypeSerialize(v string, s *BlockState) (n int32, err error) {
if v == "true" {
return 0, nil
}
if v == "false" {
return 1, nil
}
n1, errMabye := strconv.Atoi(v)
if errMabye == nil {
return int32(n1) - s.MinValue, nil
}
for i, enumValue := range s.Values {
if enumValue == v {
return int32(i), nil
}
}
err = BadEnumErr
return
}
func (b *Block) StateMapFromId(stateId int32) (ret map[string]string, err error) {
if stateId < b.MinStateId || stateId > b.MaxStateId {
err = BlockStateOutOfRangeErr
return
}
ret = make(map[string]string)
stateId -= b.MinStateId
a := int32(1)
for i := range len(b.States) {
s := b.States[len(b.States)-1-i]
ret[s.Name], err = mcDataBlockStateTypeParse((stateId/a)%s.NumValues, &s)
if err != nil {
return
}
a *= s.NumValues
}
return
}
func (b *Block) IdFromStateMap(m map[string]string) (ret int32, err error) {
a := int32(1)
for i := range len(b.States) {
s := b.States[len(b.States)-1-i]
v, found := m[s.Name]
if !found {
err = SupplyAllStatesErr
return
}
var n int32
n, err = mcDataBlockStateTypeSerialize(v, &s)
if err != nil {
return
}
ret += n * a
a *= s.NumValues
}
ret += b.MinStateId
return
}
+26
View File
@@ -14,3 +14,29 @@ func TestLookupBlockByStateId(t *testing.T) {
} }
fmt.Println(b) fmt.Println(b)
} }
func TestBlockStates(t *testing.T) {
var stateId int32 = 8301
b, stateMap, err := data.FromBlockState("1.21.8", stateId)
if err != nil {
t.Fatal(err)
return
}
t.Logf("Block state map: %v, block: %v", stateMap, b.Name)
stateId2, err := b.IdFromStateMap(stateMap)
if err != nil {
t.Fatal(err)
return
}
if stateId2 != stateId {
t.Fatal("state id mismatch")
}
}
func TestBlockStateOutOfRangeBug(t *testing.T) {
id, err := data.StateIdFromBlocKAndStateMap("1.21.11", "wildflowers", map[string]string{"facing": "east", "flower_amount": "4"})
if err != nil {
t.Fatal(err)
}
t.Logf("State id: %d", id)
}
+7 -3
View File
@@ -4,9 +4,12 @@ import (
"embed" "embed"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
) )
//go:embed minecraft-data/data //go:generate ./download_minecraft_data.sh
//go:embed minecraft-data/pc minecraft-data/dataPaths.json
var MinecraftData embed.FS var MinecraftData embed.FS
func LoadJson(path string, data any) (err error) { func LoadJson(path string, data any) (err error) {
@@ -19,9 +22,10 @@ func LoadJson(path string, data any) (err error) {
} }
func LoadVersionedJson(version, dataName string, data any) (err error) { func LoadVersionedJson(version, dataName string, data any) (err error) {
b, err := MinecraftData.ReadFile("minecraft-data/data/" + Paths.Data[version][dataName] + "/" + dataName + ".json") b, err := MinecraftData.ReadFile("minecraft-data/" + Paths.Data[version][dataName] + "/" + dataName + ".json")
if err != nil { if err != nil {
return // If you get this error, you need to probably need to update the download script
return fmt.Errorf("minecraft-data/%s/%s/%s.json: %w", version, Paths.Data[version][dataName], dataName, err)
} }
err = json.Unmarshal(b, data) err = json.Unmarshal(b, data)
return return
+1 -1
View File
@@ -9,5 +9,5 @@ var Paths struct {
} }
func init() { func init() {
must(LoadJson("minecraft-data/data/dataPaths.json", &Paths)) must(LoadJson("minecraft-data/dataPaths.json", &Paths))
} }
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/sh
set -xeuo pipefail
# Go get / install does not clone git submodules so we have to do it like this
rm -rf minecraft-data/
git clone --depth 1 git@github.com:PrismarineJS/minecraft-data.git
mv minecraft-data minecraft-data-untrimmed
mkdir minecraft-data
mkdir minecraft-data/pc
mv minecraft-data-untrimmed/data/dataPaths.json minecraft-data
copy-mc() {
mv minecraft-data-untrimmed/data/pc/$1 minecraft-data/pc
}
copy-mc common
copy-mc 1.21.8
copy-mc 1.21.9
copy-mc 1.21.11
rm -rf minecraft-data-untrimmed
+57
View File
@@ -0,0 +1,57 @@
package data
import "sync"
// {
// "id": 2,
// "name": "granite",
// "displayName": "Granite",
// "stackSize": 64
// },
type Item struct {
Id int32
Name string
DisplayName string
StackSize int32
}
var ItemsCache = make(map[string][]*Item)
var ItemsCacheMutex = &sync.RWMutex{}
func ItemsForVersion(v string) (ret []*Item) {
var ok bool
ItemsCacheMutex.RLock()
if ret, ok = ItemsCache[v]; ok {
ItemsCacheMutex.RUnlock()
return
}
ItemsCacheMutex.RUnlock()
var b []*Item
must(LoadVersionedJson(v, "items", &b))
ItemsCacheMutex.Lock()
ItemsCache[v] = b
ItemsCacheMutex.Unlock()
return b
}
func LookupItemById(version string, id int32) (item *Item, ok bool) {
for _, i := range ItemsForVersion(version) {
if i.Id == id {
item = i
ok = true
return
}
}
return
}
func LookupItemByName(version string, name string) (item *Item, ok bool) {
for _, i := range ItemsForVersion(version) {
if i.Name == name {
item = i
ok = true
}
}
return
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,247 @@
[
{
"name": "armor",
"resource": "minecraft:armor",
"min": 0.0,
"max": 30.0,
"default": 0.0
},
{
"name": "armorToughness",
"resource": "minecraft:armor_toughness",
"min": 0.0,
"max": 20.0,
"default": 0.0
},
{
"name": "attackDamage",
"resource": "minecraft:attack_damage",
"min": 0.0,
"max": 2048.0,
"default": 2.0
},
{
"name": "attackKnockback",
"resource": "minecraft:attack_knockback",
"min": 0.0,
"max": 5.0,
"default": 0.0
},
{
"name": "attackSpeed",
"resource": "minecraft:attack_speed",
"min": 0.0,
"max": 1024.0,
"default": 4.0
},
{
"name": "blockBreakSpeed",
"resource": "minecraft:block_break_speed",
"min": 0.0,
"max": 1024.0,
"default": 1.0
},
{
"name": "blockInteractionRange",
"resource": "minecraft:block_interaction_range",
"min": 0.0,
"max": 64.0,
"default": 4.5
},
{
"name": "burningTime",
"resource": "minecraft:burning_time",
"min": 0.0,
"max": 1024.0,
"default": 1.0
},
{
"name": "cameraDistance",
"resource": "minecraft:camera_distance",
"min": 0.0,
"max": 32.0,
"default": 4.0
},
{
"name": "explosionKnockbackResistance",
"resource": "minecraft:explosion_knockback_resistance",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "entityInteractionRange",
"resource": "minecraft:entity_interaction_range",
"min": 0.0,
"max": 64.0,
"default": 3.0
},
{
"name": "fallDamageMultiplier",
"resource": "minecraft:fall_damage_multiplier",
"min": 0.0,
"max": 100.0,
"default": 1.0
},
{
"name": "flyingSpeed",
"resource": "minecraft:flying_speed",
"min": 0.0,
"max": 1024.0,
"default": 0.4
},
{
"name": "followRange",
"resource": "minecraft:follow_range",
"min": 0.0,
"max": 2048.0,
"default": 32.0
},
{
"name": "gravity",
"resource": "minecraft:gravity",
"min": -1.0,
"max": 1.0,
"default": 0.08
},
{
"name": "jumpStrength",
"resource": "minecraft:jump_strength",
"min": 0.0,
"max": 32.0,
"default": 0.41999998688697815
},
{
"name": "knockbackResistance",
"resource": "minecraft:knockback_resistance",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "luck",
"resource": "minecraft:luck",
"min": -1024.0,
"max": 1024.0,
"default": 0.0
},
{
"name": "maxAbsorption",
"resource": "minecraft:max_absorption",
"min": 0.0,
"max": 2048.0,
"default": 0.0
},
{
"name": "maxHealth",
"resource": "minecraft:max_health",
"min": 1.0,
"max": 1024.0,
"default": 20.0
},
{
"name": "miningEfficiency",
"resource": "minecraft:mining_efficiency",
"min": 0.0,
"max": 1024.0,
"default": 0.0
},
{
"name": "movementEfficiency",
"resource": "minecraft:movement_efficiency",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "movementSpeed",
"resource": "minecraft:movement_speed",
"min": 0.0,
"max": 1024.0,
"default": 0.7
},
{
"name": "oxygenBonus",
"resource": "minecraft:oxygen_bonus",
"min": 0.0,
"max": 1024.0,
"default": 0.0
},
{
"name": "safeFallDistance",
"resource": "minecraft:safe_fall_distance",
"min": -1024.0,
"max": 1024.0,
"default": 3.0
},
{
"name": "scale",
"resource": "minecraft:scale",
"min": 0.0625,
"max": 16.0,
"default": 1.0
},
{
"name": "sneakingSpeed",
"resource": "minecraft:sneaking_speed",
"min": 0.0,
"max": 1.0,
"default": 0.3
},
{
"name": "spawnReinforcements",
"resource": "minecraft:spawn_reinforcements",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "stepHeight",
"resource": "minecraft:step_height",
"min": 0.0,
"max": 10.0,
"default": 0.6
},
{
"name": "submergedMiningSpeed",
"resource": "minecraft:submerged_mining_speed",
"min": 0.0,
"max": 20.0,
"default": 0.2
},
{
"name": "sweepingDamageRatio",
"resource": "minecraft:sweeping_damage_ratio",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "temptRange",
"resource": "minecraft:tempt_range",
"min": 0.0,
"max": 2048.0,
"default": 10.0
},
{
"name": "waterMovementEfficiency",
"resource": "minecraft:water_movement_efficiency",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "waypointTransmitRange",
"resource": "minecraft:waypoint_transmit_range",
"min": 0.0,
"max": 6.0E7,
"default": 0.0
},
{
"name": "waypointReceiveRange",
"resource": "minecraft:waypoint_receive_range",
"min": 0.0,
"max": 6.0E7,
"default": 0.0
}
]
+652
View File
@@ -0,0 +1,652 @@
[
{
"id": 0,
"name": "badlands",
"category": "mesa",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Badlands",
"color": 7254527
},
{
"id": 1,
"name": "bamboo_jungle",
"category": "jungle",
"temperature": 0.95,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Bamboo Jungle",
"color": 7842047
},
{
"id": 2,
"name": "basalt_deltas",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Basalt Deltas",
"color": 0
},
{
"id": 3,
"name": "beach",
"category": "beach",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Beach",
"color": 7907327
},
{
"id": 4,
"name": "birch_forest",
"category": "forest",
"temperature": 0.6,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Birch Forest",
"color": 8037887
},
{
"id": 5,
"name": "cherry_grove",
"category": "forest",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Cherry Grove",
"color": 8103167
},
{
"id": 6,
"name": "cold_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Cold Ocean",
"color": 8103167
},
{
"id": 7,
"name": "crimson_forest",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Crimson Forest",
"color": 0
},
{
"id": 8,
"name": "dark_forest",
"category": "forest",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Dark Forest",
"color": 7972607
},
{
"id": 9,
"name": "deep_cold_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Cold Ocean",
"color": 8103167
},
{
"id": 10,
"name": "deep_dark",
"category": "underground",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Dark",
"color": 7907327
},
{
"id": 11,
"name": "deep_frozen_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Frozen Ocean",
"color": 8103167
},
{
"id": 12,
"name": "deep_lukewarm_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Lukewarm Ocean",
"color": 8103167
},
{
"id": 13,
"name": "deep_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Ocean",
"color": 8103167
},
{
"id": 14,
"name": "desert",
"category": "desert",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Desert",
"color": 7254527
},
{
"id": 15,
"name": "dripstone_caves",
"category": "underground",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Dripstone Caves",
"color": 7907327
},
{
"id": 16,
"name": "end_barrens",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "End Barrens",
"color": 0
},
{
"id": 17,
"name": "end_highlands",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "End Highlands",
"color": 0
},
{
"id": 18,
"name": "end_midlands",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "End Midlands",
"color": 0
},
{
"id": 19,
"name": "eroded_badlands",
"category": "mesa",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Eroded Badlands",
"color": 7254527
},
{
"id": 20,
"name": "flower_forest",
"category": "forest",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Flower Forest",
"color": 7972607
},
{
"id": 21,
"name": "forest",
"category": "forest",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Forest",
"color": 7972607
},
{
"id": 22,
"name": "frozen_ocean",
"category": "ocean",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Frozen Ocean",
"color": 8364543
},
{
"id": 23,
"name": "frozen_peaks",
"category": "ice",
"temperature": -0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Frozen Peaks",
"color": 8756735
},
{
"id": 24,
"name": "frozen_river",
"category": "ice",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Frozen River",
"color": 8364543
},
{
"id": 25,
"name": "grove",
"category": "forest",
"temperature": -0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Grove",
"color": 8495359
},
{
"id": 26,
"name": "ice_spikes",
"category": "ice",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Ice Spikes",
"color": 8364543
},
{
"id": 27,
"name": "jagged_peaks",
"category": "mountain",
"temperature": -0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Jagged Peaks",
"color": 8756735
},
{
"id": 28,
"name": "jungle",
"category": "jungle",
"temperature": 0.95,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Jungle",
"color": 7842047
},
{
"id": 29,
"name": "lukewarm_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Lukewarm Ocean",
"color": 8103167
},
{
"id": 30,
"name": "lush_caves",
"category": "underground",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Lush Caves",
"color": 8103167
},
{
"id": 31,
"name": "mangrove_swamp",
"category": "forest",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Mangrove Swamp",
"color": 7907327
},
{
"id": 32,
"name": "meadow",
"category": "mountain",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Meadow",
"color": 8103167
},
{
"id": 33,
"name": "mushroom_fields",
"category": "mushroom",
"temperature": 0.9,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Mushroom Fields",
"color": 7842047
},
{
"id": 34,
"name": "nether_wastes",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Nether Wastes",
"color": 0
},
{
"id": 35,
"name": "ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Ocean",
"color": 8103167
},
{
"id": 36,
"name": "old_growth_birch_forest",
"category": "forest",
"temperature": 0.6,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Old Growth Birch Forest",
"color": 8037887
},
{
"id": 37,
"name": "old_growth_pine_taiga",
"category": "taiga",
"temperature": 0.3,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Old Growth Pine Taiga",
"color": 8168447
},
{
"id": 38,
"name": "old_growth_spruce_taiga",
"category": "taiga",
"temperature": 0.25,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Old Growth Spruce Taiga",
"color": 8233983
},
{
"id": 39,
"name": "pale_garden",
"category": "none",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Pale Garden",
"color": 12171705
},
{
"id": 40,
"name": "plains",
"category": "plains",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Plains",
"color": 7907327
},
{
"id": 41,
"name": "river",
"category": "river",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "River",
"color": 8103167
},
{
"id": 42,
"name": "savanna",
"category": "savanna",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Savanna",
"color": 7254527
},
{
"id": 43,
"name": "savanna_plateau",
"category": "savanna",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Savanna Plateau",
"color": 7254527
},
{
"id": 44,
"name": "small_end_islands",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "Small End Islands",
"color": 0
},
{
"id": 45,
"name": "snowy_beach",
"category": "beach",
"temperature": 0.05,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Beach",
"color": 8364543
},
{
"id": 46,
"name": "snowy_plains",
"category": "plains",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Plains",
"color": 8364543
},
{
"id": 47,
"name": "snowy_slopes",
"category": "mountain",
"temperature": -0.3,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Slopes",
"color": 8560639
},
{
"id": 48,
"name": "snowy_taiga",
"category": "taiga",
"temperature": -0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Taiga",
"color": 8625919
},
{
"id": 49,
"name": "soul_sand_valley",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Soul Sand Valley",
"color": 0
},
{
"id": 50,
"name": "sparse_jungle",
"category": "jungle",
"temperature": 0.95,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Sparse Jungle",
"color": 7842047
},
{
"id": 51,
"name": "stony_peaks",
"category": "mountain",
"temperature": 1.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Stony Peaks",
"color": 7776511
},
{
"id": 52,
"name": "stony_shore",
"category": "beach",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Stony Shore",
"color": 8233727
},
{
"id": 53,
"name": "sunflower_plains",
"category": "plains",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Sunflower Plains",
"color": 7907327
},
{
"id": 54,
"name": "swamp",
"category": "swamp",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Swamp",
"color": 7907327
},
{
"id": 55,
"name": "taiga",
"category": "taiga",
"temperature": 0.25,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Taiga",
"color": 8233983
},
{
"id": 56,
"name": "the_end",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "The End",
"color": 0
},
{
"id": 57,
"name": "the_void",
"category": "none",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "The Void",
"color": 8103167
},
{
"id": 58,
"name": "warm_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Warm Ocean",
"color": 8103167
},
{
"id": 59,
"name": "warped_forest",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Warped Forest",
"color": 0
},
{
"id": 60,
"name": "windswept_forest",
"category": "forest",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Windswept Forest",
"color": 8233727
},
{
"id": 61,
"name": "windswept_gravelly_hills",
"category": "extreme_hills",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Windswept Gravelly Hills",
"color": 8233727
},
{
"id": 62,
"name": "windswept_hills",
"category": "extreme_hills",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Windswept Hills",
"color": 8233727
},
{
"id": 63,
"name": "windswept_savanna",
"category": "savanna",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Windswept Savanna",
"color": 7254527
},
{
"id": 64,
"name": "wooded_badlands",
"category": "mesa",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Wooded Badlands",
"color": 7254527
}
]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+242
View File
@@ -0,0 +1,242 @@
[
{
"id": 0,
"name": "Speed",
"displayName": "Speed",
"type": "good"
},
{
"id": 1,
"name": "Slowness",
"displayName": "Slowness",
"type": "bad"
},
{
"id": 2,
"name": "Haste",
"displayName": "Haste",
"type": "good"
},
{
"id": 3,
"name": "MiningFatigue",
"displayName": "Mining Fatigue",
"type": "bad"
},
{
"id": 4,
"name": "Strength",
"displayName": "Strength",
"type": "good"
},
{
"id": 5,
"name": "InstantHealth",
"displayName": "Instant Health",
"type": "good"
},
{
"id": 6,
"name": "InstantDamage",
"displayName": "Instant Damage",
"type": "bad"
},
{
"id": 7,
"name": "JumpBoost",
"displayName": "Jump Boost",
"type": "good"
},
{
"id": 8,
"name": "Nausea",
"displayName": "Nausea",
"type": "bad"
},
{
"id": 9,
"name": "Regeneration",
"displayName": "Regeneration",
"type": "good"
},
{
"id": 10,
"name": "Resistance",
"displayName": "Resistance",
"type": "good"
},
{
"id": 11,
"name": "FireResistance",
"displayName": "Fire Resistance",
"type": "good"
},
{
"id": 12,
"name": "WaterBreathing",
"displayName": "Water Breathing",
"type": "good"
},
{
"id": 13,
"name": "Invisibility",
"displayName": "Invisibility",
"type": "good"
},
{
"id": 14,
"name": "Blindness",
"displayName": "Blindness",
"type": "bad"
},
{
"id": 15,
"name": "NightVision",
"displayName": "Night Vision",
"type": "good"
},
{
"id": 16,
"name": "Hunger",
"displayName": "Hunger",
"type": "bad"
},
{
"id": 17,
"name": "Weakness",
"displayName": "Weakness",
"type": "bad"
},
{
"id": 18,
"name": "Poison",
"displayName": "Poison",
"type": "bad"
},
{
"id": 19,
"name": "Wither",
"displayName": "Wither",
"type": "bad"
},
{
"id": 20,
"name": "HealthBoost",
"displayName": "Health Boost",
"type": "good"
},
{
"id": 21,
"name": "Absorption",
"displayName": "Absorption",
"type": "good"
},
{
"id": 22,
"name": "Saturation",
"displayName": "Saturation",
"type": "good"
},
{
"id": 23,
"name": "Glowing",
"displayName": "Glowing",
"type": "bad"
},
{
"id": 24,
"name": "Levitation",
"displayName": "Levitation",
"type": "bad"
},
{
"id": 25,
"name": "Luck",
"displayName": "Luck",
"type": "good"
},
{
"id": 26,
"name": "BadLuck",
"displayName": "Bad Luck",
"type": "bad"
},
{
"id": 27,
"name": "SlowFalling",
"displayName": "Slow Falling",
"type": "good"
},
{
"id": 28,
"name": "ConduitPower",
"displayName": "Conduit Power",
"type": "good"
},
{
"id": 29,
"name": "DolphinsGrace",
"displayName": "Dolphin's Grace",
"type": "good"
},
{
"id": 30,
"name": "BadOmen",
"displayName": "Bad Omen",
"type": "bad"
},
{
"id": 31,
"name": "HeroOfTheVillage",
"displayName": "Hero of the Village",
"type": "good"
},
{
"id": 32,
"name": "Darkness",
"displayName": "Darkness",
"type": "bad"
},
{
"id": 33,
"name": "TrialOmen",
"displayName": "Trial Omen",
"type": "bad"
},
{
"id": 34,
"name": "RaidOmen",
"displayName": "Raid Omen",
"type": "bad"
},
{
"id": 35,
"name": "WindCharged",
"displayName": "Wind Charged",
"type": "bad"
},
{
"id": 36,
"name": "Weaving",
"displayName": "Weaving",
"type": "bad"
},
{
"id": 37,
"name": "Oozing",
"displayName": "Oozing",
"type": "bad"
},
{
"id": 38,
"name": "Infested",
"displayName": "Infested",
"type": "bad"
},
{
"id": 39,
"name": "BreathOfTheNautilus",
"displayName": "Breath of the Nautilus",
"type": "good"
}
]
@@ -0,0 +1,980 @@
[
{
"id": 0,
"name": "aqua_affinity",
"displayName": "Aqua Affinity",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "head_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 1,
"name": "bane_of_arthropods",
"displayName": "Bane of Arthropods",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"breach",
"density",
"impaling",
"sharpness",
"smite"
],
"category": "weapon",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 2,
"name": "binding_curse",
"displayName": "Curse of Binding",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": true,
"curse": true,
"exclude": [],
"category": "equippable",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 3,
"name": "blast_protection",
"displayName": "Blast Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"fire_protection",
"projectile_protection",
"protection"
],
"category": "armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 4,
"name": "breach",
"displayName": "Breach",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"density",
"impaling",
"sharpness",
"smite"
],
"category": "mace",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 5,
"name": "channeling",
"displayName": "Channeling",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"riptide"
],
"category": "trident",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 6,
"name": "density",
"displayName": "Density",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"impaling",
"sharpness",
"smite"
],
"category": "mace",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 7,
"name": "depth_strider",
"displayName": "Depth Strider",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"frost_walker"
],
"category": "foot_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 8,
"name": "efficiency",
"displayName": "Efficiency",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "mining",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 9,
"name": "feather_falling",
"displayName": "Feather Falling",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "foot_armor",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 10,
"name": "fire_aspect",
"displayName": "Fire Aspect",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "fire_aspect",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 11,
"name": "fire_protection",
"displayName": "Fire Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"blast_protection",
"projectile_protection",
"protection"
],
"category": "armor",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 12,
"name": "flame",
"displayName": "Flame",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "bow",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 13,
"name": "fortune",
"displayName": "Fortune",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"silk_touch"
],
"category": "mining_loot",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 14,
"name": "frost_walker",
"displayName": "Frost Walker",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [
"depth_strider"
],
"category": "foot_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 15,
"name": "impaling",
"displayName": "Impaling",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"density",
"sharpness",
"smite"
],
"category": "trident",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 16,
"name": "infinity",
"displayName": "Infinity",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"mending"
],
"category": "bow",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 17,
"name": "knockback",
"displayName": "Knockback",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "melee_weapon",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 18,
"name": "looting",
"displayName": "Looting",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "melee_weapon",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 19,
"name": "loyalty",
"displayName": "Loyalty",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"riptide"
],
"category": "trident",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 20,
"name": "luck_of_the_sea",
"displayName": "Luck of the Sea",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "fishing",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 21,
"name": "lunge",
"displayName": "Lunge",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "lunge",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 22,
"name": "lure",
"displayName": "Lure",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "fishing",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 23,
"name": "mending",
"displayName": "Mending",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [
"infinity"
],
"category": "durability",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 24,
"name": "multishot",
"displayName": "Multishot",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"piercing"
],
"category": "crossbow",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 25,
"name": "piercing",
"displayName": "Piercing",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"multishot"
],
"category": "crossbow",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 26,
"name": "power",
"displayName": "Power",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "bow",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 27,
"name": "projectile_protection",
"displayName": "Projectile Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"blast_protection",
"fire_protection",
"protection"
],
"category": "armor",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 28,
"name": "protection",
"displayName": "Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"blast_protection",
"fire_protection",
"projectile_protection"
],
"category": "armor",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 29,
"name": "punch",
"displayName": "Punch",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "bow",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 30,
"name": "quick_charge",
"displayName": "Quick Charge",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "crossbow",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 31,
"name": "respiration",
"displayName": "Respiration",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "head_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 32,
"name": "riptide",
"displayName": "Riptide",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"channeling",
"loyalty"
],
"category": "trident",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 33,
"name": "sharpness",
"displayName": "Sharpness",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"density",
"impaling",
"smite"
],
"category": "sharp_weapon",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 34,
"name": "silk_touch",
"displayName": "Silk Touch",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"fortune"
],
"category": "mining_loot",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 35,
"name": "smite",
"displayName": "Smite",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"density",
"impaling",
"sharpness"
],
"category": "weapon",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 36,
"name": "soul_speed",
"displayName": "Soul Speed",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [],
"category": "foot_armor",
"weight": 1,
"tradeable": false,
"discoverable": false
},
{
"id": 37,
"name": "sweeping_edge",
"displayName": "Sweeping Edge",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "sweeping",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 38,
"name": "swift_sneak",
"displayName": "Swift Sneak",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [],
"category": "leg_armor",
"weight": 1,
"tradeable": false,
"discoverable": false
},
{
"id": 39,
"name": "thorns",
"displayName": "Thorns",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "armor",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 40,
"name": "unbreaking",
"displayName": "Unbreaking",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "durability",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 41,
"name": "vanishing_curse",
"displayName": "Curse of Vanishing",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": true,
"curse": true,
"exclude": [],
"category": "vanishing",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 42,
"name": "wind_burst",
"displayName": "Wind Burst",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [],
"category": "mace",
"weight": 2,
"tradeable": false,
"discoverable": false
}
]
File diff suppressed because it is too large Load Diff
+442
View File
@@ -0,0 +1,442 @@
[
{
"id": 893,
"name": "apple",
"stackSize": 64,
"displayName": "Apple",
"foodPoints": 4.0,
"saturation": 19.2,
"effectiveQuality": 23.2,
"saturationRatio": 4.8
},
{
"id": 947,
"name": "mushroom_stew",
"stackSize": 1,
"displayName": "Mushroom Stew",
"foodPoints": 6.0,
"saturation": 86.4,
"effectiveQuality": 92.4,
"saturationRatio": 14.400001
},
{
"id": 953,
"name": "bread",
"stackSize": 64,
"displayName": "Bread",
"foodPoints": 5.0,
"saturation": 60.0,
"effectiveQuality": 65.0,
"saturationRatio": 12.0
},
{
"id": 983,
"name": "porkchop",
"stackSize": 64,
"displayName": "Raw Porkchop",
"foodPoints": 3.0,
"saturation": 10.8,
"effectiveQuality": 13.8,
"saturationRatio": 3.6000001
},
{
"id": 984,
"name": "cooked_porkchop",
"stackSize": 64,
"displayName": "Cooked Porkchop",
"foodPoints": 8.0,
"saturation": 204.8,
"effectiveQuality": 212.8,
"saturationRatio": 25.6
},
{
"id": 986,
"name": "golden_apple",
"stackSize": 64,
"displayName": "Golden Apple",
"foodPoints": 4.0,
"saturation": 76.8,
"effectiveQuality": 80.8,
"saturationRatio": 19.2
},
{
"id": 987,
"name": "enchanted_golden_apple",
"stackSize": 64,
"displayName": "Enchanted Golden Apple",
"foodPoints": 4.0,
"saturation": 76.8,
"effectiveQuality": 80.8,
"saturationRatio": 19.2
},
{
"id": 1019,
"name": "pufferfish_bucket",
"stackSize": 1,
"displayName": "Bucket of Pufferfish",
"foodPoints": 1.0,
"saturation": 0.4,
"effectiveQuality": 1.4,
"saturationRatio": 0.4
},
{
"id": 1020,
"name": "salmon_bucket",
"stackSize": 1,
"displayName": "Bucket of Salmon",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1021,
"name": "cod_bucket",
"stackSize": 1,
"displayName": "Bucket of Cod",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1022,
"name": "tropical_fish_bucket",
"stackSize": 1,
"displayName": "Bucket of Tropical Fish",
"foodPoints": 1.0,
"saturation": 0.4,
"effectiveQuality": 1.4,
"saturationRatio": 0.4
},
{
"id": 1057,
"name": "cod",
"stackSize": 64,
"displayName": "Raw Cod",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1058,
"name": "salmon",
"stackSize": 64,
"displayName": "Raw Salmon",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1059,
"name": "tropical_fish",
"stackSize": 64,
"displayName": "Tropical Fish",
"foodPoints": 1.0,
"saturation": 0.4,
"effectiveQuality": 1.4,
"saturationRatio": 0.4
},
{
"id": 1060,
"name": "pufferfish",
"stackSize": 64,
"displayName": "Pufferfish",
"foodPoints": 1.0,
"saturation": 0.4,
"effectiveQuality": 1.4,
"saturationRatio": 0.4
},
{
"id": 1061,
"name": "cooked_cod",
"stackSize": 64,
"displayName": "Cooked Cod",
"foodPoints": 5.0,
"saturation": 60.0,
"effectiveQuality": 65.0,
"saturationRatio": 12.0
},
{
"id": 1062,
"name": "cooked_salmon",
"stackSize": 64,
"displayName": "Cooked Salmon",
"foodPoints": 6.0,
"saturation": 115.200005,
"effectiveQuality": 121.200005,
"saturationRatio": 19.2
},
{
"id": 1102,
"name": "cookie",
"stackSize": 64,
"displayName": "Cookie",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1106,
"name": "melon_slice",
"stackSize": 64,
"displayName": "Melon Slice",
"foodPoints": 2.0,
"saturation": 4.8,
"effectiveQuality": 6.8,
"saturationRatio": 2.4
},
{
"id": 1107,
"name": "dried_kelp",
"stackSize": 64,
"displayName": "Dried Kelp",
"foodPoints": 1.0,
"saturation": 1.2,
"effectiveQuality": 2.2,
"saturationRatio": 1.2
},
{
"id": 1110,
"name": "beef",
"stackSize": 64,
"displayName": "Raw Beef",
"foodPoints": 3.0,
"saturation": 10.8,
"effectiveQuality": 13.8,
"saturationRatio": 3.6000001
},
{
"id": 1111,
"name": "cooked_beef",
"stackSize": 64,
"displayName": "Steak",
"foodPoints": 8.0,
"saturation": 204.8,
"effectiveQuality": 212.8,
"saturationRatio": 25.6
},
{
"id": 1112,
"name": "chicken",
"stackSize": 64,
"displayName": "Raw Chicken",
"foodPoints": 2.0,
"saturation": 4.8,
"effectiveQuality": 6.8,
"saturationRatio": 2.4
},
{
"id": 1113,
"name": "cooked_chicken",
"stackSize": 64,
"displayName": "Cooked Chicken",
"foodPoints": 6.0,
"saturation": 86.4,
"effectiveQuality": 92.4,
"saturationRatio": 14.400001
},
{
"id": 1114,
"name": "rotten_flesh",
"stackSize": 64,
"displayName": "Rotten Flesh",
"foodPoints": 4.0,
"saturation": 6.4,
"effectiveQuality": 10.4,
"saturationRatio": 1.6
},
{
"id": 1122,
"name": "spider_eye",
"stackSize": 64,
"displayName": "Spider Eye",
"foodPoints": 2.0,
"saturation": 12.8,
"effectiveQuality": 14.8,
"saturationRatio": 6.4
},
{
"id": 1227,
"name": "carrot",
"stackSize": 64,
"displayName": "Carrot",
"foodPoints": 3.0,
"saturation": 21.6,
"effectiveQuality": 24.6,
"saturationRatio": 7.2000003
},
{
"id": 1228,
"name": "potato",
"stackSize": 64,
"displayName": "Potato",
"foodPoints": 1.0,
"saturation": 1.2,
"effectiveQuality": 2.2,
"saturationRatio": 1.2
},
{
"id": 1229,
"name": "baked_potato",
"stackSize": 64,
"displayName": "Baked Potato",
"foodPoints": 5.0,
"saturation": 60.0,
"effectiveQuality": 65.0,
"saturationRatio": 12.0
},
{
"id": 1230,
"name": "poisonous_potato",
"stackSize": 64,
"displayName": "Poisonous Potato",
"foodPoints": 2.0,
"saturation": 4.8,
"effectiveQuality": 6.8,
"saturationRatio": 2.4
},
{
"id": 1232,
"name": "golden_carrot",
"stackSize": 64,
"displayName": "Golden Carrot",
"foodPoints": 6.0,
"saturation": 172.8,
"effectiveQuality": 178.8,
"saturationRatio": 28.800001
},
{
"id": 1241,
"name": "pumpkin_pie",
"stackSize": 64,
"displayName": "Pumpkin Pie",
"foodPoints": 8.0,
"saturation": 76.8,
"effectiveQuality": 84.8,
"saturationRatio": 9.6
},
{
"id": 1249,
"name": "rabbit",
"stackSize": 64,
"displayName": "Raw Rabbit",
"foodPoints": 3.0,
"saturation": 10.8,
"effectiveQuality": 13.8,
"saturationRatio": 3.6000001
},
{
"id": 1250,
"name": "cooked_rabbit",
"stackSize": 64,
"displayName": "Cooked Rabbit",
"foodPoints": 5.0,
"saturation": 60.0,
"effectiveQuality": 65.0,
"saturationRatio": 12.0
},
{
"id": 1251,
"name": "rabbit_stew",
"stackSize": 1,
"displayName": "Rabbit Stew",
"foodPoints": 10.0,
"saturation": 240.0,
"effectiveQuality": 250.0,
"saturationRatio": 24.0
},
{
"id": 1264,
"name": "mutton",
"stackSize": 64,
"displayName": "Raw Mutton",
"foodPoints": 2.0,
"saturation": 4.8,
"effectiveQuality": 6.8,
"saturationRatio": 2.4
},
{
"id": 1265,
"name": "cooked_mutton",
"stackSize": 64,
"displayName": "Cooked Mutton",
"foodPoints": 6.0,
"saturation": 115.200005,
"effectiveQuality": 121.200005,
"saturationRatio": 19.2
},
{
"id": 1283,
"name": "chorus_fruit",
"stackSize": 64,
"displayName": "Chorus Fruit",
"foodPoints": 4.0,
"saturation": 19.2,
"effectiveQuality": 23.2,
"saturationRatio": 4.8
},
{
"id": 1287,
"name": "beetroot",
"stackSize": 64,
"displayName": "Beetroot",
"foodPoints": 1.0,
"saturation": 2.4,
"effectiveQuality": 3.4,
"saturationRatio": 2.4
},
{
"id": 1289,
"name": "beetroot_soup",
"stackSize": 1,
"displayName": "Beetroot Soup",
"foodPoints": 6.0,
"saturation": 86.4,
"effectiveQuality": 92.4,
"saturationRatio": 14.400001
},
{
"id": 1340,
"name": "suspicious_stew",
"stackSize": 1,
"displayName": "Suspicious Stew",
"foodPoints": 6.0,
"saturation": 86.4,
"effectiveQuality": 92.4,
"saturationRatio": 14.400001
},
{
"id": 1373,
"name": "sweet_berries",
"stackSize": 64,
"displayName": "Sweet Berries",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1374,
"name": "glow_berries",
"stackSize": 64,
"displayName": "Glow Berries",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1381,
"name": "honey_bottle",
"stackSize": 16,
"displayName": "Honey Bottle",
"foodPoints": 6.0,
"saturation": 14.400001,
"effectiveQuality": 20.400002,
"saturationRatio": 2.4
}
]
@@ -0,0 +1,94 @@
[
{
"id": 0,
"name": "harp"
},
{
"id": 1,
"name": "basedrum"
},
{
"id": 2,
"name": "snare"
},
{
"id": 3,
"name": "hat"
},
{
"id": 4,
"name": "bass"
},
{
"id": 5,
"name": "flute"
},
{
"id": 6,
"name": "bell"
},
{
"id": 7,
"name": "guitar"
},
{
"id": 8,
"name": "chime"
},
{
"id": 9,
"name": "xylophone"
},
{
"id": 10,
"name": "iron_xylophone"
},
{
"id": 11,
"name": "cow_bell"
},
{
"id": 12,
"name": "didgeridoo"
},
{
"id": 13,
"name": "bit"
},
{
"id": 14,
"name": "banjo"
},
{
"id": 15,
"name": "pling"
},
{
"id": 16,
"name": "zombie"
},
{
"id": 17,
"name": "skeleton"
},
{
"id": 18,
"name": "creeper"
},
{
"id": 19,
"name": "dragon"
},
{
"id": 20,
"name": "wither_skeleton"
},
{
"id": 21,
"name": "piglin"
},
{
"id": 22,
"name": "custom_head"
}
]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,233 @@
{
"default": {},
"leaves": {
"1105": 1.0,
"911": 1.5,
"916": 1.5,
"921": 1.5,
"926": 1.5,
"931": 1.5,
"936": 1.5,
"941": 1.5
},
"coweb": {
"1105": 15.0,
"911": 15.0,
"916": 15.0,
"921": 15.0,
"926": 15.0,
"931": 15.0,
"936": 15.0,
"941": 15.0
},
"plant": {
"911": 1.5,
"916": 1.5,
"921": 1.5,
"926": 1.5,
"931": 1.5,
"936": 1.5,
"941": 1.5
},
"gourd": {
"911": 1.5,
"916": 1.5,
"921": 1.5,
"926": 1.5,
"931": 1.5,
"936": 1.5,
"941": 1.5
},
"vine_or_glow_lichen": {
"1105": 2.0
},
"wool": {
"1105": 1.0
},
"sword_instantly_mines": {
"911": 2.0,
"916": 1.0,
"921": 4.0,
"926": 12.0,
"931": 6.0,
"936": 8.0,
"941": 9.0
},
"sword_efficient": {
"911": 2.0,
"916": 1.0,
"921": 4.0,
"926": 12.0,
"931": 6.0,
"936": 8.0,
"941": 9.0
},
"incorrect_for_wooden_tool": {
"912": 2.0,
"913": 2.0,
"914": 2.0,
"915": 2.0
},
"mineable/shovel": {
"912": 2.0,
"917": 1.0,
"922": 4.0,
"927": 12.0,
"932": 6.0,
"937": 8.0,
"942": 9.0
},
"mineable/pickaxe": {
"913": 2.0,
"918": 1.0,
"923": 4.0,
"928": 12.0,
"933": 6.0,
"938": 8.0,
"943": 9.0
},
"mineable/axe": {
"914": 2.0,
"919": 1.0,
"924": 4.0,
"929": 12.0,
"934": 6.0,
"939": 8.0,
"944": 9.0
},
"mineable/hoe": {
"915": 2.0,
"920": 1.0,
"925": 4.0,
"930": 12.0,
"935": 6.0,
"940": 8.0,
"945": 9.0
},
"incorrect_for_copper_tool": {
"917": 1.0,
"918": 1.0,
"919": 1.0,
"920": 1.0
},
"incorrect_for_stone_tool": {
"922": 4.0,
"923": 4.0,
"924": 4.0,
"925": 4.0
},
"incorrect_for_gold_tool": {
"927": 12.0,
"928": 12.0,
"929": 12.0,
"930": 12.0
},
"incorrect_for_iron_tool": {
"932": 6.0,
"933": 6.0,
"934": 6.0,
"935": 6.0
},
"incorrect_for_diamond_tool": {
"937": 8.0,
"938": 8.0,
"939": 8.0,
"940": 8.0
},
"incorrect_for_netherite_tool": {
"942": 9.0,
"943": 9.0,
"944": 9.0,
"945": 9.0
},
"plant;mineable/axe": {
"911": 1.5,
"916": 1.5,
"921": 1.5,
"926": 1.5,
"931": 1.5,
"936": 1.5,
"941": 1.5,
"914": 2.0,
"919": 1.0,
"924": 4.0,
"929": 12.0,
"934": 6.0,
"939": 8.0,
"944": 9.0
},
"gourd;mineable/axe": {
"911": 1.5,
"916": 1.5,
"921": 1.5,
"926": 1.5,
"931": 1.5,
"936": 1.5,
"941": 1.5,
"914": 2.0,
"919": 1.0,
"924": 4.0,
"929": 12.0,
"934": 6.0,
"939": 8.0,
"944": 9.0
},
"leaves;mineable/hoe": {
"1105": 1.0,
"911": 1.5,
"916": 1.5,
"921": 1.5,
"926": 1.5,
"931": 1.5,
"936": 1.5,
"941": 1.5,
"915": 2.0,
"920": 1.0,
"925": 4.0,
"930": 12.0,
"935": 6.0,
"940": 8.0,
"945": 9.0
},
"leaves;mineable/axe;mineable/hoe": {
"1105": 1.0,
"911": 1.5,
"916": 1.5,
"921": 1.5,
"926": 1.5,
"931": 1.5,
"936": 1.5,
"941": 1.5,
"914": 2.0,
"919": 1.0,
"924": 4.0,
"929": 12.0,
"934": 6.0,
"939": 8.0,
"944": 9.0,
"915": 2.0,
"920": 1.0,
"925": 4.0,
"930": 12.0,
"935": 6.0,
"940": 8.0,
"945": 9.0
},
"vine_or_glow_lichen;plant;mineable/axe": {
"1105": 2.0,
"911": 1.5,
"916": 1.5,
"921": 1.5,
"926": 1.5,
"931": 1.5,
"936": 1.5,
"941": 1.5,
"914": 2.0,
"919": 1.0,
"924": 4.0,
"929": 12.0,
"934": 6.0,
"939": 8.0,
"944": 9.0
}
}
@@ -0,0 +1,462 @@
[
{
"id": 0,
"name": "angry_villager"
},
{
"id": 1,
"name": "block"
},
{
"id": 2,
"name": "block_marker"
},
{
"id": 3,
"name": "bubble"
},
{
"id": 4,
"name": "cloud"
},
{
"id": 5,
"name": "copper_fire_flame"
},
{
"id": 6,
"name": "crit"
},
{
"id": 7,
"name": "damage_indicator"
},
{
"id": 8,
"name": "dragon_breath"
},
{
"id": 9,
"name": "dripping_lava"
},
{
"id": 10,
"name": "falling_lava"
},
{
"id": 11,
"name": "landing_lava"
},
{
"id": 12,
"name": "dripping_water"
},
{
"id": 13,
"name": "falling_water"
},
{
"id": 14,
"name": "dust"
},
{
"id": 15,
"name": "dust_color_transition"
},
{
"id": 16,
"name": "effect"
},
{
"id": 17,
"name": "elder_guardian"
},
{
"id": 18,
"name": "enchanted_hit"
},
{
"id": 19,
"name": "enchant"
},
{
"id": 20,
"name": "end_rod"
},
{
"id": 21,
"name": "entity_effect"
},
{
"id": 22,
"name": "explosion_emitter"
},
{
"id": 23,
"name": "explosion"
},
{
"id": 24,
"name": "gust"
},
{
"id": 25,
"name": "small_gust"
},
{
"id": 26,
"name": "gust_emitter_large"
},
{
"id": 27,
"name": "gust_emitter_small"
},
{
"id": 28,
"name": "sonic_boom"
},
{
"id": 29,
"name": "falling_dust"
},
{
"id": 30,
"name": "firework"
},
{
"id": 31,
"name": "fishing"
},
{
"id": 32,
"name": "flame"
},
{
"id": 33,
"name": "infested"
},
{
"id": 34,
"name": "cherry_leaves"
},
{
"id": 35,
"name": "pale_oak_leaves"
},
{
"id": 36,
"name": "tinted_leaves"
},
{
"id": 37,
"name": "sculk_soul"
},
{
"id": 38,
"name": "sculk_charge"
},
{
"id": 39,
"name": "sculk_charge_pop"
},
{
"id": 40,
"name": "soul_fire_flame"
},
{
"id": 41,
"name": "soul"
},
{
"id": 42,
"name": "flash"
},
{
"id": 43,
"name": "happy_villager"
},
{
"id": 44,
"name": "composter"
},
{
"id": 45,
"name": "heart"
},
{
"id": 46,
"name": "instant_effect"
},
{
"id": 47,
"name": "item"
},
{
"id": 48,
"name": "vibration"
},
{
"id": 49,
"name": "trail"
},
{
"id": 50,
"name": "item_slime"
},
{
"id": 51,
"name": "item_cobweb"
},
{
"id": 52,
"name": "item_snowball"
},
{
"id": 53,
"name": "large_smoke"
},
{
"id": 54,
"name": "lava"
},
{
"id": 55,
"name": "mycelium"
},
{
"id": 56,
"name": "note"
},
{
"id": 57,
"name": "poof"
},
{
"id": 58,
"name": "portal"
},
{
"id": 59,
"name": "rain"
},
{
"id": 60,
"name": "smoke"
},
{
"id": 61,
"name": "white_smoke"
},
{
"id": 62,
"name": "sneeze"
},
{
"id": 63,
"name": "spit"
},
{
"id": 64,
"name": "squid_ink"
},
{
"id": 65,
"name": "sweep_attack"
},
{
"id": 66,
"name": "totem_of_undying"
},
{
"id": 67,
"name": "underwater"
},
{
"id": 68,
"name": "splash"
},
{
"id": 69,
"name": "witch"
},
{
"id": 70,
"name": "bubble_pop"
},
{
"id": 71,
"name": "current_down"
},
{
"id": 72,
"name": "bubble_column_up"
},
{
"id": 73,
"name": "nautilus"
},
{
"id": 74,
"name": "dolphin"
},
{
"id": 75,
"name": "campfire_cosy_smoke"
},
{
"id": 76,
"name": "campfire_signal_smoke"
},
{
"id": 77,
"name": "dripping_honey"
},
{
"id": 78,
"name": "falling_honey"
},
{
"id": 79,
"name": "landing_honey"
},
{
"id": 80,
"name": "falling_nectar"
},
{
"id": 81,
"name": "falling_spore_blossom"
},
{
"id": 82,
"name": "ash"
},
{
"id": 83,
"name": "crimson_spore"
},
{
"id": 84,
"name": "warped_spore"
},
{
"id": 85,
"name": "spore_blossom_air"
},
{
"id": 86,
"name": "dripping_obsidian_tear"
},
{
"id": 87,
"name": "falling_obsidian_tear"
},
{
"id": 88,
"name": "landing_obsidian_tear"
},
{
"id": 89,
"name": "reverse_portal"
},
{
"id": 90,
"name": "white_ash"
},
{
"id": 91,
"name": "small_flame"
},
{
"id": 92,
"name": "snowflake"
},
{
"id": 93,
"name": "dripping_dripstone_lava"
},
{
"id": 94,
"name": "falling_dripstone_lava"
},
{
"id": 95,
"name": "dripping_dripstone_water"
},
{
"id": 96,
"name": "falling_dripstone_water"
},
{
"id": 97,
"name": "glow_squid_ink"
},
{
"id": 98,
"name": "glow"
},
{
"id": 99,
"name": "wax_on"
},
{
"id": 100,
"name": "wax_off"
},
{
"id": 101,
"name": "electric_spark"
},
{
"id": 102,
"name": "scrape"
},
{
"id": 103,
"name": "shriek"
},
{
"id": 104,
"name": "egg_crack"
},
{
"id": 105,
"name": "dust_plume"
},
{
"id": 106,
"name": "trial_spawner_detection"
},
{
"id": 107,
"name": "trial_spawner_detection_ominous"
},
{
"id": 108,
"name": "vault_connection"
},
{
"id": 109,
"name": "dust_pillar"
},
{
"id": 110,
"name": "ominous_spawning"
},
{
"id": 111,
"name": "raid_omen"
},
{
"id": 112,
"name": "trial_omen"
},
{
"id": 113,
"name": "block_crumble"
},
{
"id": 114,
"name": "firefly"
}
]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+465
View File
@@ -0,0 +1,465 @@
{
"grass": {
"data": [
{
"keys": [
"badlands",
"eroded_badlands",
"wooded_badlands"
],
"color": -7306931
},
{
"keys": [
"bamboo_jungle",
"basalt_deltas",
"beach",
"birch_forest",
"cold_ocean",
"crimson_forest",
"deep_cold_ocean",
"deep_dark",
"deep_frozen_ocean",
"deep_lukewarm_ocean",
"deep_ocean",
"desert",
"dripstone_caves",
"end_barrens",
"end_highlands",
"end_midlands",
"flower_forest",
"forest",
"frozen_ocean",
"frozen_peaks",
"frozen_river",
"grove",
"ice_spikes",
"jagged_peaks",
"jungle",
"lukewarm_ocean",
"lush_caves",
"meadow",
"mushroom_fields",
"nether_wastes",
"ocean",
"old_growth_birch_forest",
"old_growth_pine_taiga",
"old_growth_spruce_taiga",
"plains",
"river",
"savanna",
"savanna_plateau",
"small_end_islands",
"snowy_beach",
"snowy_plains",
"snowy_slopes",
"snowy_taiga",
"soul_sand_valley",
"sparse_jungle",
"stony_peaks",
"stony_shore",
"sunflower_plains",
"taiga",
"the_end",
"the_void",
"warm_ocean",
"warped_forest",
"windswept_forest",
"windswept_gravelly_hills",
"windswept_hills",
"windswept_savanna"
],
"color": 0
},
{
"keys": [
"cherry_grove"
],
"color": -4793503
},
{
"keys": [
"dark_forest"
],
"color": 1317381
},
{
"keys": [
"mangrove_swamp",
"swamp"
],
"color": 6975545
},
{
"keys": [
"pale_garden"
],
"color": -8945038
}
]
},
"foliage": {
"data": [
{
"keys": [
"badlands",
"eroded_badlands",
"wooded_badlands"
],
"color": -6389427
},
{
"keys": [
"bamboo_jungle",
"basalt_deltas",
"beach",
"birch_forest",
"cold_ocean",
"crimson_forest",
"dark_forest",
"deep_cold_ocean",
"deep_dark",
"deep_frozen_ocean",
"deep_lukewarm_ocean",
"deep_ocean",
"desert",
"dripstone_caves",
"end_barrens",
"end_highlands",
"end_midlands",
"flower_forest",
"forest",
"frozen_ocean",
"frozen_peaks",
"frozen_river",
"grove",
"ice_spikes",
"jagged_peaks",
"jungle",
"lukewarm_ocean",
"lush_caves",
"meadow",
"mushroom_fields",
"nether_wastes",
"ocean",
"old_growth_birch_forest",
"old_growth_pine_taiga",
"old_growth_spruce_taiga",
"plains",
"river",
"savanna",
"savanna_plateau",
"small_end_islands",
"snowy_beach",
"snowy_plains",
"snowy_slopes",
"snowy_taiga",
"soul_sand_valley",
"sparse_jungle",
"stony_peaks",
"stony_shore",
"sunflower_plains",
"taiga",
"the_end",
"the_void",
"warm_ocean",
"warped_forest",
"windswept_forest",
"windswept_gravelly_hills",
"windswept_hills",
"windswept_savanna"
],
"color": 0
},
{
"keys": [
"cherry_grove"
],
"color": -4793503
},
{
"keys": [
"mangrove_swamp"
],
"color": -7491289
},
{
"keys": [
"pale_garden"
],
"color": -7893642
},
{
"keys": [
"swamp"
],
"color": -9801671
}
]
},
"water": {
"data": [
{
"keys": [
"badlands",
"bamboo_jungle",
"basalt_deltas",
"beach",
"birch_forest",
"crimson_forest",
"dark_forest",
"deep_dark",
"deep_ocean",
"desert",
"dripstone_caves",
"end_barrens",
"end_highlands",
"end_midlands",
"eroded_badlands",
"flower_forest",
"forest",
"frozen_peaks",
"grove",
"ice_spikes",
"jagged_peaks",
"jungle",
"lush_caves",
"mushroom_fields",
"nether_wastes",
"ocean",
"old_growth_birch_forest",
"old_growth_pine_taiga",
"old_growth_spruce_taiga",
"plains",
"river",
"savanna",
"savanna_plateau",
"small_end_islands",
"snowy_plains",
"snowy_slopes",
"soul_sand_valley",
"sparse_jungle",
"stony_peaks",
"stony_shore",
"sunflower_plains",
"taiga",
"the_end",
"the_void",
"warped_forest",
"windswept_forest",
"windswept_gravelly_hills",
"windswept_hills",
"windswept_savanna",
"wooded_badlands"
],
"color": -12618012
},
{
"keys": [
"cherry_grove"
],
"color": -10635281
},
{
"keys": [
"cold_ocean",
"deep_cold_ocean",
"snowy_beach",
"snowy_taiga"
],
"color": -12757034
},
{
"keys": [
"deep_frozen_ocean",
"frozen_ocean",
"frozen_river"
],
"color": -13027127
},
{
"keys": [
"deep_lukewarm_ocean",
"lukewarm_ocean"
],
"color": -12210702
},
{
"keys": [
"mangrove_swamp"
],
"color": -12944790
},
{
"keys": [
"meadow"
],
"color": -15839537
},
{
"keys": [
"pale_garden"
],
"color": -9008995
},
{
"keys": [
"swamp"
],
"color": -10388636
},
{
"keys": [
"warm_ocean"
],
"color": -12331538
}
]
},
"redstone": {
"data": [
{
"keys": [
0
],
"color": 4980736
},
{
"keys": [
1
],
"color": 7340032
},
{
"keys": [
2
],
"color": 7995392
},
{
"keys": [
3
],
"color": 8650752
},
{
"keys": [
4
],
"color": 9306112
},
{
"keys": [
5
],
"color": 10027008
},
{
"keys": [
6
],
"color": 10682368
},
{
"keys": [
7
],
"color": 11337728
},
{
"keys": [
8
],
"color": 11993088
},
{
"keys": [
9
],
"color": 12648448
},
{
"keys": [
10
],
"color": 13369344
},
{
"keys": [
11
],
"color": 14024704
},
{
"keys": [
12
],
"color": 14680064
},
{
"keys": [
13
],
"color": 15336960
},
{
"keys": [
14
],
"color": 15997696
},
{
"keys": [
15
],
"color": 16724480
}
]
},
"constant": {
"data": [
{
"keys": [
"birch_leaves"
],
"color": -8345771
},
{
"keys": [
"spruce_leaves"
],
"color": -10380959
},
{
"keys": [
"lily_pad"
],
"color": -14647248
},
{
"keys": [
"attached_melon_stem"
],
"color": -2046180
},
{
"keys": [
"attached_pumpkin_stem"
],
"color": -2046180
},
{
"keys": [
"melon_stem"
],
"color": -16711936
},
{
"keys": [
"pumpkin_stem"
],
"color": -16711936
}
]
}
}
@@ -0,0 +1,6 @@
{
"version": 774,
"minecraftVersion": "1.21.11",
"majorVersion": "1.21",
"releaseType": "release"
}
@@ -0,0 +1,247 @@
[
{
"name": "armor",
"resource": "minecraft:armor",
"min": 0.0,
"max": 30.0,
"default": 0.0
},
{
"name": "armorToughness",
"resource": "minecraft:armor_toughness",
"min": 0.0,
"max": 20.0,
"default": 0.0
},
{
"name": "attackDamage",
"resource": "minecraft:attack_damage",
"min": 0.0,
"max": 2048.0,
"default": 2.0
},
{
"name": "attackKnockback",
"resource": "minecraft:attack_knockback",
"min": 0.0,
"max": 5.0,
"default": 0.0
},
{
"name": "attackSpeed",
"resource": "minecraft:attack_speed",
"min": 0.0,
"max": 1024.0,
"default": 4.0
},
{
"name": "blockBreakSpeed",
"resource": "minecraft:block_break_speed",
"min": 0.0,
"max": 1024.0,
"default": 1.0
},
{
"name": "blockInteractionRange",
"resource": "minecraft:block_interaction_range",
"min": 0.0,
"max": 64.0,
"default": 4.5
},
{
"name": "burningTime",
"resource": "minecraft:burning_time",
"min": 0.0,
"max": 1024.0,
"default": 1.0
},
{
"name": "cameraDistance",
"resource": "minecraft:camera_distance",
"min": 0.0,
"max": 32.0,
"default": 4.0
},
{
"name": "explosionKnockbackResistance",
"resource": "minecraft:explosion_knockback_resistance",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "entityInteractionRange",
"resource": "minecraft:entity_interaction_range",
"min": 0.0,
"max": 64.0,
"default": 3.0
},
{
"name": "fallDamageMultiplier",
"resource": "minecraft:fall_damage_multiplier",
"min": 0.0,
"max": 100.0,
"default": 1.0
},
{
"name": "flyingSpeed",
"resource": "minecraft:flying_speed",
"min": 0.0,
"max": 1024.0,
"default": 0.4
},
{
"name": "followRange",
"resource": "minecraft:follow_range",
"min": 0.0,
"max": 2048.0,
"default": 32.0
},
{
"name": "gravity",
"resource": "minecraft:gravity",
"min": -1.0,
"max": 1.0,
"default": 0.08
},
{
"name": "jumpStrength",
"resource": "minecraft:jump_strength",
"min": 0.0,
"max": 32.0,
"default": 0.41999998688697815
},
{
"name": "knockbackResistance",
"resource": "minecraft:knockback_resistance",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "luck",
"resource": "minecraft:luck",
"min": -1024.0,
"max": 1024.0,
"default": 0.0
},
{
"name": "maxAbsorption",
"resource": "minecraft:max_absorption",
"min": 0.0,
"max": 2048.0,
"default": 0.0
},
{
"name": "maxHealth",
"resource": "minecraft:max_health",
"min": 1.0,
"max": 1024.0,
"default": 20.0
},
{
"name": "miningEfficiency",
"resource": "minecraft:mining_efficiency",
"min": 0.0,
"max": 1024.0,
"default": 0.0
},
{
"name": "movementEfficiency",
"resource": "minecraft:movement_efficiency",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "movementSpeed",
"resource": "minecraft:movement_speed",
"min": 0.0,
"max": 1024.0,
"default": 0.7
},
{
"name": "oxygenBonus",
"resource": "minecraft:oxygen_bonus",
"min": 0.0,
"max": 1024.0,
"default": 0.0
},
{
"name": "safeFallDistance",
"resource": "minecraft:safe_fall_distance",
"min": -1024.0,
"max": 1024.0,
"default": 3.0
},
{
"name": "scale",
"resource": "minecraft:scale",
"min": 0.0625,
"max": 16.0,
"default": 1.0
},
{
"name": "sneakingSpeed",
"resource": "minecraft:sneaking_speed",
"min": 0.0,
"max": 1.0,
"default": 0.3
},
{
"name": "spawnReinforcements",
"resource": "minecraft:spawn_reinforcements",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "stepHeight",
"resource": "minecraft:step_height",
"min": 0.0,
"max": 10.0,
"default": 0.6
},
{
"name": "submergedMiningSpeed",
"resource": "minecraft:submerged_mining_speed",
"min": 0.0,
"max": 20.0,
"default": 0.2
},
{
"name": "sweepingDamageRatio",
"resource": "minecraft:sweeping_damage_ratio",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "temptRange",
"resource": "minecraft:tempt_range",
"min": 0.0,
"max": 2048.0,
"default": 10.0
},
{
"name": "waterMovementEfficiency",
"resource": "minecraft:water_movement_efficiency",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "waypointTransmitRange",
"resource": "minecraft:waypoint_transmit_range",
"min": 0.0,
"max": 6.0E7,
"default": 0.0
},
{
"name": "waypointReceiveRange",
"resource": "minecraft:waypoint_receive_range",
"min": 0.0,
"max": 6.0E7,
"default": 0.0
}
]
+652
View File
@@ -0,0 +1,652 @@
[
{
"id": 0,
"name": "badlands",
"category": "mesa",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Badlands",
"color": 7254527
},
{
"id": 1,
"name": "bamboo_jungle",
"category": "jungle",
"temperature": 0.95,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Bamboo Jungle",
"color": 7842047
},
{
"id": 2,
"name": "basalt_deltas",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Basalt Deltas",
"color": 7254527
},
{
"id": 3,
"name": "beach",
"category": "beach",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Beach",
"color": 7907327
},
{
"id": 4,
"name": "birch_forest",
"category": "forest",
"temperature": 0.6,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Birch Forest",
"color": 8037887
},
{
"id": 5,
"name": "cherry_grove",
"category": "forest",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Cherry Grove",
"color": 8103167
},
{
"id": 6,
"name": "cold_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Cold Ocean",
"color": 8103167
},
{
"id": 7,
"name": "crimson_forest",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Crimson Forest",
"color": 7254527
},
{
"id": 8,
"name": "dark_forest",
"category": "forest",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Dark Forest",
"color": 7972607
},
{
"id": 9,
"name": "deep_cold_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Cold Ocean",
"color": 8103167
},
{
"id": 10,
"name": "deep_dark",
"category": "underground",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Dark",
"color": 7907327
},
{
"id": 11,
"name": "deep_frozen_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Frozen Ocean",
"color": 8103167
},
{
"id": 12,
"name": "deep_lukewarm_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Lukewarm Ocean",
"color": 8103167
},
{
"id": 13,
"name": "deep_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Ocean",
"color": 8103167
},
{
"id": 14,
"name": "desert",
"category": "desert",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Desert",
"color": 7254527
},
{
"id": 15,
"name": "dripstone_caves",
"category": "underground",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Dripstone Caves",
"color": 7907327
},
{
"id": 16,
"name": "end_barrens",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "End Barrens",
"color": 0
},
{
"id": 17,
"name": "end_highlands",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "End Highlands",
"color": 0
},
{
"id": 18,
"name": "end_midlands",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "End Midlands",
"color": 0
},
{
"id": 19,
"name": "eroded_badlands",
"category": "mesa",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Eroded Badlands",
"color": 7254527
},
{
"id": 20,
"name": "flower_forest",
"category": "forest",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Flower Forest",
"color": 7972607
},
{
"id": 21,
"name": "forest",
"category": "forest",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Forest",
"color": 7972607
},
{
"id": 22,
"name": "frozen_ocean",
"category": "ocean",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Frozen Ocean",
"color": 8364543
},
{
"id": 23,
"name": "frozen_peaks",
"category": "ice",
"temperature": -0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Frozen Peaks",
"color": 8756735
},
{
"id": 24,
"name": "frozen_river",
"category": "ice",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Frozen River",
"color": 8364543
},
{
"id": 25,
"name": "grove",
"category": "forest",
"temperature": -0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Grove",
"color": 8495359
},
{
"id": 26,
"name": "ice_spikes",
"category": "ice",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Ice Spikes",
"color": 8364543
},
{
"id": 27,
"name": "jagged_peaks",
"category": "mountain",
"temperature": -0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Jagged Peaks",
"color": 8756735
},
{
"id": 28,
"name": "jungle",
"category": "jungle",
"temperature": 0.95,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Jungle",
"color": 7842047
},
{
"id": 29,
"name": "lukewarm_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Lukewarm Ocean",
"color": 8103167
},
{
"id": 30,
"name": "lush_caves",
"category": "underground",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Lush Caves",
"color": 8103167
},
{
"id": 31,
"name": "mangrove_swamp",
"category": "forest",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Mangrove Swamp",
"color": 7907327
},
{
"id": 32,
"name": "meadow",
"category": "mountain",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Meadow",
"color": 8103167
},
{
"id": 33,
"name": "mushroom_fields",
"category": "mushroom",
"temperature": 0.9,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Mushroom Fields",
"color": 7842047
},
{
"id": 34,
"name": "nether_wastes",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Nether Wastes",
"color": 7254527
},
{
"id": 35,
"name": "ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Ocean",
"color": 8103167
},
{
"id": 36,
"name": "old_growth_birch_forest",
"category": "forest",
"temperature": 0.6,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Old Growth Birch Forest",
"color": 8037887
},
{
"id": 37,
"name": "old_growth_pine_taiga",
"category": "taiga",
"temperature": 0.3,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Old Growth Pine Taiga",
"color": 8168447
},
{
"id": 38,
"name": "old_growth_spruce_taiga",
"category": "taiga",
"temperature": 0.25,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Old Growth Spruce Taiga",
"color": 8233983
},
{
"id": 39,
"name": "pale_garden",
"category": "none",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Pale Garden",
"color": 12171705
},
{
"id": 40,
"name": "plains",
"category": "plains",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Plains",
"color": 7907327
},
{
"id": 41,
"name": "river",
"category": "river",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "River",
"color": 8103167
},
{
"id": 42,
"name": "savanna",
"category": "savanna",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Savanna",
"color": 7254527
},
{
"id": 43,
"name": "savanna_plateau",
"category": "savanna",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Savanna Plateau",
"color": 7254527
},
{
"id": 44,
"name": "small_end_islands",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "Small End Islands",
"color": 0
},
{
"id": 45,
"name": "snowy_beach",
"category": "beach",
"temperature": 0.05,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Beach",
"color": 8364543
},
{
"id": 46,
"name": "snowy_plains",
"category": "plains",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Plains",
"color": 8364543
},
{
"id": 47,
"name": "snowy_slopes",
"category": "mountain",
"temperature": -0.3,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Slopes",
"color": 8560639
},
{
"id": 48,
"name": "snowy_taiga",
"category": "taiga",
"temperature": -0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Taiga",
"color": 8625919
},
{
"id": 49,
"name": "soul_sand_valley",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Soul Sand Valley",
"color": 7254527
},
{
"id": 50,
"name": "sparse_jungle",
"category": "jungle",
"temperature": 0.95,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Sparse Jungle",
"color": 7842047
},
{
"id": 51,
"name": "stony_peaks",
"category": "mountain",
"temperature": 1.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Stony Peaks",
"color": 7776511
},
{
"id": 52,
"name": "stony_shore",
"category": "beach",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Stony Shore",
"color": 8233727
},
{
"id": 53,
"name": "sunflower_plains",
"category": "plains",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Sunflower Plains",
"color": 7907327
},
{
"id": 54,
"name": "swamp",
"category": "swamp",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Swamp",
"color": 7907327
},
{
"id": 55,
"name": "taiga",
"category": "taiga",
"temperature": 0.25,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Taiga",
"color": 8233983
},
{
"id": 56,
"name": "the_end",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "The End",
"color": 0
},
{
"id": 57,
"name": "the_void",
"category": "none",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "The Void",
"color": 8103167
},
{
"id": 58,
"name": "warm_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Warm Ocean",
"color": 8103167
},
{
"id": 59,
"name": "warped_forest",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Warped Forest",
"color": 7254527
},
{
"id": 60,
"name": "windswept_forest",
"category": "forest",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Windswept Forest",
"color": 8233727
},
{
"id": 61,
"name": "windswept_gravelly_hills",
"category": "extreme_hills",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Windswept Gravelly Hills",
"color": 8233727
},
{
"id": 62,
"name": "windswept_hills",
"category": "extreme_hills",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Windswept Hills",
"color": 8233727
},
{
"id": 63,
"name": "windswept_savanna",
"category": "savanna",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Windswept Savanna",
"color": 7254527
},
{
"id": 64,
"name": "wooded_badlands",
"category": "mesa",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Wooded Badlands",
"color": 7254527
}
]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+236
View File
@@ -0,0 +1,236 @@
[
{
"id": 0,
"name": "Speed",
"displayName": "Speed",
"type": "good"
},
{
"id": 1,
"name": "Slowness",
"displayName": "Slowness",
"type": "bad"
},
{
"id": 2,
"name": "Haste",
"displayName": "Haste",
"type": "good"
},
{
"id": 3,
"name": "MiningFatigue",
"displayName": "Mining Fatigue",
"type": "bad"
},
{
"id": 4,
"name": "Strength",
"displayName": "Strength",
"type": "good"
},
{
"id": 5,
"name": "InstantHealth",
"displayName": "Instant Health",
"type": "good"
},
{
"id": 6,
"name": "InstantDamage",
"displayName": "Instant Damage",
"type": "bad"
},
{
"id": 7,
"name": "JumpBoost",
"displayName": "Jump Boost",
"type": "good"
},
{
"id": 8,
"name": "Nausea",
"displayName": "Nausea",
"type": "bad"
},
{
"id": 9,
"name": "Regeneration",
"displayName": "Regeneration",
"type": "good"
},
{
"id": 10,
"name": "Resistance",
"displayName": "Resistance",
"type": "good"
},
{
"id": 11,
"name": "FireResistance",
"displayName": "Fire Resistance",
"type": "good"
},
{
"id": 12,
"name": "WaterBreathing",
"displayName": "Water Breathing",
"type": "good"
},
{
"id": 13,
"name": "Invisibility",
"displayName": "Invisibility",
"type": "good"
},
{
"id": 14,
"name": "Blindness",
"displayName": "Blindness",
"type": "bad"
},
{
"id": 15,
"name": "NightVision",
"displayName": "Night Vision",
"type": "good"
},
{
"id": 16,
"name": "Hunger",
"displayName": "Hunger",
"type": "bad"
},
{
"id": 17,
"name": "Weakness",
"displayName": "Weakness",
"type": "bad"
},
{
"id": 18,
"name": "Poison",
"displayName": "Poison",
"type": "bad"
},
{
"id": 19,
"name": "Wither",
"displayName": "Wither",
"type": "bad"
},
{
"id": 20,
"name": "HealthBoost",
"displayName": "Health Boost",
"type": "good"
},
{
"id": 21,
"name": "Absorption",
"displayName": "Absorption",
"type": "good"
},
{
"id": 22,
"name": "Saturation",
"displayName": "Saturation",
"type": "good"
},
{
"id": 23,
"name": "Glowing",
"displayName": "Glowing",
"type": "bad"
},
{
"id": 24,
"name": "Levitation",
"displayName": "Levitation",
"type": "bad"
},
{
"id": 25,
"name": "Luck",
"displayName": "Luck",
"type": "good"
},
{
"id": 26,
"name": "BadLuck",
"displayName": "Bad Luck",
"type": "bad"
},
{
"id": 27,
"name": "SlowFalling",
"displayName": "Slow Falling",
"type": "good"
},
{
"id": 28,
"name": "ConduitPower",
"displayName": "Conduit Power",
"type": "good"
},
{
"id": 29,
"name": "DolphinsGrace",
"displayName": "Dolphin's Grace",
"type": "good"
},
{
"id": 30,
"name": "BadOmen",
"displayName": "Bad Omen",
"type": "bad"
},
{
"id": 31,
"name": "HeroOfTheVillage",
"displayName": "Hero of the Village",
"type": "good"
},
{
"id": 32,
"name": "Darkness",
"displayName": "Darkness",
"type": "bad"
},
{
"id": 33,
"name": "TrialOmen",
"displayName": "Trial Omen",
"type": "bad"
},
{
"id": 34,
"name": "RaidOmen",
"displayName": "Raid Omen",
"type": "bad"
},
{
"id": 35,
"name": "WindCharged",
"displayName": "Wind Charged",
"type": "bad"
},
{
"id": 36,
"name": "Weaving",
"displayName": "Weaving",
"type": "bad"
},
{
"id": 37,
"name": "Oozing",
"displayName": "Oozing",
"type": "bad"
},
{
"id": 38,
"name": "Infested",
"displayName": "Infested",
"type": "bad"
}
]
@@ -0,0 +1,959 @@
[
{
"id": 0,
"name": "aqua_affinity",
"displayName": "Aqua Affinity",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "head_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 1,
"name": "bane_of_arthropods",
"displayName": "Bane of Arthropods",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"breach",
"density",
"impaling",
"sharpness",
"smite"
],
"category": "weapon",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 2,
"name": "binding_curse",
"displayName": "Curse of Binding",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": true,
"curse": true,
"exclude": [],
"category": "equippable",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 3,
"name": "blast_protection",
"displayName": "Blast Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"fire_protection",
"projectile_protection",
"protection"
],
"category": "armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 4,
"name": "breach",
"displayName": "Breach",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"density",
"impaling",
"sharpness",
"smite"
],
"category": "mace",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 5,
"name": "channeling",
"displayName": "Channeling",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"riptide"
],
"category": "trident",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 6,
"name": "density",
"displayName": "Density",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"impaling",
"sharpness",
"smite"
],
"category": "mace",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 7,
"name": "depth_strider",
"displayName": "Depth Strider",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"frost_walker"
],
"category": "foot_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 8,
"name": "efficiency",
"displayName": "Efficiency",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "mining",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 9,
"name": "feather_falling",
"displayName": "Feather Falling",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "foot_armor",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 10,
"name": "fire_aspect",
"displayName": "Fire Aspect",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "fire_aspect",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 11,
"name": "fire_protection",
"displayName": "Fire Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"blast_protection",
"projectile_protection",
"protection"
],
"category": "armor",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 12,
"name": "flame",
"displayName": "Flame",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "bow",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 13,
"name": "fortune",
"displayName": "Fortune",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"silk_touch"
],
"category": "mining_loot",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 14,
"name": "frost_walker",
"displayName": "Frost Walker",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [
"depth_strider"
],
"category": "foot_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 15,
"name": "impaling",
"displayName": "Impaling",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"density",
"sharpness",
"smite"
],
"category": "trident",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 16,
"name": "infinity",
"displayName": "Infinity",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"mending"
],
"category": "bow",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 17,
"name": "knockback",
"displayName": "Knockback",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "sword",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 18,
"name": "looting",
"displayName": "Looting",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "sword",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 19,
"name": "loyalty",
"displayName": "Loyalty",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"riptide"
],
"category": "trident",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 20,
"name": "luck_of_the_sea",
"displayName": "Luck of the Sea",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "fishing",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 21,
"name": "lure",
"displayName": "Lure",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "fishing",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 22,
"name": "mending",
"displayName": "Mending",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [
"infinity"
],
"category": "durability",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 23,
"name": "multishot",
"displayName": "Multishot",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"piercing"
],
"category": "crossbow",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 24,
"name": "piercing",
"displayName": "Piercing",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"multishot"
],
"category": "crossbow",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 25,
"name": "power",
"displayName": "Power",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "bow",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 26,
"name": "projectile_protection",
"displayName": "Projectile Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"blast_protection",
"fire_protection",
"protection"
],
"category": "armor",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 27,
"name": "protection",
"displayName": "Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"blast_protection",
"fire_protection",
"projectile_protection"
],
"category": "armor",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 28,
"name": "punch",
"displayName": "Punch",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "bow",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 29,
"name": "quick_charge",
"displayName": "Quick Charge",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "crossbow",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 30,
"name": "respiration",
"displayName": "Respiration",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "head_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 31,
"name": "riptide",
"displayName": "Riptide",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"channeling",
"loyalty"
],
"category": "trident",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 32,
"name": "sharpness",
"displayName": "Sharpness",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"density",
"impaling",
"smite"
],
"category": "sharp_weapon",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 33,
"name": "silk_touch",
"displayName": "Silk Touch",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"fortune"
],
"category": "mining_loot",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 34,
"name": "smite",
"displayName": "Smite",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"density",
"impaling",
"sharpness"
],
"category": "weapon",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 35,
"name": "soul_speed",
"displayName": "Soul Speed",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [],
"category": "foot_armor",
"weight": 1,
"tradeable": false,
"discoverable": false
},
{
"id": 36,
"name": "sweeping_edge",
"displayName": "Sweeping Edge",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "sword",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 37,
"name": "swift_sneak",
"displayName": "Swift Sneak",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [],
"category": "leg_armor",
"weight": 1,
"tradeable": false,
"discoverable": false
},
{
"id": 38,
"name": "thorns",
"displayName": "Thorns",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "armor",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 39,
"name": "unbreaking",
"displayName": "Unbreaking",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "durability",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 40,
"name": "vanishing_curse",
"displayName": "Curse of Vanishing",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": true,
"curse": true,
"exclude": [],
"category": "vanishing",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 41,
"name": "wind_burst",
"displayName": "Wind Burst",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [],
"category": "mace",
"weight": 2,
"tradeable": false,
"discoverable": false
}
]
File diff suppressed because it is too large Load Diff
+402
View File
@@ -0,0 +1,402 @@
[
{
"id": 857,
"name": "apple",
"stackSize": 64,
"displayName": "Apple",
"foodPoints": 4.0,
"saturation": 19.2,
"effectiveQuality": 23.2,
"saturationRatio": 4.8
},
{
"id": 906,
"name": "mushroom_stew",
"stackSize": 1,
"displayName": "Mushroom Stew",
"foodPoints": 6.0,
"saturation": 86.4,
"effectiveQuality": 92.4,
"saturationRatio": 14.400001
},
{
"id": 912,
"name": "bread",
"stackSize": 64,
"displayName": "Bread",
"foodPoints": 5.0,
"saturation": 60.0,
"effectiveQuality": 65.0,
"saturationRatio": 12.0
},
{
"id": 938,
"name": "porkchop",
"stackSize": 64,
"displayName": "Raw Porkchop",
"foodPoints": 3.0,
"saturation": 10.8,
"effectiveQuality": 13.8,
"saturationRatio": 3.6000001
},
{
"id": 939,
"name": "cooked_porkchop",
"stackSize": 64,
"displayName": "Cooked Porkchop",
"foodPoints": 8.0,
"saturation": 204.8,
"effectiveQuality": 212.8,
"saturationRatio": 25.6
},
{
"id": 941,
"name": "golden_apple",
"stackSize": 64,
"displayName": "Golden Apple",
"foodPoints": 4.0,
"saturation": 76.8,
"effectiveQuality": 80.8,
"saturationRatio": 19.2
},
{
"id": 942,
"name": "enchanted_golden_apple",
"stackSize": 64,
"displayName": "Enchanted Golden Apple",
"foodPoints": 4.0,
"saturation": 76.8,
"effectiveQuality": 80.8,
"saturationRatio": 19.2
},
{
"id": 1012,
"name": "cod",
"stackSize": 64,
"displayName": "Raw Cod",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1013,
"name": "salmon",
"stackSize": 64,
"displayName": "Raw Salmon",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1014,
"name": "tropical_fish",
"stackSize": 64,
"displayName": "Tropical Fish",
"foodPoints": 1.0,
"saturation": 0.4,
"effectiveQuality": 1.4,
"saturationRatio": 0.4
},
{
"id": 1015,
"name": "pufferfish",
"stackSize": 64,
"displayName": "Pufferfish",
"foodPoints": 1.0,
"saturation": 0.4,
"effectiveQuality": 1.4,
"saturationRatio": 0.4
},
{
"id": 1016,
"name": "cooked_cod",
"stackSize": 64,
"displayName": "Cooked Cod",
"foodPoints": 5.0,
"saturation": 60.0,
"effectiveQuality": 65.0,
"saturationRatio": 12.0
},
{
"id": 1017,
"name": "cooked_salmon",
"stackSize": 64,
"displayName": "Cooked Salmon",
"foodPoints": 6.0,
"saturation": 115.200005,
"effectiveQuality": 121.200005,
"saturationRatio": 19.2
},
{
"id": 1057,
"name": "cookie",
"stackSize": 64,
"displayName": "Cookie",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1061,
"name": "melon_slice",
"stackSize": 64,
"displayName": "Melon Slice",
"foodPoints": 2.0,
"saturation": 4.8,
"effectiveQuality": 6.8,
"saturationRatio": 2.4
},
{
"id": 1062,
"name": "dried_kelp",
"stackSize": 64,
"displayName": "Dried Kelp",
"foodPoints": 1.0,
"saturation": 1.2,
"effectiveQuality": 2.2,
"saturationRatio": 1.2
},
{
"id": 1065,
"name": "beef",
"stackSize": 64,
"displayName": "Raw Beef",
"foodPoints": 3.0,
"saturation": 10.8,
"effectiveQuality": 13.8,
"saturationRatio": 3.6000001
},
{
"id": 1066,
"name": "cooked_beef",
"stackSize": 64,
"displayName": "Steak",
"foodPoints": 8.0,
"saturation": 204.8,
"effectiveQuality": 212.8,
"saturationRatio": 25.6
},
{
"id": 1067,
"name": "chicken",
"stackSize": 64,
"displayName": "Raw Chicken",
"foodPoints": 2.0,
"saturation": 4.8,
"effectiveQuality": 6.8,
"saturationRatio": 2.4
},
{
"id": 1068,
"name": "cooked_chicken",
"stackSize": 64,
"displayName": "Cooked Chicken",
"foodPoints": 6.0,
"saturation": 86.4,
"effectiveQuality": 92.4,
"saturationRatio": 14.400001
},
{
"id": 1069,
"name": "rotten_flesh",
"stackSize": 64,
"displayName": "Rotten Flesh",
"foodPoints": 4.0,
"saturation": 6.4,
"effectiveQuality": 10.4,
"saturationRatio": 1.6
},
{
"id": 1077,
"name": "spider_eye",
"stackSize": 64,
"displayName": "Spider Eye",
"foodPoints": 2.0,
"saturation": 12.8,
"effectiveQuality": 14.8,
"saturationRatio": 6.4
},
{
"id": 1177,
"name": "carrot",
"stackSize": 64,
"displayName": "Carrot",
"foodPoints": 3.0,
"saturation": 21.6,
"effectiveQuality": 24.6,
"saturationRatio": 7.2000003
},
{
"id": 1178,
"name": "potato",
"stackSize": 64,
"displayName": "Potato",
"foodPoints": 1.0,
"saturation": 1.2,
"effectiveQuality": 2.2,
"saturationRatio": 1.2
},
{
"id": 1179,
"name": "baked_potato",
"stackSize": 64,
"displayName": "Baked Potato",
"foodPoints": 5.0,
"saturation": 60.0,
"effectiveQuality": 65.0,
"saturationRatio": 12.0
},
{
"id": 1180,
"name": "poisonous_potato",
"stackSize": 64,
"displayName": "Poisonous Potato",
"foodPoints": 2.0,
"saturation": 4.8,
"effectiveQuality": 6.8,
"saturationRatio": 2.4
},
{
"id": 1182,
"name": "golden_carrot",
"stackSize": 64,
"displayName": "Golden Carrot",
"foodPoints": 6.0,
"saturation": 172.8,
"effectiveQuality": 178.8,
"saturationRatio": 28.800001
},
{
"id": 1191,
"name": "pumpkin_pie",
"stackSize": 64,
"displayName": "Pumpkin Pie",
"foodPoints": 8.0,
"saturation": 76.8,
"effectiveQuality": 84.8,
"saturationRatio": 9.6
},
{
"id": 1199,
"name": "rabbit",
"stackSize": 64,
"displayName": "Raw Rabbit",
"foodPoints": 3.0,
"saturation": 10.8,
"effectiveQuality": 13.8,
"saturationRatio": 3.6000001
},
{
"id": 1200,
"name": "cooked_rabbit",
"stackSize": 64,
"displayName": "Cooked Rabbit",
"foodPoints": 5.0,
"saturation": 60.0,
"effectiveQuality": 65.0,
"saturationRatio": 12.0
},
{
"id": 1201,
"name": "rabbit_stew",
"stackSize": 1,
"displayName": "Rabbit Stew",
"foodPoints": 10.0,
"saturation": 240.0,
"effectiveQuality": 250.0,
"saturationRatio": 24.0
},
{
"id": 1212,
"name": "mutton",
"stackSize": 64,
"displayName": "Raw Mutton",
"foodPoints": 2.0,
"saturation": 4.8,
"effectiveQuality": 6.8,
"saturationRatio": 2.4
},
{
"id": 1213,
"name": "cooked_mutton",
"stackSize": 64,
"displayName": "Cooked Mutton",
"foodPoints": 6.0,
"saturation": 115.200005,
"effectiveQuality": 121.200005,
"saturationRatio": 19.2
},
{
"id": 1231,
"name": "chorus_fruit",
"stackSize": 64,
"displayName": "Chorus Fruit",
"foodPoints": 4.0,
"saturation": 19.2,
"effectiveQuality": 23.2,
"saturationRatio": 4.8
},
{
"id": 1235,
"name": "beetroot",
"stackSize": 64,
"displayName": "Beetroot",
"foodPoints": 1.0,
"saturation": 2.4,
"effectiveQuality": 3.4,
"saturationRatio": 2.4
},
{
"id": 1237,
"name": "beetroot_soup",
"stackSize": 1,
"displayName": "Beetroot Soup",
"foodPoints": 6.0,
"saturation": 86.4,
"effectiveQuality": 92.4,
"saturationRatio": 14.400001
},
{
"id": 1275,
"name": "suspicious_stew",
"stackSize": 1,
"displayName": "Suspicious Stew",
"foodPoints": 6.0,
"saturation": 86.4,
"effectiveQuality": 92.4,
"saturationRatio": 14.400001
},
{
"id": 1300,
"name": "sweet_berries",
"stackSize": 64,
"displayName": "Sweet Berries",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1301,
"name": "glow_berries",
"stackSize": 64,
"displayName": "Glow Berries",
"foodPoints": 2.0,
"saturation": 1.6,
"effectiveQuality": 3.6,
"saturationRatio": 0.8
},
{
"id": 1308,
"name": "honey_bottle",
"stackSize": 16,
"displayName": "Honey Bottle",
"foodPoints": 6.0,
"saturation": 14.400001,
"effectiveQuality": 20.400002,
"saturationRatio": 2.4
}
]
@@ -0,0 +1,94 @@
[
{
"id": 0,
"name": "harp"
},
{
"id": 1,
"name": "basedrum"
},
{
"id": 2,
"name": "snare"
},
{
"id": 3,
"name": "hat"
},
{
"id": 4,
"name": "bass"
},
{
"id": 5,
"name": "flute"
},
{
"id": 6,
"name": "bell"
},
{
"id": 7,
"name": "guitar"
},
{
"id": 8,
"name": "chime"
},
{
"id": 9,
"name": "xylophone"
},
{
"id": 10,
"name": "iron_xylophone"
},
{
"id": 11,
"name": "cow_bell"
},
{
"id": 12,
"name": "didgeridoo"
},
{
"id": 13,
"name": "bit"
},
{
"id": 14,
"name": "banjo"
},
{
"id": 15,
"name": "pling"
},
{
"id": 16,
"name": "zombie"
},
{
"id": 17,
"name": "skeleton"
},
{
"id": 18,
"name": "creeper"
},
{
"id": 19,
"name": "dragon"
},
{
"id": 20,
"name": "wither_skeleton"
},
{
"id": 21,
"name": "piglin"
},
{
"id": 22,
"name": "custom_head"
}
]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,206 @@
{
"default": {},
"leaves": {
"1060": 1.0,
"875": 1.5,
"880": 1.5,
"885": 1.5,
"890": 1.5,
"895": 1.5,
"900": 1.5
},
"coweb": {
"1060": 15.0,
"875": 15.0,
"880": 15.0,
"885": 15.0,
"890": 15.0,
"895": 15.0,
"900": 15.0
},
"plant": {
"875": 1.5,
"880": 1.5,
"885": 1.5,
"890": 1.5,
"895": 1.5,
"900": 1.5
},
"gourd": {
"875": 1.5,
"880": 1.5,
"885": 1.5,
"890": 1.5,
"895": 1.5,
"900": 1.5
},
"vine_or_glow_lichen": {
"1060": 2.0
},
"wool": {
"1060": 1.0
},
"sword_instantly_mines": {
"875": 2.0,
"880": 4.0,
"885": 12.0,
"890": 6.0,
"895": 8.0,
"900": 9.0
},
"sword_efficient": {
"875": 2.0,
"880": 4.0,
"885": 12.0,
"890": 6.0,
"895": 8.0,
"900": 9.0
},
"incorrect_for_wooden_tool": {
"876": 2.0,
"877": 2.0,
"878": 2.0,
"879": 2.0
},
"mineable/shovel": {
"876": 2.0,
"881": 4.0,
"886": 12.0,
"891": 6.0,
"896": 8.0,
"901": 9.0
},
"mineable/pickaxe": {
"877": 2.0,
"882": 4.0,
"887": 12.0,
"892": 6.0,
"897": 8.0,
"902": 9.0
},
"mineable/axe": {
"878": 2.0,
"883": 4.0,
"888": 12.0,
"893": 6.0,
"898": 8.0,
"903": 9.0
},
"mineable/hoe": {
"879": 2.0,
"884": 4.0,
"889": 12.0,
"894": 6.0,
"899": 8.0,
"904": 9.0
},
"incorrect_for_stone_tool": {
"881": 4.0,
"882": 4.0,
"883": 4.0,
"884": 4.0
},
"incorrect_for_gold_tool": {
"886": 12.0,
"887": 12.0,
"888": 12.0,
"889": 12.0
},
"incorrect_for_iron_tool": {
"891": 6.0,
"892": 6.0,
"893": 6.0,
"894": 6.0
},
"incorrect_for_diamond_tool": {
"896": 8.0,
"897": 8.0,
"898": 8.0,
"899": 8.0
},
"incorrect_for_netherite_tool": {
"901": 9.0,
"902": 9.0,
"903": 9.0,
"904": 9.0
},
"plant;mineable/axe": {
"875": 1.5,
"880": 1.5,
"885": 1.5,
"890": 1.5,
"895": 1.5,
"900": 1.5,
"878": 2.0,
"883": 4.0,
"888": 12.0,
"893": 6.0,
"898": 8.0,
"903": 9.0
},
"gourd;mineable/axe": {
"875": 1.5,
"880": 1.5,
"885": 1.5,
"890": 1.5,
"895": 1.5,
"900": 1.5,
"878": 2.0,
"883": 4.0,
"888": 12.0,
"893": 6.0,
"898": 8.0,
"903": 9.0
},
"leaves;mineable/hoe": {
"1060": 1.0,
"875": 1.5,
"880": 1.5,
"885": 1.5,
"890": 1.5,
"895": 1.5,
"900": 1.5,
"879": 2.0,
"884": 4.0,
"889": 12.0,
"894": 6.0,
"899": 8.0,
"904": 9.0
},
"leaves;mineable/axe;mineable/hoe": {
"1060": 1.0,
"875": 1.5,
"880": 1.5,
"885": 1.5,
"890": 1.5,
"895": 1.5,
"900": 1.5,
"878": 2.0,
"883": 4.0,
"888": 12.0,
"893": 6.0,
"898": 8.0,
"903": 9.0,
"879": 2.0,
"884": 4.0,
"889": 12.0,
"894": 6.0,
"899": 8.0,
"904": 9.0
},
"vine_or_glow_lichen;plant;mineable/axe": {
"1060": 2.0,
"875": 1.5,
"880": 1.5,
"885": 1.5,
"890": 1.5,
"895": 1.5,
"900": 1.5,
"878": 2.0,
"883": 4.0,
"888": 12.0,
"893": 6.0,
"898": 8.0,
"903": 9.0
}
}
@@ -0,0 +1,458 @@
[
{
"id": 0,
"name": "angry_villager"
},
{
"id": 1,
"name": "block"
},
{
"id": 2,
"name": "block_marker"
},
{
"id": 3,
"name": "bubble"
},
{
"id": 4,
"name": "cloud"
},
{
"id": 5,
"name": "crit"
},
{
"id": 6,
"name": "damage_indicator"
},
{
"id": 7,
"name": "dragon_breath"
},
{
"id": 8,
"name": "dripping_lava"
},
{
"id": 9,
"name": "falling_lava"
},
{
"id": 10,
"name": "landing_lava"
},
{
"id": 11,
"name": "dripping_water"
},
{
"id": 12,
"name": "falling_water"
},
{
"id": 13,
"name": "dust"
},
{
"id": 14,
"name": "dust_color_transition"
},
{
"id": 15,
"name": "effect"
},
{
"id": 16,
"name": "elder_guardian"
},
{
"id": 17,
"name": "enchanted_hit"
},
{
"id": 18,
"name": "enchant"
},
{
"id": 19,
"name": "end_rod"
},
{
"id": 20,
"name": "entity_effect"
},
{
"id": 21,
"name": "explosion_emitter"
},
{
"id": 22,
"name": "explosion"
},
{
"id": 23,
"name": "gust"
},
{
"id": 24,
"name": "small_gust"
},
{
"id": 25,
"name": "gust_emitter_large"
},
{
"id": 26,
"name": "gust_emitter_small"
},
{
"id": 27,
"name": "sonic_boom"
},
{
"id": 28,
"name": "falling_dust"
},
{
"id": 29,
"name": "firework"
},
{
"id": 30,
"name": "fishing"
},
{
"id": 31,
"name": "flame"
},
{
"id": 32,
"name": "infested"
},
{
"id": 33,
"name": "cherry_leaves"
},
{
"id": 34,
"name": "pale_oak_leaves"
},
{
"id": 35,
"name": "tinted_leaves"
},
{
"id": 36,
"name": "sculk_soul"
},
{
"id": 37,
"name": "sculk_charge"
},
{
"id": 38,
"name": "sculk_charge_pop"
},
{
"id": 39,
"name": "soul_fire_flame"
},
{
"id": 40,
"name": "soul"
},
{
"id": 41,
"name": "flash"
},
{
"id": 42,
"name": "happy_villager"
},
{
"id": 43,
"name": "composter"
},
{
"id": 44,
"name": "heart"
},
{
"id": 45,
"name": "instant_effect"
},
{
"id": 46,
"name": "item"
},
{
"id": 47,
"name": "vibration"
},
{
"id": 48,
"name": "trail"
},
{
"id": 49,
"name": "item_slime"
},
{
"id": 50,
"name": "item_cobweb"
},
{
"id": 51,
"name": "item_snowball"
},
{
"id": 52,
"name": "large_smoke"
},
{
"id": 53,
"name": "lava"
},
{
"id": 54,
"name": "mycelium"
},
{
"id": 55,
"name": "note"
},
{
"id": 56,
"name": "poof"
},
{
"id": 57,
"name": "portal"
},
{
"id": 58,
"name": "rain"
},
{
"id": 59,
"name": "smoke"
},
{
"id": 60,
"name": "white_smoke"
},
{
"id": 61,
"name": "sneeze"
},
{
"id": 62,
"name": "spit"
},
{
"id": 63,
"name": "squid_ink"
},
{
"id": 64,
"name": "sweep_attack"
},
{
"id": 65,
"name": "totem_of_undying"
},
{
"id": 66,
"name": "underwater"
},
{
"id": 67,
"name": "splash"
},
{
"id": 68,
"name": "witch"
},
{
"id": 69,
"name": "bubble_pop"
},
{
"id": 70,
"name": "current_down"
},
{
"id": 71,
"name": "bubble_column_up"
},
{
"id": 72,
"name": "nautilus"
},
{
"id": 73,
"name": "dolphin"
},
{
"id": 74,
"name": "campfire_cosy_smoke"
},
{
"id": 75,
"name": "campfire_signal_smoke"
},
{
"id": 76,
"name": "dripping_honey"
},
{
"id": 77,
"name": "falling_honey"
},
{
"id": 78,
"name": "landing_honey"
},
{
"id": 79,
"name": "falling_nectar"
},
{
"id": 80,
"name": "falling_spore_blossom"
},
{
"id": 81,
"name": "ash"
},
{
"id": 82,
"name": "crimson_spore"
},
{
"id": 83,
"name": "warped_spore"
},
{
"id": 84,
"name": "spore_blossom_air"
},
{
"id": 85,
"name": "dripping_obsidian_tear"
},
{
"id": 86,
"name": "falling_obsidian_tear"
},
{
"id": 87,
"name": "landing_obsidian_tear"
},
{
"id": 88,
"name": "reverse_portal"
},
{
"id": 89,
"name": "white_ash"
},
{
"id": 90,
"name": "small_flame"
},
{
"id": 91,
"name": "snowflake"
},
{
"id": 92,
"name": "dripping_dripstone_lava"
},
{
"id": 93,
"name": "falling_dripstone_lava"
},
{
"id": 94,
"name": "dripping_dripstone_water"
},
{
"id": 95,
"name": "falling_dripstone_water"
},
{
"id": 96,
"name": "glow_squid_ink"
},
{
"id": 97,
"name": "glow"
},
{
"id": 98,
"name": "wax_on"
},
{
"id": 99,
"name": "wax_off"
},
{
"id": 100,
"name": "electric_spark"
},
{
"id": 101,
"name": "scrape"
},
{
"id": 102,
"name": "shriek"
},
{
"id": 103,
"name": "egg_crack"
},
{
"id": 104,
"name": "dust_plume"
},
{
"id": 105,
"name": "trial_spawner_detection"
},
{
"id": 106,
"name": "trial_spawner_detection_ominous"
},
{
"id": 107,
"name": "vault_connection"
},
{
"id": 108,
"name": "dust_pillar"
},
{
"id": 109,
"name": "ominous_spawning"
},
{
"id": 110,
"name": "raid_omen"
},
{
"id": 111,
"name": "trial_omen"
},
{
"id": 112,
"name": "block_crumble"
},
{
"id": 113,
"name": "firefly"
}
]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+465
View File
@@ -0,0 +1,465 @@
{
"grass": {
"data": [
{
"keys": [
"badlands",
"eroded_badlands",
"wooded_badlands"
],
"color": 9470285
},
{
"keys": [
"bamboo_jungle",
"basalt_deltas",
"beach",
"birch_forest",
"cold_ocean",
"crimson_forest",
"deep_cold_ocean",
"deep_dark",
"deep_frozen_ocean",
"deep_lukewarm_ocean",
"deep_ocean",
"desert",
"dripstone_caves",
"end_barrens",
"end_highlands",
"end_midlands",
"flower_forest",
"forest",
"frozen_ocean",
"frozen_peaks",
"frozen_river",
"grove",
"ice_spikes",
"jagged_peaks",
"jungle",
"lukewarm_ocean",
"lush_caves",
"meadow",
"mushroom_fields",
"nether_wastes",
"ocean",
"old_growth_birch_forest",
"old_growth_pine_taiga",
"old_growth_spruce_taiga",
"plains",
"river",
"savanna",
"savanna_plateau",
"small_end_islands",
"snowy_beach",
"snowy_plains",
"snowy_slopes",
"snowy_taiga",
"soul_sand_valley",
"sparse_jungle",
"stony_peaks",
"stony_shore",
"sunflower_plains",
"taiga",
"the_end",
"the_void",
"warm_ocean",
"warped_forest",
"windswept_forest",
"windswept_gravelly_hills",
"windswept_hills",
"windswept_savanna"
],
"color": 0
},
{
"keys": [
"cherry_grove"
],
"color": 11983713
},
{
"keys": [
"dark_forest"
],
"color": 1317381
},
{
"keys": [
"mangrove_swamp",
"swamp"
],
"color": 6975545
},
{
"keys": [
"pale_garden"
],
"color": 7832178
}
]
},
"foliage": {
"data": [
{
"keys": [
"badlands",
"eroded_badlands",
"wooded_badlands"
],
"color": 10387789
},
{
"keys": [
"bamboo_jungle",
"basalt_deltas",
"beach",
"birch_forest",
"cold_ocean",
"crimson_forest",
"dark_forest",
"deep_cold_ocean",
"deep_dark",
"deep_frozen_ocean",
"deep_lukewarm_ocean",
"deep_ocean",
"desert",
"dripstone_caves",
"end_barrens",
"end_highlands",
"end_midlands",
"flower_forest",
"forest",
"frozen_ocean",
"frozen_peaks",
"frozen_river",
"grove",
"ice_spikes",
"jagged_peaks",
"jungle",
"lukewarm_ocean",
"lush_caves",
"meadow",
"mushroom_fields",
"nether_wastes",
"ocean",
"old_growth_birch_forest",
"old_growth_pine_taiga",
"old_growth_spruce_taiga",
"plains",
"river",
"savanna",
"savanna_plateau",
"small_end_islands",
"snowy_beach",
"snowy_plains",
"snowy_slopes",
"snowy_taiga",
"soul_sand_valley",
"sparse_jungle",
"stony_peaks",
"stony_shore",
"sunflower_plains",
"taiga",
"the_end",
"the_void",
"warm_ocean",
"warped_forest",
"windswept_forest",
"windswept_gravelly_hills",
"windswept_hills",
"windswept_savanna"
],
"color": 0
},
{
"keys": [
"cherry_grove"
],
"color": 11983713
},
{
"keys": [
"mangrove_swamp"
],
"color": 9285927
},
{
"keys": [
"pale_garden"
],
"color": 8883574
},
{
"keys": [
"swamp"
],
"color": 6975545
}
]
},
"water": {
"data": [
{
"keys": [
"badlands",
"bamboo_jungle",
"basalt_deltas",
"beach",
"birch_forest",
"crimson_forest",
"dark_forest",
"deep_dark",
"deep_ocean",
"desert",
"dripstone_caves",
"end_barrens",
"end_highlands",
"end_midlands",
"eroded_badlands",
"flower_forest",
"forest",
"frozen_peaks",
"grove",
"ice_spikes",
"jagged_peaks",
"jungle",
"lush_caves",
"mushroom_fields",
"nether_wastes",
"ocean",
"old_growth_birch_forest",
"old_growth_pine_taiga",
"old_growth_spruce_taiga",
"plains",
"river",
"savanna",
"savanna_plateau",
"small_end_islands",
"snowy_plains",
"snowy_slopes",
"soul_sand_valley",
"sparse_jungle",
"stony_peaks",
"stony_shore",
"sunflower_plains",
"taiga",
"the_end",
"the_void",
"warped_forest",
"windswept_forest",
"windswept_gravelly_hills",
"windswept_hills",
"windswept_savanna",
"wooded_badlands"
],
"color": 4159204
},
{
"keys": [
"cherry_grove"
],
"color": 6141935
},
{
"keys": [
"cold_ocean",
"deep_cold_ocean",
"snowy_beach",
"snowy_taiga"
],
"color": 4020182
},
{
"keys": [
"deep_frozen_ocean",
"frozen_ocean",
"frozen_river"
],
"color": 3750089
},
{
"keys": [
"deep_lukewarm_ocean",
"lukewarm_ocean"
],
"color": 4566514
},
{
"keys": [
"mangrove_swamp"
],
"color": 3832426
},
{
"keys": [
"meadow"
],
"color": 937679
},
{
"keys": [
"pale_garden"
],
"color": 7768221
},
{
"keys": [
"swamp"
],
"color": 6388580
},
{
"keys": [
"warm_ocean"
],
"color": 4445678
}
]
},
"redstone": {
"data": [
{
"keys": [
0
],
"color": 4980736
},
{
"keys": [
1
],
"color": 7340032
},
{
"keys": [
2
],
"color": 7995392
},
{
"keys": [
3
],
"color": 8650752
},
{
"keys": [
4
],
"color": 9306112
},
{
"keys": [
5
],
"color": 10027008
},
{
"keys": [
6
],
"color": 10682368
},
{
"keys": [
7
],
"color": 11337728
},
{
"keys": [
8
],
"color": 11993088
},
{
"keys": [
9
],
"color": 12648448
},
{
"keys": [
10
],
"color": 13369344
},
{
"keys": [
11
],
"color": 14024704
},
{
"keys": [
12
],
"color": 14680064
},
{
"keys": [
13
],
"color": 15336960
},
{
"keys": [
14
],
"color": 15997696
},
{
"keys": [
15
],
"color": 16724480
}
]
},
"constant": {
"data": [
{
"keys": [
"birch_leaves"
],
"color": -8345771
},
{
"keys": [
"spruce_leaves"
],
"color": -10380959
},
{
"keys": [
"lily_pad"
],
"color": -14647248
},
{
"keys": [
"attached_melon_stem"
],
"color": -2046180
},
{
"keys": [
"attached_pumpkin_stem"
],
"color": -2046180
},
{
"keys": [
"melon_stem"
],
"color": -16711936
},
{
"keys": [
"pumpkin_stem"
],
"color": -16711936
}
]
}
}
@@ -0,0 +1,6 @@
{
"version": 772,
"minecraftVersion": "1.21.8",
"majorVersion": "1.21",
"releaseType": "release"
}
@@ -0,0 +1,247 @@
[
{
"name": "armor",
"resource": "minecraft:armor",
"min": 0.0,
"max": 30.0,
"default": 0.0
},
{
"name": "armorToughness",
"resource": "minecraft:armor_toughness",
"min": 0.0,
"max": 20.0,
"default": 0.0
},
{
"name": "attackDamage",
"resource": "minecraft:attack_damage",
"min": 0.0,
"max": 2048.0,
"default": 2.0
},
{
"name": "attackKnockback",
"resource": "minecraft:attack_knockback",
"min": 0.0,
"max": 5.0,
"default": 0.0
},
{
"name": "attackSpeed",
"resource": "minecraft:attack_speed",
"min": 0.0,
"max": 1024.0,
"default": 4.0
},
{
"name": "blockBreakSpeed",
"resource": "minecraft:block_break_speed",
"min": 0.0,
"max": 1024.0,
"default": 1.0
},
{
"name": "blockInteractionRange",
"resource": "minecraft:block_interaction_range",
"min": 0.0,
"max": 64.0,
"default": 4.5
},
{
"name": "burningTime",
"resource": "minecraft:burning_time",
"min": 0.0,
"max": 1024.0,
"default": 1.0
},
{
"name": "cameraDistance",
"resource": "minecraft:camera_distance",
"min": 0.0,
"max": 32.0,
"default": 4.0
},
{
"name": "explosionKnockbackResistance",
"resource": "minecraft:explosion_knockback_resistance",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "entityInteractionRange",
"resource": "minecraft:entity_interaction_range",
"min": 0.0,
"max": 64.0,
"default": 3.0
},
{
"name": "fallDamageMultiplier",
"resource": "minecraft:fall_damage_multiplier",
"min": 0.0,
"max": 100.0,
"default": 1.0
},
{
"name": "flyingSpeed",
"resource": "minecraft:flying_speed",
"min": 0.0,
"max": 1024.0,
"default": 0.4
},
{
"name": "followRange",
"resource": "minecraft:follow_range",
"min": 0.0,
"max": 2048.0,
"default": 32.0
},
{
"name": "gravity",
"resource": "minecraft:gravity",
"min": -1.0,
"max": 1.0,
"default": 0.08
},
{
"name": "jumpStrength",
"resource": "minecraft:jump_strength",
"min": 0.0,
"max": 32.0,
"default": 0.41999998688697815
},
{
"name": "knockbackResistance",
"resource": "minecraft:knockback_resistance",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "luck",
"resource": "minecraft:luck",
"min": -1024.0,
"max": 1024.0,
"default": 0.0
},
{
"name": "maxAbsorption",
"resource": "minecraft:max_absorption",
"min": 0.0,
"max": 2048.0,
"default": 0.0
},
{
"name": "maxHealth",
"resource": "minecraft:max_health",
"min": 1.0,
"max": 1024.0,
"default": 20.0
},
{
"name": "miningEfficiency",
"resource": "minecraft:mining_efficiency",
"min": 0.0,
"max": 1024.0,
"default": 0.0
},
{
"name": "movementEfficiency",
"resource": "minecraft:movement_efficiency",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "movementSpeed",
"resource": "minecraft:movement_speed",
"min": 0.0,
"max": 1024.0,
"default": 0.7
},
{
"name": "oxygenBonus",
"resource": "minecraft:oxygen_bonus",
"min": 0.0,
"max": 1024.0,
"default": 0.0
},
{
"name": "safeFallDistance",
"resource": "minecraft:safe_fall_distance",
"min": -1024.0,
"max": 1024.0,
"default": 3.0
},
{
"name": "scale",
"resource": "minecraft:scale",
"min": 0.0625,
"max": 16.0,
"default": 1.0
},
{
"name": "sneakingSpeed",
"resource": "minecraft:sneaking_speed",
"min": 0.0,
"max": 1.0,
"default": 0.3
},
{
"name": "spawnReinforcements",
"resource": "minecraft:spawn_reinforcements",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "stepHeight",
"resource": "minecraft:step_height",
"min": 0.0,
"max": 10.0,
"default": 0.6
},
{
"name": "submergedMiningSpeed",
"resource": "minecraft:submerged_mining_speed",
"min": 0.0,
"max": 20.0,
"default": 0.2
},
{
"name": "sweepingDamageRatio",
"resource": "minecraft:sweeping_damage_ratio",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "temptRange",
"resource": "minecraft:tempt_range",
"min": 0.0,
"max": 2048.0,
"default": 10.0
},
{
"name": "waterMovementEfficiency",
"resource": "minecraft:water_movement_efficiency",
"min": 0.0,
"max": 1.0,
"default": 0.0
},
{
"name": "waypointTransmitRange",
"resource": "minecraft:waypoint_transmit_range",
"min": 0.0,
"max": 6.0E7,
"default": 0.0
},
{
"name": "waypointReceiveRange",
"resource": "minecraft:waypoint_receive_range",
"min": 0.0,
"max": 6.0E7,
"default": 0.0
}
]
+652
View File
@@ -0,0 +1,652 @@
[
{
"id": 0,
"name": "badlands",
"category": "mesa",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Badlands",
"color": 7254527
},
{
"id": 1,
"name": "bamboo_jungle",
"category": "jungle",
"temperature": 0.95,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Bamboo Jungle",
"color": 7842047
},
{
"id": 2,
"name": "basalt_deltas",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Basalt Deltas",
"color": 7254527
},
{
"id": 3,
"name": "beach",
"category": "beach",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Beach",
"color": 7907327
},
{
"id": 4,
"name": "birch_forest",
"category": "forest",
"temperature": 0.6,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Birch Forest",
"color": 8037887
},
{
"id": 5,
"name": "cherry_grove",
"category": "forest",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Cherry Grove",
"color": 8103167
},
{
"id": 6,
"name": "cold_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Cold Ocean",
"color": 8103167
},
{
"id": 7,
"name": "crimson_forest",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Crimson Forest",
"color": 7254527
},
{
"id": 8,
"name": "dark_forest",
"category": "forest",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Dark Forest",
"color": 7972607
},
{
"id": 9,
"name": "deep_cold_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Cold Ocean",
"color": 8103167
},
{
"id": 10,
"name": "deep_dark",
"category": "underground",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Dark",
"color": 7907327
},
{
"id": 11,
"name": "deep_frozen_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Frozen Ocean",
"color": 8103167
},
{
"id": 12,
"name": "deep_lukewarm_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Lukewarm Ocean",
"color": 8103167
},
{
"id": 13,
"name": "deep_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Deep Ocean",
"color": 8103167
},
{
"id": 14,
"name": "desert",
"category": "desert",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Desert",
"color": 7254527
},
{
"id": 15,
"name": "dripstone_caves",
"category": "underground",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Dripstone Caves",
"color": 7907327
},
{
"id": 16,
"name": "end_barrens",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "End Barrens",
"color": 0
},
{
"id": 17,
"name": "end_highlands",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "End Highlands",
"color": 0
},
{
"id": 18,
"name": "end_midlands",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "End Midlands",
"color": 0
},
{
"id": 19,
"name": "eroded_badlands",
"category": "mesa",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Eroded Badlands",
"color": 7254527
},
{
"id": 20,
"name": "flower_forest",
"category": "forest",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Flower Forest",
"color": 7972607
},
{
"id": 21,
"name": "forest",
"category": "forest",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Forest",
"color": 7972607
},
{
"id": 22,
"name": "frozen_ocean",
"category": "ocean",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Frozen Ocean",
"color": 8364543
},
{
"id": 23,
"name": "frozen_peaks",
"category": "ice",
"temperature": -0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Frozen Peaks",
"color": 8756735
},
{
"id": 24,
"name": "frozen_river",
"category": "ice",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Frozen River",
"color": 8364543
},
{
"id": 25,
"name": "grove",
"category": "forest",
"temperature": -0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Grove",
"color": 8495359
},
{
"id": 26,
"name": "ice_spikes",
"category": "ice",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Ice Spikes",
"color": 8364543
},
{
"id": 27,
"name": "jagged_peaks",
"category": "mountain",
"temperature": -0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Jagged Peaks",
"color": 8756735
},
{
"id": 28,
"name": "jungle",
"category": "jungle",
"temperature": 0.95,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Jungle",
"color": 7842047
},
{
"id": 29,
"name": "lukewarm_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Lukewarm Ocean",
"color": 8103167
},
{
"id": 30,
"name": "lush_caves",
"category": "underground",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Lush Caves",
"color": 8103167
},
{
"id": 31,
"name": "mangrove_swamp",
"category": "forest",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Mangrove Swamp",
"color": 7907327
},
{
"id": 32,
"name": "meadow",
"category": "mountain",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Meadow",
"color": 8103167
},
{
"id": 33,
"name": "mushroom_fields",
"category": "mushroom",
"temperature": 0.9,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Mushroom Fields",
"color": 7842047
},
{
"id": 34,
"name": "nether_wastes",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Nether Wastes",
"color": 7254527
},
{
"id": 35,
"name": "ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Ocean",
"color": 8103167
},
{
"id": 36,
"name": "old_growth_birch_forest",
"category": "forest",
"temperature": 0.6,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Old Growth Birch Forest",
"color": 8037887
},
{
"id": 37,
"name": "old_growth_pine_taiga",
"category": "taiga",
"temperature": 0.3,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Old Growth Pine Taiga",
"color": 8168447
},
{
"id": 38,
"name": "old_growth_spruce_taiga",
"category": "taiga",
"temperature": 0.25,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Old Growth Spruce Taiga",
"color": 8233983
},
{
"id": 39,
"name": "pale_garden",
"category": "none",
"temperature": 0.7,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Pale Garden",
"color": 12171705
},
{
"id": 40,
"name": "plains",
"category": "plains",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Plains",
"color": 7907327
},
{
"id": 41,
"name": "river",
"category": "river",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "River",
"color": 8103167
},
{
"id": 42,
"name": "savanna",
"category": "savanna",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Savanna",
"color": 7254527
},
{
"id": 43,
"name": "savanna_plateau",
"category": "savanna",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Savanna Plateau",
"color": 7254527
},
{
"id": 44,
"name": "small_end_islands",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "Small End Islands",
"color": 0
},
{
"id": 45,
"name": "snowy_beach",
"category": "beach",
"temperature": 0.05,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Beach",
"color": 8364543
},
{
"id": 46,
"name": "snowy_plains",
"category": "plains",
"temperature": 0.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Plains",
"color": 8364543
},
{
"id": 47,
"name": "snowy_slopes",
"category": "mountain",
"temperature": -0.3,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Slopes",
"color": 8560639
},
{
"id": 48,
"name": "snowy_taiga",
"category": "taiga",
"temperature": -0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Snowy Taiga",
"color": 8625919
},
{
"id": 49,
"name": "soul_sand_valley",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Soul Sand Valley",
"color": 7254527
},
{
"id": 50,
"name": "sparse_jungle",
"category": "jungle",
"temperature": 0.95,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Sparse Jungle",
"color": 7842047
},
{
"id": 51,
"name": "stony_peaks",
"category": "mountain",
"temperature": 1.0,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Stony Peaks",
"color": 7776511
},
{
"id": 52,
"name": "stony_shore",
"category": "beach",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Stony Shore",
"color": 8233727
},
{
"id": 53,
"name": "sunflower_plains",
"category": "plains",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Sunflower Plains",
"color": 7907327
},
{
"id": 54,
"name": "swamp",
"category": "swamp",
"temperature": 0.8,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Swamp",
"color": 7907327
},
{
"id": 55,
"name": "taiga",
"category": "taiga",
"temperature": 0.25,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Taiga",
"color": 8233983
},
{
"id": 56,
"name": "the_end",
"category": "the_end",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "end",
"displayName": "The End",
"color": 0
},
{
"id": 57,
"name": "the_void",
"category": "none",
"temperature": 0.5,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "The Void",
"color": 8103167
},
{
"id": 58,
"name": "warm_ocean",
"category": "ocean",
"temperature": 0.5,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Warm Ocean",
"color": 8103167
},
{
"id": 59,
"name": "warped_forest",
"category": "nether",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "nether",
"displayName": "Warped Forest",
"color": 7254527
},
{
"id": 60,
"name": "windswept_forest",
"category": "forest",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Windswept Forest",
"color": 8233727
},
{
"id": 61,
"name": "windswept_gravelly_hills",
"category": "extreme_hills",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Windswept Gravelly Hills",
"color": 8233727
},
{
"id": 62,
"name": "windswept_hills",
"category": "extreme_hills",
"temperature": 0.2,
"has_precipitation": true,
"dimension": "overworld",
"displayName": "Windswept Hills",
"color": 8233727
},
{
"id": 63,
"name": "windswept_savanna",
"category": "savanna",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Windswept Savanna",
"color": 7254527
},
{
"id": 64,
"name": "wooded_badlands",
"category": "mesa",
"temperature": 2.0,
"has_precipitation": false,
"dimension": "overworld",
"displayName": "Wooded Badlands",
"color": 7254527
}
]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+236
View File
@@ -0,0 +1,236 @@
[
{
"id": 0,
"name": "Speed",
"displayName": "Speed",
"type": "good"
},
{
"id": 1,
"name": "Slowness",
"displayName": "Slowness",
"type": "bad"
},
{
"id": 2,
"name": "Haste",
"displayName": "Haste",
"type": "good"
},
{
"id": 3,
"name": "MiningFatigue",
"displayName": "Mining Fatigue",
"type": "bad"
},
{
"id": 4,
"name": "Strength",
"displayName": "Strength",
"type": "good"
},
{
"id": 5,
"name": "InstantHealth",
"displayName": "Instant Health",
"type": "good"
},
{
"id": 6,
"name": "InstantDamage",
"displayName": "Instant Damage",
"type": "bad"
},
{
"id": 7,
"name": "JumpBoost",
"displayName": "Jump Boost",
"type": "good"
},
{
"id": 8,
"name": "Nausea",
"displayName": "Nausea",
"type": "bad"
},
{
"id": 9,
"name": "Regeneration",
"displayName": "Regeneration",
"type": "good"
},
{
"id": 10,
"name": "Resistance",
"displayName": "Resistance",
"type": "good"
},
{
"id": 11,
"name": "FireResistance",
"displayName": "Fire Resistance",
"type": "good"
},
{
"id": 12,
"name": "WaterBreathing",
"displayName": "Water Breathing",
"type": "good"
},
{
"id": 13,
"name": "Invisibility",
"displayName": "Invisibility",
"type": "good"
},
{
"id": 14,
"name": "Blindness",
"displayName": "Blindness",
"type": "bad"
},
{
"id": 15,
"name": "NightVision",
"displayName": "Night Vision",
"type": "good"
},
{
"id": 16,
"name": "Hunger",
"displayName": "Hunger",
"type": "bad"
},
{
"id": 17,
"name": "Weakness",
"displayName": "Weakness",
"type": "bad"
},
{
"id": 18,
"name": "Poison",
"displayName": "Poison",
"type": "bad"
},
{
"id": 19,
"name": "Wither",
"displayName": "Wither",
"type": "bad"
},
{
"id": 20,
"name": "HealthBoost",
"displayName": "Health Boost",
"type": "good"
},
{
"id": 21,
"name": "Absorption",
"displayName": "Absorption",
"type": "good"
},
{
"id": 22,
"name": "Saturation",
"displayName": "Saturation",
"type": "good"
},
{
"id": 23,
"name": "Glowing",
"displayName": "Glowing",
"type": "bad"
},
{
"id": 24,
"name": "Levitation",
"displayName": "Levitation",
"type": "bad"
},
{
"id": 25,
"name": "Luck",
"displayName": "Luck",
"type": "good"
},
{
"id": 26,
"name": "BadLuck",
"displayName": "Bad Luck",
"type": "bad"
},
{
"id": 27,
"name": "SlowFalling",
"displayName": "Slow Falling",
"type": "good"
},
{
"id": 28,
"name": "ConduitPower",
"displayName": "Conduit Power",
"type": "good"
},
{
"id": 29,
"name": "DolphinsGrace",
"displayName": "Dolphin's Grace",
"type": "good"
},
{
"id": 30,
"name": "BadOmen",
"displayName": "Bad Omen",
"type": "bad"
},
{
"id": 31,
"name": "HeroOfTheVillage",
"displayName": "Hero of the Village",
"type": "good"
},
{
"id": 32,
"name": "Darkness",
"displayName": "Darkness",
"type": "bad"
},
{
"id": 33,
"name": "TrialOmen",
"displayName": "Trial Omen",
"type": "bad"
},
{
"id": 34,
"name": "RaidOmen",
"displayName": "Raid Omen",
"type": "bad"
},
{
"id": 35,
"name": "WindCharged",
"displayName": "Wind Charged",
"type": "bad"
},
{
"id": 36,
"name": "Weaving",
"displayName": "Weaving",
"type": "bad"
},
{
"id": 37,
"name": "Oozing",
"displayName": "Oozing",
"type": "bad"
},
{
"id": 38,
"name": "Infested",
"displayName": "Infested",
"type": "bad"
}
]
@@ -0,0 +1,959 @@
[
{
"id": 0,
"name": "aqua_affinity",
"displayName": "Aqua Affinity",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "head_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 1,
"name": "bane_of_arthropods",
"displayName": "Bane of Arthropods",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"breach",
"density",
"impaling",
"sharpness",
"smite"
],
"category": "weapon",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 2,
"name": "binding_curse",
"displayName": "Curse of Binding",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": true,
"curse": true,
"exclude": [],
"category": "equippable",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 3,
"name": "blast_protection",
"displayName": "Blast Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"fire_protection",
"projectile_protection",
"protection"
],
"category": "armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 4,
"name": "breach",
"displayName": "Breach",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"density",
"impaling",
"sharpness",
"smite"
],
"category": "mace",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 5,
"name": "channeling",
"displayName": "Channeling",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"riptide"
],
"category": "trident",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 6,
"name": "density",
"displayName": "Density",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"impaling",
"sharpness",
"smite"
],
"category": "mace",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 7,
"name": "depth_strider",
"displayName": "Depth Strider",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"frost_walker"
],
"category": "foot_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 8,
"name": "efficiency",
"displayName": "Efficiency",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "mining",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 9,
"name": "feather_falling",
"displayName": "Feather Falling",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "foot_armor",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 10,
"name": "fire_aspect",
"displayName": "Fire Aspect",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "fire_aspect",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 11,
"name": "fire_protection",
"displayName": "Fire Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"blast_protection",
"projectile_protection",
"protection"
],
"category": "armor",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 12,
"name": "flame",
"displayName": "Flame",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "bow",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 13,
"name": "fortune",
"displayName": "Fortune",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"silk_touch"
],
"category": "mining_loot",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 14,
"name": "frost_walker",
"displayName": "Frost Walker",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [
"depth_strider"
],
"category": "foot_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 15,
"name": "impaling",
"displayName": "Impaling",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"density",
"sharpness",
"smite"
],
"category": "trident",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 16,
"name": "infinity",
"displayName": "Infinity",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"mending"
],
"category": "bow",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 17,
"name": "knockback",
"displayName": "Knockback",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "sword",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 18,
"name": "looting",
"displayName": "Looting",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "sword",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 19,
"name": "loyalty",
"displayName": "Loyalty",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"riptide"
],
"category": "trident",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 20,
"name": "luck_of_the_sea",
"displayName": "Luck of the Sea",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "fishing",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 21,
"name": "lure",
"displayName": "Lure",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "fishing",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 22,
"name": "mending",
"displayName": "Mending",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [
"infinity"
],
"category": "durability",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 23,
"name": "multishot",
"displayName": "Multishot",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"piercing"
],
"category": "crossbow",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 24,
"name": "piercing",
"displayName": "Piercing",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"multishot"
],
"category": "crossbow",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 25,
"name": "power",
"displayName": "Power",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "bow",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 26,
"name": "projectile_protection",
"displayName": "Projectile Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"blast_protection",
"fire_protection",
"protection"
],
"category": "armor",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 27,
"name": "protection",
"displayName": "Protection",
"maxLevel": 4,
"minCost": {
"a": 3,
"b": 1
},
"maxCost": {
"a": 3,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"blast_protection",
"fire_protection",
"projectile_protection"
],
"category": "armor",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 28,
"name": "punch",
"displayName": "Punch",
"maxLevel": 2,
"minCost": {
"a": 1,
"b": 1
},
"maxCost": {
"a": 1,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "bow",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 29,
"name": "quick_charge",
"displayName": "Quick Charge",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "crossbow",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 30,
"name": "respiration",
"displayName": "Respiration",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "head_armor",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 31,
"name": "riptide",
"displayName": "Riptide",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"channeling",
"loyalty"
],
"category": "trident",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 32,
"name": "sharpness",
"displayName": "Sharpness",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"density",
"impaling",
"smite"
],
"category": "sharp_weapon",
"weight": 10,
"tradeable": true,
"discoverable": true
},
{
"id": 33,
"name": "silk_touch",
"displayName": "Silk Touch",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"fortune"
],
"category": "mining_loot",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 34,
"name": "smite",
"displayName": "Smite",
"maxLevel": 5,
"minCost": {
"a": 4,
"b": 1
},
"maxCost": {
"a": 4,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [
"bane_of_arthropods",
"breach",
"density",
"impaling",
"sharpness"
],
"category": "weapon",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 35,
"name": "soul_speed",
"displayName": "Soul Speed",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [],
"category": "foot_armor",
"weight": 1,
"tradeable": false,
"discoverable": false
},
{
"id": 36,
"name": "sweeping_edge",
"displayName": "Sweeping Edge",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "sword",
"weight": 2,
"tradeable": true,
"discoverable": true
},
{
"id": 37,
"name": "swift_sneak",
"displayName": "Swift Sneak",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [],
"category": "leg_armor",
"weight": 1,
"tradeable": false,
"discoverable": false
},
{
"id": 38,
"name": "thorns",
"displayName": "Thorns",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "armor",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 39,
"name": "unbreaking",
"displayName": "Unbreaking",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": false,
"curse": false,
"exclude": [],
"category": "durability",
"weight": 5,
"tradeable": true,
"discoverable": true
},
{
"id": 40,
"name": "vanishing_curse",
"displayName": "Curse of Vanishing",
"maxLevel": 1,
"minCost": {
"a": 0,
"b": 1
},
"maxCost": {
"a": 0,
"b": 1
},
"treasureOnly": true,
"curse": true,
"exclude": [],
"category": "vanishing",
"weight": 1,
"tradeable": true,
"discoverable": true
},
{
"id": 41,
"name": "wind_burst",
"displayName": "Wind Burst",
"maxLevel": 3,
"minCost": {
"a": 2,
"b": 1
},
"maxCost": {
"a": 2,
"b": 1
},
"treasureOnly": true,
"curse": false,
"exclude": [],
"category": "mace",
"weight": 2,
"tradeable": false,
"discoverable": false
}
]
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More