1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-11-14 00:06:45 -05:00
OpenDiablo2/d2core/d2asset/archived_file_manager.go
dk 8809fb2c22
Made abstractiong for the file manager (#542)
I realized that the file manager is actually managing file access
to the archives, but it's doing so through the archive manager.

I've renamed it, it's now called ArchivedFileManager because that
is really what it is.
2020-07-05 00:00:00 -04:00

100 lines
2.4 KiB
Go

package d2asset
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"strings"
"github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
)
const (
fileBudget = 1024 * 1024 * 32
)
type fileManager struct {
cache d2interface.Cache
archiveManager d2interface.ArchiveManager
config d2interface.Configuration
}
func createFileManager(config d2interface.Configuration,
archiveManager d2interface.ArchiveManager) d2interface.ArchivedFileManager {
return &fileManager{
d2common.CreateCache(fileBudget),
archiveManager,
config,
}
}
// LoadFileStream loads a file as a stream automatically from an archive
func (fm *fileManager) LoadFileStream(filePath string) (d2interface.ArchiveDataStream, error) {
filePath = fm.fixupFilePath(filePath)
archive, err := fm.archiveManager.LoadArchiveForFile(filePath)
if err != nil {
return nil, err
}
return archive.ReadFileStream(filePath)
}
// LoadFile loads a file automatically from a managed archive
func (fm *fileManager) LoadFile(filePath string) ([]byte, error) {
filePath = fm.fixupFilePath(filePath)
if value, found := fm.cache.Retrieve(filePath); found {
return value.([]byte), nil
}
archive, err := fm.archiveManager.LoadArchiveForFile(filePath)
if err != nil {
return nil, err
}
data, err := archive.ReadFile(filePath)
if err != nil {
return nil, err
}
if err := fm.cache.Insert(filePath, data, len(data)); err != nil {
return nil, err
}
return data, nil
}
// FileExists checks if a file exists in an archive
func (fm *fileManager) FileExists(filePath string) (bool, error) {
filePath = fm.fixupFilePath(filePath)
return fm.archiveManager.FileExistsInArchive(filePath)
}
func (fm *fileManager) ClearCache() {
fm.cache.Clear()
}
func (fm *fileManager) GetCache() d2interface.Cache {
return fm.cache
}
func (fm *fileManager) fixupFilePath(filePath string) string {
filePath = fm.removeLocaleTokens(filePath)
filePath = strings.ToLower(filePath)
filePath = strings.ReplaceAll(filePath, `/`, "\\")
filePath = strings.TrimPrefix(filePath, "\\")
return filePath
}
func (fm *fileManager) removeLocaleTokens(filePath string) string {
tableToken := d2resource.LanguageTableToken
fontToken := d2resource.LanguageFontToken
filePath = strings.ReplaceAll(filePath, tableToken, fm.config.Language())
// fixme: not all languages==latin
filePath = strings.ReplaceAll(filePath, fontToken, "latin")
return filePath
}