feat(backend): add mod manager service for scanning workshop/local mods
This commit is contained in:
120
backend/internal/services/mod_manager.go
Normal file
120
backend/internal/services/mod_manager.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type ModInfo struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Source string `json:"source"`
|
||||
Path string `json:"path"`
|
||||
Size int64 `json:"size"`
|
||||
InUse bool `json:"in_use"`
|
||||
Modlists []string `json:"modlists"`
|
||||
}
|
||||
|
||||
func ListWorkshopMods(serverfileDir string) []ModInfo {
|
||||
workshopDir := filepath.Join(serverfileDir, "steamapps", "workshop", "content", workshopAppID)
|
||||
entries, err := os.ReadDir(workshopDir)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var mods []ModInfo
|
||||
for _, e := range entries {
|
||||
if !e.IsDir() {
|
||||
continue
|
||||
}
|
||||
id := e.Name()
|
||||
p := filepath.Join(workshopDir, id)
|
||||
size := dirSize(p)
|
||||
mods = append(mods, ModInfo{
|
||||
ID: id,
|
||||
Name: "",
|
||||
Source: "workshop",
|
||||
Path: p,
|
||||
Size: size,
|
||||
})
|
||||
}
|
||||
return mods
|
||||
}
|
||||
|
||||
func ListLocalMods(modsDir string) []ModInfo {
|
||||
entries, err := os.ReadDir(modsDir)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var mods []ModInfo
|
||||
for _, e := range entries {
|
||||
if !e.IsDir() {
|
||||
continue
|
||||
}
|
||||
name := e.Name()
|
||||
p := filepath.Join(modsDir, name)
|
||||
size := dirSize(p)
|
||||
displayName := name
|
||||
if len(name) > 0 && name[0] == '@' {
|
||||
displayName = name[1:]
|
||||
}
|
||||
mods = append(mods, ModInfo{
|
||||
ID: displayName,
|
||||
Name: name,
|
||||
Source: "local",
|
||||
Path: p,
|
||||
Size: size,
|
||||
})
|
||||
}
|
||||
return mods
|
||||
}
|
||||
|
||||
func BuildUsageMap(modlists *ModlistManager) (usedWorkshop map[string][]string, usedLocal map[string][]string) {
|
||||
usedWorkshop = make(map[string][]string)
|
||||
usedLocal = make(map[string][]string)
|
||||
|
||||
lists, err := modlists.List()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, li := range lists {
|
||||
ml, err := modlists.Get(li.ID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, m := range ml.Mods {
|
||||
if m.ID != "" {
|
||||
usedWorkshop[m.ID] = append(usedWorkshop[m.ID], ml.Name)
|
||||
}
|
||||
if m.Name != "" {
|
||||
nameWithAt := "@" + m.Name
|
||||
usedLocal[m.Name] = append(usedLocal[m.Name], ml.Name)
|
||||
usedLocal[nameWithAt] = append(usedLocal[nameWithAt], ml.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func RemoveMod(path string) error {
|
||||
return os.RemoveAll(path)
|
||||
}
|
||||
|
||||
func dirSize(path string) int64 {
|
||||
var size int64
|
||||
filepath.WalkDir(path, func(_ string, d os.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
if !d.IsDir() {
|
||||
fi, err := d.Info()
|
||||
if err == nil {
|
||||
size += fi.Size()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return size
|
||||
}
|
||||
Reference in New Issue
Block a user