43 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
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
272 changed files with 50001 additions and 861 deletions
+4
View File
@@ -1,2 +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
+9 -2
View File
@@ -14,15 +14,22 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Checkout with LFS
uses: actions/checkout@v4
with:
lfs: true
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.25'
go-version: '1.26.2'
- name: Build
run: go build -v ./...
- name: Vet
run: go vet -v ./...
- name: Test
run: go test -v ./...
+5 -7
View File
@@ -13,8 +13,10 @@ import (
"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"
)
@@ -36,6 +38,7 @@ func Version(args []string) (err error) {
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,
@@ -43,6 +46,7 @@ var subcommands = map[string]func(args []string) error{
"version": Version,
"extract-mca": extract_mca.Run,
"data": data.Run,
"print-replay": print_replay.Run,
}
func Help(args []string) (err error) {
@@ -53,15 +57,9 @@ func Help(args []string) (err error) {
}
func mainE() (err error) {
subcommands["help"] = Help // this is here because if it isn't tools/cli/main.go:17:5: initialization cycle for subcommands
// tools/cli/main.go:17:5: subcommands refers to Help
// tools/cli/main.go:22:6: Help refers to subcommands
subcommands["help"] = Help
args := os.Args
// Debug stuff
slog.SetLogLoggerLevel(slog.LevelDebug)
//args = []string{"TEST", "version"}
if len(args) < 2 {
err = ExpectedASubcommandErr
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"
}
}
@@ -4,13 +4,13 @@ import (
"bytes"
"testing"
"github.com/admin-else/strom/proto_generated/v1_21_8"
generated "github.com/admin-else/strom/proto_generated/%v"
)
// Error: %v
func TestFailedPacket%10X(t *testing.T) {
p := v1_21_8.Play%vPacket{}
b := bytes.NewBuffer(%#v)
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
+4
View File
@@ -28,6 +28,7 @@ package crypto
import (
"crypto/cipher"
"crypto/subtle"
"sync"
"unsafe"
)
@@ -37,6 +38,7 @@ type CFB8 struct {
ivPos int
iv []byte
de bool
mutex sync.Mutex
}
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) {
cf.mutex.Lock()
defer cf.mutex.Unlock()
if len(src) == 0 {
return
}
+22 -2
View File
@@ -2,7 +2,10 @@ package data
import (
"errors"
"slices"
"strconv"
"github.com/admin-else/strom/util"
)
// {
@@ -48,6 +51,7 @@ type Block struct {
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
}
@@ -63,6 +67,20 @@ func BlocksForVersion(v string) (ret []*Block) {
var b []*Block
must(LoadVersionedJson(v, "blocks", &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
}
@@ -104,7 +122,9 @@ func StateIdFromBlocKAndStateMap(version string, name string, stateMap map[strin
} else {
stateId, err = b.IdFromStateMap(stateMap)
}
if b.MinStateId > stateId || b.MaxStateId < stateId {
err = BlockStateOutOfRangeErr
}
return
}
@@ -153,7 +173,7 @@ func mcDataBlockStateTypeSerialize(v string, s *BlockState) (n int32, err error)
}
n1, errMabye := strconv.Atoi(v)
if errMabye == nil {
return int32(n1), nil
return int32(n1) - s.MinValue, nil
}
for i, enumValue := range s.Values {
if enumValue == v {
+8
View File
@@ -32,3 +32,11 @@ func TestBlockStates(t *testing.T) {
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)
}
+3
View File
@@ -240,6 +240,9 @@ func NewLoop() (l *Loop) {
}
func NewLoopCtx(ctx context.Context) (l *Loop) {
if ctx == nil {
ctx = context.Background()
}
l = &Loop{}
l.Ctx, l.Cancel = context.WithCancel(ctx)
l.HandlerFunctions = make(map[reflect.Type][]reflect.Value)
+2 -2
View File
@@ -1,9 +1,9 @@
module github.com/admin-else/strom
go 1.25
go 1.26.2
require (
github.com/go-viper/mapstructure/v2 v2.4.0
github.com/go-viper/mapstructure/v2 v2.4.0 // FIXME: this should be replaced with my version
github.com/google/go-cmp v0.7.0
github.com/google/uuid v1.6.0
)
+43 -14
View File
@@ -22,6 +22,7 @@ const McPrefix = "minecraft:"
func (c Chunk) ToStorage(version string) (toChunk *level.Chunk, err error) {
f := level.MakeBlockFormat(version)
toChunk = new(level.Chunk)
toChunk.Version = version
toChunk.Sections = make([]level.Section, len(c.Sections))
for i, s := range c.Sections {
@@ -33,15 +34,30 @@ func (c Chunk) ToStorage(version string) (toChunk *level.Chunk, err error) {
}
}
// this is probably fine
uintSlice := unsafe.Slice((*uint64)(unsafe.Pointer(unsafe.SliceData(s.BlockStates.Data))), len(s.BlockStates.Data))
toChunk.Sections[i].Blocks, err = f.Import(uintSlice, util.BpeByNum(float64(len(s.BlockStates.Palette))), pallete)
if err != nil {
return
if s.BlockStates.Data != nil {
uintSlice := unsafe.Slice((*uint64)(unsafe.Pointer(unsafe.SliceData(s.BlockStates.Data))), len(s.BlockStates.Data))
bpe := util.BpeByNum(float64(len(s.BlockStates.Palette)))
toChunk.Sections[i].Blocks, err = f.Import(uintSlice, bpe, pallete)
if err != nil {
return
}
toChunk.Sections[i].BlockCount = int16(level.BlocksPerChunkSection - level.CountStorage(toChunk.Sections[i].Blocks, 0))
} else {
var fillerId = int32(0)
if len(pallete) == 1 {
fillerId = pallete[0]
if fillerId != 0 {
toChunk.Sections[i].BlockCount = level.BlocksPerChunkSection
}
}
toChunk.Sections[i].Blocks, err = f.FullWith(fillerId)
if err != nil {
return
}
}
toChunk.Sections[i].BlockCount = int16(level.CountStorage(toChunk.Sections[i].Blocks, 0))
}
f = level.MakeBiomeFormat(version)
for i, s := range c.Sections {
pallete := make([]int32, len(s.Biomes.Palette))
for j, p := range s.Biomes.Palette {
@@ -53,12 +69,25 @@ func (c Chunk) ToStorage(version string) (toChunk *level.Chunk, err error) {
}
pallete[j] = b.Id
}
// this is probably fine
uintSlice := unsafe.Slice((*uint64)(unsafe.Pointer(unsafe.SliceData(s.Biomes.Data))), len(s.Biomes.Data))
toChunk.Sections[i].Biomes, err = f.Import(uintSlice, util.BpeByNum(float64(len(pallete))), pallete)
if err != nil {
return
if s.Biomes.Data != nil {
// this is probably fine
uintSlice := unsafe.Slice((*uint64)(unsafe.Pointer(unsafe.SliceData(s.Biomes.Data))), len(s.Biomes.Data))
bpe := util.BpeByNum(float64(len(pallete)))
toChunk.Sections[i].Biomes, err = f.Import(uintSlice, bpe, pallete)
if err != nil {
return
}
} else {
var fillerId = int32(0)
if len(pallete) == 1 {
fillerId = pallete[0]
}
toChunk.Sections[i].Biomes, err = f.FullWith(fillerId)
if err != nil {
return
}
}
}
return
@@ -70,11 +99,11 @@ type Section struct {
Data []int64 `nbt:"data,omitempty"`
Palette []struct {
Name string
Properties map[string]string `nbt:"properties,omitempty"`
Properties map[string]string `nbt:"Properties,omitempty"`
}
}
} `nbt:"block_states,omitempty"`
Biomes struct {
Data []int64 `nbt:"data,omitempty"`
Palette []string
}
} `nbt:"biomes,omitempty"`
}
+6 -7
View File
@@ -1,11 +1,13 @@
package anvil_test
import (
"bytes"
"encoding/json"
"fmt"
"os"
"testing"
"github.com/admin-else/strom/level"
"github.com/admin-else/strom/level/anvil"
"github.com/admin-else/strom/util"
)
@@ -44,11 +46,8 @@ func TestRegionFile(t *testing.T) {
fmt.Println("Chunk loaded successfully")
}
func TestConverToPacket(t *testing.T) {
f, err := os.Open("./level/anvil/testdata/r.0.0.mca")
if err != nil {
return
}
defer f.Close()
func loadPacketToChunk(b []byte) (chunk *level.Chunk, err error) {
buffer := bytes.NewBuffer(b)
chunk, err = level.ReadChunkFromChunkPacketData(buffer, "1.21.11", 384)
return
}
+5
View File
@@ -62,12 +62,17 @@ func ReadChunkHeader(r *os.File) (ch *ChunkHeader, err error) {
return
}
// ChunkAt returns the chunk at the given position, or nil if it is empty.
func (c *ChunkHeader) ChunkAt(f *os.File, x, z int32) (n *nbt.Tag, err error) {
if x < 0 || z < 0 || x >= ChunksWidthRegionFile || z >= ChunksWidthRegionFile {
err = fmt.Errorf("chunk out of bounds")
return
}
off, size := chunkLocation(c.Chunk[chunkXZtoIndex(x, z)])
if off == 0 {
return nil, nil
}
_, err = f.Seek(int64(off), 0)
if err != nil {
return
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,215 @@
{
"minecraft:recipes/building_blocks/polished_deepslate": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_tile_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_brick_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/combat/stone_sword": {
"criteria": {
"has_cobblestone": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_axe": {
"criteria": {
"has_cobblestone": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:story/mine_stone": {
"criteria": {
"get_stone": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/decorations/furnace": {
"criteria": {
"has_cobblestone": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/chiseled_deepslate_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/decorations/crafting_table": {
"criteria": {
"unlock_right_away": "2026-01-18 19:40:40 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_slab": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/decorations/cobbled_deepslate_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop_from_campfire_cooking": {
"criteria": {
"has_porkchop": "2026-01-18 19:40:40 +0100"
},
"done": true
},
"minecraft:recipes/decorations/cobbled_deepslate_wall": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/decorations/polished_deepslate_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/decorations/deepslate_brick_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop": {
"criteria": {
"has_porkchop": "2026-01-18 19:40:40 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_pickaxe": {
"criteria": {
"has_cobblestone": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_brick_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_tile_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/misc/charcoal": {
"criteria": {
"has_log": "2026-01-18 19:41:43 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_stairs": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/decorations/deepslate_tile_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/oak_planks": {
"criteria": {
"has_logs": "2026-01-18 19:41:43 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop_from_smoking": {
"criteria": {
"has_porkchop": "2026-01-18 19:40:40 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_bricks_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:adventure/adventuring_time": {
"criteria": {
"minecraft:forest": "2026-01-18 19:40:40 +0100",
"minecraft:deep_dark": "2026-01-18 19:41:56 +0100",
"minecraft:stony_shore": "2026-01-18 19:40:46 +0100"
},
"done": false
},
"minecraft:recipes/building_blocks/deepslate_tiles_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_hoe": {
"criteria": {
"has_cobblestone": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_shovel": {
"criteria": {
"has_cobblestone": "2026-01-18 19:41:36 +0100"
},
"done": true
},
"DataVersion": 4556
}
@@ -0,0 +1,17 @@
{
"minecraft:recipes/decorations/crafting_table": {
"criteria": {
"unlock_right_away": "2026-04-23 22:08:36 +0200"
},
"done": true
},
"minecraft:adventure/adventuring_time": {
"criteria": {
"minecraft:taiga": "2026-04-23 22:10:55 +0200",
"minecraft:grove": "2026-04-23 22:09:03 +0200",
"minecraft:stony_shore": "2026-04-23 22:08:37 +0200"
},
"done": false
},
"DataVersion": 4671
}
@@ -0,0 +1,17 @@
{
"minecraft:recipes/decorations/crafting_table": {
"criteria": {
"unlock_right_away": "2026-05-08 20:07:02 +0200"
},
"done": true
},
"minecraft:adventure/adventuring_time": {
"criteria": {
"minecraft:forest": "2026-05-08 20:07:06 +0200",
"minecraft:taiga": "2026-05-08 20:07:05 +0200",
"minecraft:grove": "2026-05-08 20:07:03 +0200"
},
"done": false
},
"DataVersion": 4671
}
@@ -0,0 +1,220 @@
{
"minecraft:recipes/building_blocks/polished_deepslate": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_tile_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_brick_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/combat/stone_sword": {
"criteria": {
"has_cobblestone": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_axe": {
"criteria": {
"has_cobblestone": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:story/mine_stone": {
"criteria": {
"get_stone": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/decorations/furnace": {
"criteria": {
"has_cobblestone": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/chiseled_deepslate_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/decorations/crafting_table": {
"criteria": {
"unlock_right_away": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_slab": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/decorations/cobbled_deepslate_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop_from_campfire_cooking": {
"criteria": {
"has_porkchop": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/decorations/cobbled_deepslate_wall": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/decorations/polished_deepslate_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/decorations/deepslate_brick_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop": {
"criteria": {
"has_porkchop": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_pickaxe": {
"criteria": {
"has_cobblestone": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_brick_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_tile_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/misc/charcoal": {
"criteria": {
"has_log": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_stairs": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/combat/stone_spear": {
"criteria": {
"has_cobblestone": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/decorations/deepslate_tile_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/oak_planks": {
"criteria": {
"has_logs": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop_from_smoking": {
"criteria": {
"has_porkchop": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_bricks_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:adventure/adventuring_time": {
"criteria": {
"minecraft:stony_shore": "2026-03-11 19:22:59 +0100",
"minecraft:plains": "2026-03-11 19:22:38 +0100"
},
"done": false
},
"minecraft:recipes/building_blocks/deepslate_tiles_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_hoe": {
"criteria": {
"has_cobblestone": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_shovel": {
"criteria": {
"has_cobblestone": "2026-03-11 19:22:37 +0100"
},
"done": true
},
"DataVersion": 4671
}
@@ -0,0 +1,222 @@
{
"minecraft:recipes/building_blocks/polished_deepslate": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_tile_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_brick_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/combat/stone_sword": {
"criteria": {
"has_cobblestone": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_axe": {
"criteria": {
"has_cobblestone": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:story/mine_stone": {
"criteria": {
"get_stone": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/decorations/furnace": {
"criteria": {
"has_cobblestone": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/chiseled_deepslate_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/decorations/crafting_table": {
"criteria": {
"unlock_right_away": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_slab": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/decorations/cobbled_deepslate_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop_from_campfire_cooking": {
"criteria": {
"has_porkchop": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/decorations/cobbled_deepslate_wall": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/decorations/polished_deepslate_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/decorations/deepslate_brick_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop": {
"criteria": {
"has_porkchop": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_pickaxe": {
"criteria": {
"has_cobblestone": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_brick_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_tile_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/misc/charcoal": {
"criteria": {
"has_log": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_stairs": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/combat/stone_spear": {
"criteria": {
"has_cobblestone": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/decorations/deepslate_tile_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/oak_planks": {
"criteria": {
"has_logs": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop_from_smoking": {
"criteria": {
"has_porkchop": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_bricks_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:adventure/adventuring_time": {
"criteria": {
"minecraft:forest": "2026-02-07 19:19:04 +0100",
"minecraft:river": "2026-02-07 19:20:26 +0100",
"minecraft:stony_shore": "2026-02-07 19:20:11 +0100",
"minecraft:plains": "2026-02-07 19:20:12 +0100"
},
"done": false
},
"minecraft:recipes/building_blocks/deepslate_tiles_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_hoe": {
"criteria": {
"has_cobblestone": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_shovel": {
"criteria": {
"has_cobblestone": "2026-02-07 19:19:03 +0100"
},
"done": true
},
"DataVersion": 4671
}
@@ -0,0 +1,119 @@
{
"minecraft:recipes/decorations/crafting_table": {
"criteria": {
"unlock_right_away": "2025-11-30 09:32:28 +0100"
},
"done": true
},
"minecraft:recipes/transportation/cherry_boat": {
"criteria": {
"in_water": "2025-11-30 10:05:13 +0100"
},
"done": true
},
"minecraft:adventure/kill_all_mobs": {
"criteria": {
"minecraft:zombie": "2025-11-30 10:06:33 +0100"
},
"done": false
},
"minecraft:recipes/food/cooked_porkchop_from_campfire_cooking": {
"criteria": {
"has_porkchop": "2025-11-30 10:06:57 +0100"
},
"done": true
},
"minecraft:recipes/transportation/bamboo_raft": {
"criteria": {
"in_water": "2025-11-30 10:05:13 +0100"
},
"done": true
},
"minecraft:recipes/transportation/spruce_boat": {
"criteria": {
"in_water": "2025-11-30 10:05:13 +0100"
},
"done": true
},
"minecraft:recipes/transportation/birch_boat": {
"criteria": {
"in_water": "2025-11-30 10:05:13 +0100"
},
"done": true
},
"minecraft:recipes/transportation/oak_boat": {
"criteria": {
"in_water": "2025-11-30 10:05:13 +0100"
},
"done": true
},
"minecraft:recipes/transportation/mangrove_boat": {
"criteria": {
"in_water": "2025-11-30 10:05:13 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop": {
"criteria": {
"has_porkchop": "2025-11-30 10:06:57 +0100"
},
"done": true
},
"minecraft:recipes/transportation/acacia_boat": {
"criteria": {
"in_water": "2025-11-30 10:05:13 +0100"
},
"done": true
},
"minecraft:adventure/root": {
"criteria": {
"killed_something": "2025-11-30 10:06:33 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop_from_smoking": {
"criteria": {
"has_porkchop": "2025-11-30 10:06:57 +0100"
},
"done": true
},
"minecraft:adventure/kill_a_mob": {
"criteria": {
"minecraft:zombie": "2025-11-30 10:06:33 +0100"
},
"done": true
},
"minecraft:recipes/transportation/pale_oak_boat": {
"criteria": {
"in_water": "2025-11-30 10:05:13 +0100"
},
"done": true
},
"minecraft:adventure/adventuring_time": {
"criteria": {
"minecraft:old_growth_birch_forest": "2025-11-30 10:03:58 +0100",
"minecraft:forest": "2025-11-30 10:04:40 +0100",
"minecraft:taiga": "2025-11-30 09:32:29 +0100",
"minecraft:deep_dark": "2025-11-30 10:05:12 +0100",
"minecraft:river": "2025-11-30 10:09:03 +0100",
"minecraft:grove": "2025-11-30 09:32:32 +0100",
"minecraft:meadow": "2025-11-30 09:32:44 +0100",
"minecraft:birch_forest": "2025-11-30 10:05:33 +0100",
"minecraft:frozen_peaks": "2025-11-30 09:32:55 +0100"
},
"done": false
},
"minecraft:recipes/transportation/jungle_boat": {
"criteria": {
"in_water": "2025-11-30 10:05:13 +0100"
},
"done": true
},
"minecraft:recipes/transportation/dark_oak_boat": {
"criteria": {
"in_water": "2025-11-30 10:05:13 +0100"
},
"done": true
},
"DataVersion": 4556
}
@@ -0,0 +1,220 @@
{
"minecraft:recipes/building_blocks/polished_deepslate": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_tile_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_brick_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/combat/stone_sword": {
"criteria": {
"has_cobblestone": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_axe": {
"criteria": {
"has_cobblestone": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:story/mine_stone": {
"criteria": {
"get_stone": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/decorations/furnace": {
"criteria": {
"has_cobblestone": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/chiseled_deepslate_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/decorations/crafting_table": {
"criteria": {
"unlock_right_away": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_slab": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/decorations/cobbled_deepslate_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop_from_campfire_cooking": {
"criteria": {
"has_porkchop": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/decorations/cobbled_deepslate_wall": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/decorations/polished_deepslate_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_stairs_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/decorations/deepslate_brick_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/polished_deepslate_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop": {
"criteria": {
"has_porkchop": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_pickaxe": {
"criteria": {
"has_cobblestone": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_brick_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_tile_slab_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/misc/charcoal": {
"criteria": {
"has_log": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/cobbled_deepslate_stairs": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/combat/stone_spear": {
"criteria": {
"has_cobblestone": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/decorations/deepslate_tile_wall_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/oak_planks": {
"criteria": {
"has_logs": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/food/cooked_porkchop_from_smoking": {
"criteria": {
"has_porkchop": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/building_blocks/deepslate_bricks_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:adventure/adventuring_time": {
"criteria": {
"minecraft:stony_shore": "2026-03-12 21:17:48 +0100",
"minecraft:plains": "2026-03-12 21:17:31 +0100"
},
"done": false
},
"minecraft:recipes/building_blocks/deepslate_tiles_from_cobbled_deepslate_stonecutting": {
"criteria": {
"has_cobbled_deepslate": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_hoe": {
"criteria": {
"has_cobblestone": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"minecraft:recipes/tools/stone_shovel": {
"criteria": {
"has_cobblestone": "2026-03-12 21:17:28 +0100"
},
"done": true
},
"DataVersion": 4671
}
@@ -0,0 +1 @@
https://github.com/cabaletta/baritone
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fc0958e0912637fd74710a15fe7f1272f3cd2af3bcce3c23fed19736388c00ad
size 753664
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:26d5f8cd8bd1c860416914bc4c02d0b70607656beba85dba2263e0e79a06e7b8
size 348160
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:28c10367fb1e46056999833e17d07551e5bf76dd913551e09f8d43595a2b3fb2
size 12288
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:19a35fe09fba69dfe85874a548d28b77c4c70664e338530b9f3f08f24ad4abba
size 598016
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:30adf5f8dec1ff527794b72ec7f6e647b5501c851dc988210daf354b6d56f03b
size 143360
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:65c4290f6e9cc93cf73a91a47437484b94d014a0b9ad648d896c12674faf1f10
size 405504
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c68c40572cb6667a818d6982a1c2cd40f95c3ab25551b7d70fbc35cb0146ee12
size 290816
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2c6387f0f76c625bf167373094a7628efad713158de30bb2bdfc06ad4f44acab
size 192512
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:34a1d263910364f6bd0173e0ec96e8f45a0a5c2c74e4c5a3e771612685376d34
size 77824
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:490e215ae40f8928646cfd09e2ccbed852e9a0b43a48234a5e8d5a8e01b56a1a
size 32768
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:870c2d34a6e041f46786167f5c077ce515d0daa616242d4a8065861e376aaf54
size 24576
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7473ac38f9943d9e1ed907faa2997d2833c29f326bd9829f7d0dc49b77797486
size 724992
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:adba24770ab0983249c2b327fa9ae675107a34549651d870c5d0011ea8cbcabc
size 294912
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:29fb706bffac7f1fb93f0fc62c201fdb1a0ca939fb53807362337f1ea2609737
size 16384
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a870e120e4932cbfe231c85e1ca04b7e0dc455b3e4da331b8f3e0baf6c17946f
size 344064
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c73b7ec1f3e7699e430da25bf72f570aa9c84d88dc8c21908ea6b2293c8c213a
size 98304
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4fffbd92fa6e7e271a8643b8ee0711d3fc2ebafe4b2de0b642277474778d0122
size 225280
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:048a09900055de40df61eee3fda1e65e68e438c32548c1e4bbcc1ef58568a176
size 184320
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e6e9f552d4732adc2c255b1f2cdb1d6f45f8cfceacda8bfdda613dda822f2fe3
size 16384
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a63b81662448a67d649465a56862a5ffd9af86499d7807653f865ff6606cf504
size 163840
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

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