Skip to content

Commit

Permalink
Custom titledb (#5)
Browse files Browse the repository at this point in the history
* first draft for customTitleDB

* Fix lint issues

* Add example in config

* Add missing part in index for banned theme

Co-authored-by: DblK <admin@dblk.org>
  • Loading branch information
DblK and DblK authored Dec 19, 2021
1 parent 7638137 commit 65dbeff
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 34 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

[![golangci-lint](https://github.com/DblK/tinshop/actions/workflows/golangci-lint.yml/badge.svg?event=release)](https://github.com/DblK/tinshop/actions/workflows/golangci-lint.yml)
[![GitHub go.mod Go version of a Go module](https://img.shields.io/github/go-mod/go-version/dblk/tinshop.svg)](https://github.com/dblk/tinshop)
[![GoDoc reference example](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/dblk/tinshop/v0.0.1)
[![GoDoc reference example](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/dblk/tinshop/v0.0.3)
[![GoReportCard example](https://goreportcard.com/badge/github.com/dblk/tinshop)](https://goreportcard.com/report/github.com/dblk/tinshop)
[![GitHub release](https://img.shields.io/github/release/dblk/tinshop.svg)](https://GitHub.com/dblk/tinshop/releases/)

Expand Down Expand Up @@ -43,6 +43,7 @@ Here is the list of all main features so far:
- [X] Auto-refresh configuration on file change
- [X] Add the possibility to whitelist or blacklist a switch
- [X] Add the possibility to ban theme
- [X] You can specify custom titledb to be merged with official one

# Dev or build from source

Expand Down
14 changes: 13 additions & 1 deletion config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,16 @@ security:
# Block access to all switch present in this list
# You can find the uid of a switch in the log upon access
backlist:
- NOACCESSNOACCESSNOACCESSNOACCESSNOACCESSNOACCESSNOACCESSNOACCESS
- NOACCESSNOACCESSNOACCESSNOACCESSNOACCESSNOACCESSNOACCESSNOACCESS

# This section describe all custom title db to show up properly in tinfoil
customTitledb:
# Id of the entry
"060000BADDAD0000":
id: "050000BADDAD0000"
name: "Tinfoil"
region: "US"
releaseDate: 20180801
description: "Nintendo Switch Title Manager"
size: 14000000
iconUrl: ""
35 changes: 22 additions & 13 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,19 @@ type security struct {
// File holds all config information
type File struct {
rootShop string
ShopHost string `mapstructure:"host"`
ShopProtocol string `mapstructure:"protocol"`
ShopPort int `mapstructure:"port"`
Debug debug `mapstructure:"debug"`
AllSources repository.Sources `mapstructure:"sources"`
Name string `mapstructure:"name"`
Security security `mapstructure:"security"`
ShopHost string `mapstructure:"host"`
ShopProtocol string `mapstructure:"protocol"`
ShopPort int `mapstructure:"port"`
Debug debug `mapstructure:"debug"`
AllSources repository.Sources `mapstructure:"sources"`
Name string `mapstructure:"name"`
Security security `mapstructure:"security"`
CustomTitleDB map[string]repository.CustomDBEntry `mapstructure:"customTitledb"`
shopTemplateData repository.ShopTemplate
}

var serverConfig File
var allHooks []func(repository.Sources)
var allHooks []func(repository.Config)

// LoadConfig handles viper under the hood
func LoadConfig() {
Expand Down Expand Up @@ -71,7 +72,7 @@ func configChange() {

// Call all hooks
for _, hook := range allHooks {
hook(serverConfig.AllSources)
hook(&serverConfig)
}
}

Expand Down Expand Up @@ -134,8 +135,8 @@ func ComputeDefaultValues(config repository.Config) repository.Config {
return config
}

// HookOnSource Add hook function on change sources
func HookOnSource(f func(repository.Sources)) {
// AddHook Add hook function on change config
func AddHook(f func(repository.Config)) {
allHooks = append(allHooks, f)
}

Expand Down Expand Up @@ -179,6 +180,11 @@ func (cfg *File) Directories() []string {
return cfg.AllSources.Directories
}

// CustomDB returns the list of custom title db
func (cfg *File) CustomDB() map[string]repository.CustomDBEntry {
return cfg.CustomTitleDB
}

// NfsShares returns the list of nfs sources
func (cfg *File) NfsShares() []string {
return cfg.AllSources.Nfs
Expand Down Expand Up @@ -235,10 +241,13 @@ func (cfg *File) isInWhiteList(uid string) bool {

// IsBannedTheme tells if the theme is banned or not
func (cfg *File) IsBannedTheme(theme string) bool {
fmt.Println(theme)
fmt.Println(cfg.Security.BannedTheme)
idxBannedTheme := utils.Search(len(cfg.Security.BannedTheme), func(index int) bool {
return cfg.Security.BannedTheme[index] == theme
})
return idxBannedTheme != -1
}

// BannedTheme returns all banned theme
func (cfg *File) BannedTheme() []string {
return cfg.Security.BannedTheme
}
57 changes: 47 additions & 10 deletions gamescollection/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import (
"io"
"log"
"os"
"reflect"
"strings"

"github.com/dblk/tinshop/config"
"github.com/dblk/tinshop/repository"
"github.com/dblk/tinshop/utils"
)

var library map[string]map[string]interface{}
var mergedLibrary map[string]interface{}
var games repository.GameType

// Load ensure that necessary data is loaded
Expand Down Expand Up @@ -58,28 +61,56 @@ func loadTitlesLibrary() {
func initGamesCollection() {
// Build games object
games.Success = "Welcome to your own shop!"
games.Titledb = make(map[string]map[string]interface{})
games.Titledb = make(map[string]interface{})
games.Files = make([]interface{}, 0)
games.ThemeBlackList = nil
}

// Reset the collection of files
func Reset(src repository.Sources) {
// OnConfigUpdate the collection of files
func OnConfigUpdate(cfg repository.Config) {
initGamesCollection()

// Create merged library
mergedLibrary = make(map[string]interface{})

// Copy library
for key, entry := range library {
gameID := strings.ToUpper(key)

mergedLibrary[gameID] = entry
}

// Copy CustomDB
for key, entry := range config.GetConfig().CustomDB() {
gameID := strings.ToUpper(key)
if mergedLibrary[gameID] != nil {
log.Println("Duplicate customDB entry from official titledb (consider removing from configuration)", gameID)
} else {
mergedLibrary[gameID] = entry
}
}

// Check if blacklist entries
if len(config.GetConfig().BannedTheme()) != 0 {
games.ThemeBlackList = config.GetConfig().BannedTheme()
} else {
games.ThemeBlackList = nil
}
}

// Library returns the titledb library
func Library() map[string]map[string]interface{} {
return library
func Library() map[string]interface{} {
return mergedLibrary
}

// HasGameIDInLibrary tells if we have gameID information in library
func HasGameIDInLibrary(gameID string) bool {
return library[gameID] != nil
return Library()[gameID] != nil
}

// IsBaseGame tells if the gameID is a base game or not
func IsBaseGame(gameID string) bool {
return library[gameID]["iconUrl"] != nil
return Library()[gameID].(map[string]interface{})["iconUrl"] != nil
}

// Games returns the games inside the library
Expand All @@ -91,8 +122,14 @@ func Games() repository.GameType {
func CountGames() int {
var uniqueGames int
for _, entry := range games.Titledb {
if entry["iconUrl"] != nil {
uniqueGames++
if reflect.TypeOf(entry).String() == "repository.CustomDBEntry" {
if entry.(repository.CustomDBEntry).IconURL != "" {
uniqueGames++
}
} else {
if entry.(map[string]interface{})["iconUrl"] != nil {
uniqueGames++
}
}
}
return uniqueGames
Expand All @@ -114,7 +151,7 @@ func AddNewGames(newGames []repository.FileDesc) {
if games.Titledb[file.GameID] != nil && IsBaseGame(file.GameID) {
log.Println("Already added id!", file.GameID, file.Path)
} else {
games.Titledb[file.GameID] = library[file.GameID]
games.Titledb[file.GameID] = Library()[file.GameID]
}
} else {
log.Println("Game not found in database!", file.GameInfo, file.Path)
Expand Down
4 changes: 2 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ func initServer() {
collection.Load()

// Loading config
config.HookOnSource(collection.Reset)
config.HookOnSource(sources.Load)
config.AddHook(collection.OnConfigUpdate)
config.AddHook(sources.OnConfigUpdate)
config.LoadConfig()
}

Expand Down
28 changes: 28 additions & 0 deletions mock_repository/mock_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 18 additions & 3 deletions repository/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ type Config interface {
IsBlacklisted(string) bool
IsWhitelisted(string) bool
IsBannedTheme(string) bool
BannedTheme() []string

CustomDB() map[string]CustomDBEntry
}

// ShopTemplate contains all variables used for shop template
Expand Down Expand Up @@ -61,7 +64,19 @@ type FileDesc struct {

// GameType structure
type GameType struct {
Success string `json:"success"`
Titledb map[string]map[string]interface{} `json:"titledb"`
Files []interface{} `json:"files"`
Success string `json:"success"`
Titledb map[string]interface{} `json:"titledb"`
Files []interface{} `json:"files"`
ThemeBlackList []string `json:"themeBlackList,omitempty"`
}

// CustomDBEntry describe the various fields for entries
type CustomDBEntry struct {
ID string `mapstructure:"id" json:"id"`
Name string `mapstructure:"name" json:"name"`
Region string `mapstructure:"region" json:"region"`
Size int `mapstructure:"size" json:"size"`
ReleaseDate int `mapstructure:"releaseDate" json:"releaseDate"`
Description string `mapstructure:"description" json:"description"`
IconURL string `mapstructure:"iconUrl" json:"iconUrl"`
}
8 changes: 4 additions & 4 deletions sources/sources.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import (

var gameFiles []repository.FileDesc

// Load from all sources
func Load(src repository.Sources) {
// OnConfigUpdate from all sources
func OnConfigUpdate(cfg repository.Config) {
log.Println("Sources loading...")
gameFiles = make([]repository.FileDesc, 0)
loadGamesDirectories(src.Directories, len(src.Nfs) == 0)
loadGamesNfsShares(src.Nfs)
loadGamesDirectories(cfg.Directories(), len(cfg.NfsShares()) == 0)
loadGamesNfsShares(cfg.NfsShares())
}

// GetFiles returns all games files in various sources
Expand Down

0 comments on commit 65dbeff

Please sign in to comment.