RC-7
release-tag / release-image (push) Failing after 2m44s

This commit is contained in:
2026-08-11 16:58:07 +02:00
parent 185ccf1101
commit bcfbef390f
44 changed files with 4778 additions and 172 deletions
+86 -16
View File
@@ -3,6 +3,7 @@ package main
import (
"bufio"
"context"
"crypto/sha256"
"encoding/json"
"errors"
"fmt"
@@ -31,18 +32,19 @@ type app struct {
quiet bool
unattended bool
mu sync.RWMutex
task taskDTO
seq int64
points map[string]point
me meDTO
ws *websocket.Conn
wsConnected bool
sessionCancel context.CancelFunc
switching bool
leaderWatch bool
lastGuessAt time.Time
lastGuessOK bool
mu sync.RWMutex
task taskDTO
seq int64
points map[string]point
me meDTO
ws *websocket.Conn
wsConnected bool
sessionCancel context.CancelFunc
switching bool
leaderWatch bool
lastGuessAt time.Time
lastGuessOK bool
beaconPathMode string
}
func newApp(api *apiClient, identityPath, passphrase string, maxNodes int, quiet, unattended bool) *app {
@@ -428,6 +430,16 @@ func (a *app) refreshTask(taskID string) {
}
}
func chooseBeaconPath(mode, clientID string, seq int64) string {
switch strings.ToUpper(strings.TrimSpace(mode)) {
case "PULSE", "FLUX", "ORBIT":
return strings.ToUpper(strings.TrimSpace(mode))
}
h := sha256.Sum256([]byte(fmt.Sprintf("nh-cli-beacon-auto|%s|%d", clientID, seq)))
paths := []string{"PULSE", "FLUX", "ORBIT"}
return paths[int(h[0])%len(paths)]
}
func (a *app) guessLoop(ctx context.Context, taskID string) {
for {
a.mu.RLock()
@@ -461,7 +473,14 @@ func (a *app) guessLoop(ctx context.Context, taskID string) {
if t.Paused || !connected {
continue
}
correct, err := a.api.guess(ctx, t, seq)
path := ""
if t.BeaconHuntEnabled == 1 && t.GuessLotteryMaxAccepted > 0 {
path = chooseBeaconPath(a.beaconPathMode, a.api.cid, seq)
if !a.quiet {
fmt.Printf("[beacon] Pfad %s · Bonusgewicht bei Treffer ×%d\n", path, t.BeaconBonusWeight)
}
}
correct, err := a.api.guess(ctx, t, seq, path)
if err != nil {
if ctx.Err() != nil {
return
@@ -613,6 +632,31 @@ func (a *app) printNFTs(ctx context.Context, limit int) error {
return nil
}
func (a *app) printMyNFTs(ctx context.Context, limit int) error {
if limit <= 0 {
limit = 30
}
items, err := a.api.ownedArtifacts(ctx, limit)
if err != nil {
return err
}
fmt.Println("\nMEINE NFTS / ORIGINAL-ARTEFAKTE")
fmt.Println("──────────────────────────────────────────────────────────────────────────")
for i, n := range items {
name := strings.TrimSpace(n.DisplayName)
if name == "" {
name = shortID(n.TaskID)
}
fmt.Printf("%2d %-24s task=%-16s %3dbit %s\n", i+1, name, shortID(n.TaskID), n.RangeBits, n.CompletedAt.Local().Format("2006-01-02 15:04"))
fmt.Printf(" Original: %s%s\n", a.api.base, n.DownloadURI)
}
if len(items) == 0 {
fmt.Println("(für diese Identität noch keine fertigen Gewinner-Artefakte)")
}
fmt.Println()
return nil
}
func (a *app) watcher(ctx context.Context) {
t := time.NewTicker(5 * time.Second)
defer t.Stop()
@@ -638,7 +682,7 @@ func (a *app) watcher(ctx context.Context) {
func (a *app) commandLoop(ctx context.Context, in io.Reader) error {
s := bufio.NewScanner(in)
fmt.Println("Befehle: help, tasks, use <nr|id|name>, status, map [n], leaderboard [n|watch|stop], nfts [n], nft get <task-id> <datei>, identity, identity export <datei>, quit")
fmt.Println("Befehle: help, tasks, use <nr|id|name>, status, map [n], leaderboard [n|watch|stop], nfts [n], my-nfts [n], nft get <task-id> <datei>, nft original <task-id> <datei>, identity, identity export <datei>, hosted-code, quit")
for {
fmt.Print("neuralhunt> ")
if !s.Scan() {
@@ -658,10 +702,13 @@ func (a *app) commandLoop(ctx context.Context, in io.Reader) error {
fmt.Println(" map [n] textuelles Target Field / Nähe")
fmt.Println(" leaderboard [n] Live-Rangliste")
fmt.Println(" leaderboard watch|stop Rangliste alle 5s ein/aus")
fmt.Println(" nfts [n] Wasserzeichen-NFTs anzeigen")
fmt.Println(" nfts [n] öffentliche Wasserzeichen-NFTs anzeigen")
fmt.Println(" my-nfts [n] eigene Gewinner-Artefakte anzeigen")
fmt.Println(" nft get <task-id> <datei> Wasserzeichen-Preview speichern")
fmt.Println(" nft original <task-id> <datei> eigenes Original speichern")
fmt.Println(" identity Client-ID und Identity-Datei")
fmt.Println(" identity export <datei> browser-kompatiblen verschlüsselten Export schreiben")
fmt.Println(" hosted-code 10-Minuten-Code zum Koppeln als Reward-Identität")
fmt.Println(" quit beenden")
case "tasks":
if _, err := a.printTasks(ctx); err != nil {
@@ -723,6 +770,14 @@ func (a *app) commandLoop(ctx context.Context, in io.Reader) error {
if err := a.printNFTs(ctx, n); err != nil {
fmt.Println("Fehler:", err)
}
case "my-nfts", "mine":
n := 30
if len(parts) > 1 {
n, _ = strconv.Atoi(parts[1])
}
if err := a.printMyNFTs(ctx, n); err != nil {
fmt.Println("Fehler:", err)
}
case "nft":
if len(parts) == 4 && strings.EqualFold(parts[1], "get") {
if err := a.api.downloadPreview(ctx, parts[2], parts[3]); err != nil {
@@ -730,8 +785,14 @@ func (a *app) commandLoop(ctx context.Context, in io.Reader) error {
} else {
fmt.Println("Wasserzeichen-Preview gespeichert:", parts[3])
}
} else if len(parts) == 4 && (strings.EqualFold(parts[1], "original") || strings.EqualFold(parts[1], "download")) {
if err := a.api.downloadOwnedArtifact(ctx, parts[2], parts[3]); err != nil {
fmt.Println("Fehler:", err)
} else {
fmt.Println("Original-Artefakt gespeichert:", parts[3])
}
} else {
fmt.Println("nft get <task-id> <datei>")
fmt.Println("nft get <task-id> <datei> | nft original <task-id> <datei>")
}
case "identity", "id":
if len(parts) >= 2 && strings.EqualFold(parts[1], "export") {
@@ -748,6 +809,15 @@ func (a *app) commandLoop(ctx context.Context, in io.Reader) error {
fmt.Println("Client-ID:", a.api.cid)
fmt.Println("Identity :", a.identityPath)
}
case "hosted-code", "hosted-link":
x, err := a.api.hostedLinkCode(ctx)
if err != nil {
fmt.Println("Fehler:", err)
} else {
fmt.Println("Hosted-Code:", x.Code)
fmt.Println("Client-ID :", x.ClientID)
fmt.Println("Gültig bis :", x.ExpiresAt.Local().Format(time.RFC3339))
}
case "quit", "exit", "q":
return nil
default: