From 8a7f9a62e5d9c89c4ff005e13ebec8bbbc3537b2 Mon Sep 17 00:00:00 2001 From: Lucas Date: Sat, 14 Jun 2025 03:29:29 +0200 Subject: [PATCH] Add mining resource system with background updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements automatic resource production with database persistence: - Mining table with timestamp, value, and rate tracking - Background ticker updates values every minute - API endpoint calculates real-time values from database snapshots - Frontend displays live-updating current value and database history - Rate-based accumulation system for efficient resource management 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- index.html | 4 ++ main.go | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++- mining.html | 100 +++++++++++++++++++++++++++++++ 3 files changed, 267 insertions(+), 3 deletions(-) create mode 100644 mining.html diff --git a/index.html b/index.html index a3462b6..d533e89 100644 --- a/index.html +++ b/index.html @@ -31,6 +31,10 @@ Account Information
Authentication test page - displays user info and headers from Authelia (requires authentication).
+
  • + Mining Resources +
    Background resource production demo - displays live-calculated mining values with automatic database updates every minute.
    +
  • diff --git a/main.go b/main.go index 48a6577..9f8ff68 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,19 @@ type UserInfo struct { Headers map[string]string `json:"headers"` } +type MiningRecord struct { + ID int `json:"id"` + Timestamp time.Time `json:"timestamp"` + Value float64 `json:"value"` + Rate float64 `json:"rate"` +} + +type MiningData struct { + CurrentValue float64 `json:"current_value"` + Rate float64 `json:"rate"` + History []MiningRecord `json:"history"` +} + var db *sql.DB func initDB() { @@ -38,15 +51,43 @@ func initDB() { log.Fatal("Failed to open database:", err) } - createTable := ` + createItemsTable := ` CREATE TABLE IF NOT EXISTS items ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL );` - _, err = db.Exec(createTable) + _, err = db.Exec(createItemsTable) if err != nil { - log.Fatal("Failed to create table:", err) + log.Fatal("Failed to create items table:", err) + } + + createMiningTable := ` + CREATE TABLE IF NOT EXISTS mining ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp DATETIME NOT NULL, + value REAL NOT NULL, + rate REAL NOT NULL + );` + + _, err = db.Exec(createMiningTable) + if err != nil { + log.Fatal("Failed to create mining table:", err) + } + + // Insert initial mining record if table is empty + var count int + err = db.QueryRow("SELECT COUNT(*) FROM mining").Scan(&count) + if err != nil { + log.Fatal("Failed to check mining table:", err) + } + + if count == 0 { + _, err = db.Exec("INSERT INTO mining (timestamp, value, rate) VALUES (?, ?, ?)", + time.Now(), 100.0, 2.5) + if err != nil { + log.Fatal("Failed to insert initial mining record:", err) + } } } @@ -60,6 +101,9 @@ func main() { initDB() defer db.Close() + // Start mining ticker + go startMiningTicker() + // Your actual API rng := rand.New(rand.NewSource(time.Now().UnixNano())) http.HandleFunc("/randomnumber", func(w http.ResponseWriter, r *http.Request) { @@ -90,6 +134,9 @@ func main() { http.HandleFunc("/items", handleItems) http.HandleFunc("/items/", handleItemDelete) + // Mining endpoints + http.HandleFunc("/mining", handleMining) + // Auth endpoints http.HandleFunc("/auth/user", handleAuthUser) @@ -262,3 +309,116 @@ func handleAuthUser(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(userInfo) } + +func handleMining(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + + if r.Method != "GET" { + w.WriteHeader(http.StatusMethodNotAllowed) + json.NewEncoder(w).Encode(map[string]string{"error": "Method not allowed"}) + return + } + + // Get the latest record to calculate current value + var latest MiningRecord + err := db.QueryRow(` + SELECT id, timestamp, value, rate + FROM mining + ORDER BY timestamp DESC + LIMIT 1 + `).Scan(&latest.ID, &latest.Timestamp, &latest.Value, &latest.Rate) + + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + json.NewEncoder(w).Encode(map[string]string{"error": "Failed to get latest mining data"}) + return + } + + // Calculate current value based on time elapsed and rate + now := time.Now() + minutesElapsed := now.Sub(latest.Timestamp).Minutes() + currentValue := latest.Value + (latest.Rate * minutesElapsed) + + // Get recent history (last 5 records) + rows, err := db.Query(` + SELECT id, timestamp, value, rate + FROM mining + ORDER BY timestamp DESC + LIMIT 5 + `) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + json.NewEncoder(w).Encode(map[string]string{"error": "Failed to get mining history"}) + return + } + defer rows.Close() + + var history []MiningRecord + for rows.Next() { + var record MiningRecord + err := rows.Scan(&record.ID, &record.Timestamp, &record.Value, &record.Rate) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + json.NewEncoder(w).Encode(map[string]string{"error": "Failed to scan mining record"}) + return + } + history = append(history, record) + } + + response := MiningData{ + CurrentValue: currentValue, + Rate: latest.Rate, + History: history, + } + + json.NewEncoder(w).Encode(response) +} + +func startMiningTicker() { + ticker := time.NewTicker(1 * time.Minute) + defer ticker.Stop() + + log.Println("Mining ticker started - updating every minute") + + for { + select { + case <-ticker.C: + updateMiningValue() + } + } +} + +func updateMiningValue() { + // Get the latest record + var latest MiningRecord + err := db.QueryRow(` + SELECT id, timestamp, value, rate + FROM mining + ORDER BY timestamp DESC + LIMIT 1 + `).Scan(&latest.ID, &latest.Timestamp, &latest.Value, &latest.Rate) + + if err != nil { + log.Printf("Failed to get latest mining record: %v", err) + return + } + + // Calculate new value based on time elapsed and rate + now := time.Now() + minutesElapsed := now.Sub(latest.Timestamp).Minutes() + newValue := latest.Value + (latest.Rate * minutesElapsed) + + // Insert new record + _, err = db.Exec(` + INSERT INTO mining (timestamp, value, rate) + VALUES (?, ?, ?) + `, now, newValue, latest.Rate) + + if err != nil { + log.Printf("Failed to insert new mining record: %v", err) + return + } + + log.Printf("Mining updated: %.2f -> %.2f (rate: %.2f/min, elapsed: %.2f min)", + latest.Value, newValue, latest.Rate, minutesElapsed) +} diff --git a/mining.html b/mining.html new file mode 100644 index 0000000..a146f36 --- /dev/null +++ b/mining.html @@ -0,0 +1,100 @@ + + + + + + Mining Resources - Playground + + + +

    Mining Resources

    + +
    +

    Current Resources

    +
    Loading...
    +
    + Rate: 0 per minute +
    +
    Last updated: Loading...
    +
    + +
    +

    Database History (Last 5 Updates)

    +
    +
    Loading history...
    +
    +
    + + + + + + \ No newline at end of file