Re-organisation. Added file utility to calculate upload/download slot count by connection speed (we should probably add a config value in the file server to override this, but it's good for people who are lazy)

This commit is contained in:
2025-08-31 22:59:58 +01:00
parent 81c0625d27
commit dfb075a4bf
6 changed files with 69 additions and 5 deletions

48
files/files.go Normal file
View File

@@ -0,0 +1,48 @@
package files
import (
"github.com/showwin/speedtest-go/speedtest"
)
type ConnectionStatistics struct {
downloadBytes uint64 // Server download speed in bytes
uploadBytes uint64 // Upload speed in bytes
downloadSlots uint16 // How fany files can be downloaded by the server at once before queueing kicks in
uploadSlots uint16 // How many uploads we can do at once
// Slots are calculated with a minimum acceptable speed of 128KiB/s per slot
// Using uint16 for this MIGHT get a bit munted if someone tries to use something faster than a 25gbit connection
// or something but I really, really doubt anyone is going to do that. Problem for later me if it turns into an issue
}
func CalculateConnectionStatistics() ConnectionStatistics {
var speedtestClient = speedtest.New()
serverList, _ := speedtestClient.FetchServers()
// Picks server with the lowest ping
targets, _ := serverList.FindServer([]int{})
for _, s := range targets {
s.PingTest(nil)
s.DownloadTest()
s.UploadTest()
connStats := ConnectionStatistics{
downloadBytes: uint64(s.DLSpeed), // Casting since speedtest-go dev implemented this as float64
uploadBytes: uint64(s.ULSpeed),
downloadSlots: uint16(uint64(s.DLSpeed) / 131072), // 128KiB per slot
uploadSlots: uint16(uint64(s.ULSpeed) / 131072), // Casting to avoid float
}
if connStats.downloadSlots > 1000 {
connStats.downloadSlots = 1000 // Max slot count should be 1000 to avoid DDoS-like behaviour
}
if connStats.uploadSlots > 1000 {
connStats.uploadSlots = 1000
}
s.Context.Reset()
return connStats
}
// If all else fails... fuckin' yolo it
connStats := ConnectionStatistics{0, 0, 1000, 1000}
return connStats
}

13
files/files_test.go Normal file
View File

@@ -0,0 +1,13 @@
package files
import (
"fmt"
"strconv"
"testing"
)
func TestCalculateConnectionStatistics(t *testing.T) {
connStats := CalculateConnectionStatistics()
fmt.Printf(" Download: %s bytes/s\n Upload: %s bytes/s\n Estimated Client Slots: %s\n Estimated Internal Slots: %s\n", strconv.FormatUint(connStats.downloadBytes, 10), strconv.FormatUint(connStats.uploadBytes, 10), strconv.Itoa(int(connStats.uploadSlots)), strconv.Itoa(int(connStats.downloadSlots)))
}

View File

@@ -1,7 +1,7 @@
package SnowcloakUtils package global
import ( import (
"crypto/rand" // Probably better than math/rand for this crand "crypto/rand" // Probably better than math/rand for this
"log" "log"
) )
@@ -10,7 +10,7 @@ func GenerateRandomString(length int) string {
// We can probably get away with just uppercase. // We can probably get away with just uppercase.
allowedArray := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") allowedArray := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
random := make([]byte, length) random := make([]byte, length)
_, err := rand.Read(random) _, err := crand.Read(random)
if err != nil { if err != nil {
log.Fatalf("Couldn't generate secure slice: %s", err) log.Fatalf("Couldn't generate secure slice: %s", err)
} }
@@ -21,6 +21,5 @@ func GenerateRandomString(length int) string {
charArray[i] = allowedArray[int(random[i])%allowedLength] // Casting random[i] due to type mismatch charArray[i] = allowedArray[int(random[i])%allowedLength] // Casting random[i] due to type mismatch
i++ i++
} }
return string(charArray) return string(charArray)
} }

View File

@@ -1,4 +1,4 @@
package SnowcloakUtils package global
import ( import (
"fmt" "fmt"

2
go.mod
View File

@@ -1,3 +1,5 @@
module SnowcloakUtils module SnowcloakUtils
go 1.25 go 1.25
require github.com/showwin/speedtest-go v1.7.10

2
go.sum Normal file
View File

@@ -0,0 +1,2 @@
github.com/showwin/speedtest-go v1.7.10 h1:9o5zb7KsuzZKn+IE2//z5btLKJ870JwO6ETayUkqRFw=
github.com/showwin/speedtest-go v1.7.10/go.mod h1:Ei7OCTmNPdWofMadzcfgq1rUO7mvJy9Jycj//G7vyfA=