Skip to content

Commit

Permalink
dragonfly/server: Make block hashes more dynamic to avoid registry co…
Browse files Browse the repository at this point in the history
…llisions (#918)
  • Loading branch information
TwistedAsylumMC authored Sep 6, 2024
1 parent e99ffb8 commit 42801f6
Show file tree
Hide file tree
Showing 6 changed files with 451 additions and 573 deletions.
45 changes: 26 additions & 19 deletions cmd/blockhash/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"golang.org/x/tools/go/packages"
"io"
"log"
"math/bits"
"os"
"sort"
"strconv"
Expand Down Expand Up @@ -54,14 +53,14 @@ func procPackage(pkg *packages.Package, w io.Writer) {
b.sortNames()

b.writePackage(w)
i := b.writeConstants(w)
b.writeConstants(w)
b.writeNextHash(w)
b.writeMethods(w, i)
b.writeMethods(w)
}

var (
packageFormat = "// Code generated by cmd/blockhash; DO NOT EDIT.\n\npackage %v\n\n"
methodFormat = "\n// Hash ...\nfunc (%v%v) Hash() uint64 {\n\treturn %v\n}\n"
methodFormat = "\nfunc (%v%v) Hash() (uint64, uint64) {\n\treturn %v, %v\n}\n"
constFormat = "\thash%v"
)

Expand Down Expand Up @@ -91,16 +90,18 @@ func (b *hashBuilder) writePackage(w io.Writer) {
if _, err := fmt.Fprintf(w, packageFormat, b.pkg.Name); err != nil {
log.Fatalln(err)
}
if _, err := fmt.Fprintf(w, "import \"github.com/df-mc/dragonfly/server/world\"\n\n"); err != nil {
log.Fatalln(err)
}
}

// writeConstants writes hash constants for every block to a file.
func (b *hashBuilder) writeConstants(w io.Writer) (bitSize int) {
func (b *hashBuilder) writeConstants(w io.Writer) {
if _, err := fmt.Fprintln(w, "const ("); err != nil {
log.Fatalln(err)
}

var i uint64
for _, name := range b.names {
for i, name := range b.names {
c := constFormat
if i == 0 {
c += " = iota"
Expand All @@ -109,14 +110,11 @@ func (b *hashBuilder) writeConstants(w io.Writer) (bitSize int) {
if _, err := fmt.Fprintf(w, c+"\n", name); err != nil {
log.Fatalln(err)
}
i++
}

if _, err := fmt.Fprintln(w, "\thashCustomBlockBase\n)"); err != nil {
log.Fatalln(err)
}

return bits.Len64(i)
}

func (b *hashBuilder) writeNextHash(w io.Writer) {
Expand All @@ -134,12 +132,12 @@ func (b *hashBuilder) writeNextHash(w io.Writer) {
}
}

func (b *hashBuilder) writeMethods(w io.Writer, baseBits int) {
func (b *hashBuilder) writeMethods(w io.Writer) {
for _, name := range b.names {
fields := b.blockFields[name]

h := "hash" + name
bitSize := baseBits
var h string
var bitSize int

fun := b.funcs[name]
var recvName string
Expand Down Expand Up @@ -185,27 +183,36 @@ func (b *hashBuilder) writeMethods(w io.Writer, baseBits int) {
}

if bitSize > 64 {
log.Println("Hash size of block properties of", name, "exceeds", 64-baseBits, "bits. Please look at this manually.")
log.Println("Hash size of block properties of", name, "exceeds 64 bits. Please look at this manually.")
} else {
h += " | " + str + "<<" + strconv.Itoa(bitSize)
if h == "" {
h += str
} else {
h += " | " + str
}
if bitSize > 0 {
h += "<<" + strconv.Itoa(bitSize)
}
}
bitSize += v
}
}
if bitSize == baseBits {
if bitSize == 0 {
// No need to have a receiver name if we don't use any of the fields of the block.
recvName = ""
}

if recvName != "" {
recvName += " "
}
if h == "" {
h = "0"
}

if _, err := fmt.Fprintf(w, methodFormat, recvName, name, h); err != nil {
if _, err := fmt.Fprintf(w, methodFormat, recvName, name, "hash"+name, h); err != nil {
log.Fatalln(err)
}
}
log.Println("Assuming int size of 8 bits at most for all int fields: Make sure this is valid for all blocks.")
}

func (b *hashBuilder) ftype(structName, s string, expr ast.Expr, directives map[string]string) (string, int) {
Expand All @@ -227,7 +234,7 @@ func (b *hashBuilder) ftype(structName, s string, expr ast.Expr, directives map[
case "int":
return "uint64(" + s + ")", 8
case "Block":
return s + ".Hash()", 16
return "world.BlockHash(" + s + ")", 32
case "Attachment":
if _, ok := directives["facing_only"]; ok {
log.Println("Found directive: 'facing_only'")
Expand Down
Loading

0 comments on commit 42801f6

Please sign in to comment.