Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make block hashes more dynamic to avoid registry collisions #918

Merged
merged 17 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
5adb4f8
dragonfly/server: Make block hashes more dynamic
TwistedAsylumMC Feb 29, 2024
7969cf7
world/block_state.go: Offload palette sorting to finaliseBlockRegistry()
TwistedAsylumMC Mar 4, 2024
d5b4b60
Merge branch 'master' into feature/dynamichashes
TwistedAsylumMC Mar 14, 2024
7791737
Merge branch 'refs/heads/master' into feature/dynamichashes
TwistedAsylumMC Jun 21, 2024
9a1379c
block/hash.go: Regenerate hashes
TwistedAsylumMC Jun 21, 2024
4b18cdd
Merge branch 'refs/heads/master' into feature/dynamichashes
TwistedAsylumMC Jul 11, 2024
e083492
Merge branch 'refs/heads/master' into feature/dynamichashes
TwistedAsylumMC Jul 11, 2024
725bc23
Merge branch 'refs/heads/master' into feature/dynamichashes
TwistedAsylumMC Jul 11, 2024
2e27606
Merge branch 'refs/heads/master' into feature/dynamichashes
TwistedAsylumMC Jul 11, 2024
7dc96a7
Merge branch 'refs/heads/master' into feature/dynamichashes
TwistedAsylumMC Aug 28, 2024
b886b4b
block/hash.go: Regenerate hashes
TwistedAsylumMC Aug 28, 2024
16d27a7
Merge branch 'refs/heads/master' into feature/dynamichashes
TwistedAsylumMC Sep 2, 2024
6af4876
server/conf.go: Import "unsafe" and finalise block registry before cr…
TwistedAsylumMC Sep 2, 2024
82db357
world/block.go: Add documentation for new hash methods
TwistedAsylumMC Sep 2, 2024
6e71a3e
world/block.go: Document math.MaxUint64 usage
TwistedAsylumMC Sep 3, 2024
4a45f8b
world/block.go: Merge Hash() and BaseHash() methods
TwistedAsylumMC Sep 6, 2024
0638f0b
blockhash/main.go: Revert now-unnecessary const rename
TwistedAsylumMC Sep 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 34 additions & 21 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,15 +53,16 @@ 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"
constFormat = "\thash%v"
packageFormat = "// Code generated by cmd/blockhash; DO NOT EDIT.\n\npackage %v\n\n"
baseMethodFormat = "\nfunc (%v) BaseHash() uint64 {\n\treturn %v\n}\n"
hashMethodFormat = "\nfunc (%v%v) Hash() uint64 {\n\treturn %v\n}\n"
constFormat = "\thash%v"
)

type hashBuilder struct {
Expand Down Expand Up @@ -91,16 +91,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 +111,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 +133,17 @@ 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 {
if _, err := fmt.Fprintf(w, baseMethodFormat, name, "hash"+name); err != nil {
log.Fatalln(err)
}
}
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 +189,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, hashMethodFormat, recvName, 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 +240,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
Loading