refactored logging in d2loader, d2record, and d2asset (#898)

* refactored logging in d2config, d2record, and d2asset

* asset manager, record manager, and file loader now utilitize d2util.Logger
* added colored logging to d2util.Logger (excluding windows platforms)
* removed mpq file verification from d2config; d2loader handles this
* record loaders now use the record manager's logger for printing info
* added command line argument for setting log level (`--loglevel 4`, `-l4`, or `-l 4`
* added `LogLevel` parameter to config file
* default log level will show errors, warnings, and info log messages
* specifying log level as an argument overrides setting from config file

* fixed log level tests
This commit is contained in:
gravestench 2020-11-03 02:23:07 +00:00 committed by GitHub
parent b052006922
commit d6c9748fef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
96 changed files with 406 additions and 420 deletions

View File

@ -82,6 +82,7 @@ type Options struct {
Debug *bool
profiler *string
Server *d2networking.ServerOptions
LogLevel *d2util.LogLevel
}
type bindTerminalEntry struct {
@ -119,7 +120,7 @@ func (a *App) startDedicatedServer() error {
return err
}
asset, err := d2asset.NewAssetManager(d2config.Config)
asset, err := d2asset.NewAssetManager(d2config.Config, *a.Options.LogLevel)
if err != nil {
return err
}
@ -162,13 +163,21 @@ func (a *App) loadEngine() error {
return err
}
a.renderer = renderer
// If we failed to load our config, lets show the boot panic screen
if configError != nil {
return configError
}
// if the log level was specified at the command line, use it
logLevel := *a.Options.LogLevel
if logLevel == d2util.LogLevelUnspecified {
logLevel = d2config.Config.LogLevel
}
// Create the asset manager
asset, err := d2asset.NewAssetManager(d2config.Config)
asset, err := d2asset.NewAssetManager(d2config.Config, logLevel)
if err != nil {
return err
}
@ -195,7 +204,6 @@ func (a *App) loadEngine() error {
a.terminal = term
a.scriptEngine = scriptEngine
a.audio = audio
a.renderer = renderer
a.ui = uiManager
a.asset = asset
a.tAllocSamples = createZeroedRing(nSamplesTAlloc)
@ -222,15 +230,26 @@ func (a *App) parseArguments() {
playersArg = "players"
playersDesc = "Sets the number of max players for the dedicated server"
loggingArg = "loglevel"
loggingShort = 'l'
loggingDesc = "Enables verbose logging. Log levels will include those below it. " +
"0 disables log messages, " +
"1 shows errors, " +
"2 shows warnings, " +
"3 shows info, " +
"4 shows debug" +
"5 uses value from config file (default)"
)
a.Options.profiler = kingpin.Flag(profilerArg, profilerDesc).String()
a.Options.Server.Dedicated = kingpin.Flag(serverArg, serverDesc).Short(serverShort).Bool()
a.Options.printVersion = kingpin.Flag(versionArg, versionDesc).Short(versionShort).Bool()
a.Options.Server.MaxPlayers = kingpin.Flag(playersArg, playersDesc).Int()
a.Options.LogLevel = kingpin.Flag(loggingArg, loggingDesc).
Short(loggingShort).
Default(strconv.Itoa(d2util.LogLevelUnspecified)).
Int()
kingpin.Parse()
}

View File

@ -1,7 +1,6 @@
package d2data
import (
"log"
"strings"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2datautils"
@ -52,7 +51,5 @@ func LoadAnimationData(rawData []byte) AnimationData {
}
}
log.Printf("Loaded %d animation data records", len(animdata))
return animdata
}

View File

@ -1,6 +1,7 @@
package d2loader
import (
"errors"
"fmt"
"os"
"path/filepath"
@ -25,6 +26,7 @@ const (
const (
defaultLanguage = "ENG"
logPrefix = "File Loader"
)
const (
@ -33,16 +35,20 @@ const (
)
// NewLoader creates a new loader
func NewLoader(config *d2config.Configuration) *Loader {
func NewLoader(config *d2config.Configuration, l d2util.LogLevel) (*Loader, error) {
loader := &Loader{
config: config,
}
loader.Cache = d2cache.CreateCache(defaultCacheBudget)
loader.Logger = d2util.NewLogger()
loader.initFromConfig()
loader.Logger.SetPrefix(logPrefix)
loader.Logger.SetLevel(l)
return loader
err := loader.initFromConfig()
return loader, err
}
// Loader represents the manager that handles loading and caching assets with the asset Sources
@ -54,9 +60,21 @@ type Loader struct {
Sources []asset.Source
}
func (l *Loader) initFromConfig() {
const (
errConfigFileNotFound = "config file not found"
fmtErrSourceNotFound = `file not found: %s
Please check your config file at %s
Also, verify that the MPQ files exist at %s
Capitalization matters!
`
)
func (l *Loader) initFromConfig() error {
if l.config == nil {
return
return errors.New(errConfigFileNotFound)
}
for _, mpqName := range l.config.MpqLoadOrder {
@ -65,9 +83,12 @@ func (l *Loader) initFromConfig() {
_, err := l.AddSource(srcPath)
if err != nil {
fmt.Println(err.Error())
// nolint:stylecheck // we want a multiline error message here..
return fmt.Errorf(fmtErrSourceNotFound, srcPath, l.config.Path(), l.config.MpqPath)
}
}
return nil
}
// Load attempts to load an asset with the given sub-path. The sub-path is relative to the root
@ -85,7 +106,7 @@ func (l *Loader) Load(subPath string) (asset.Asset, error) {
// first, we check the cache for an existing entry
if cached, found := l.Retrieve(subPath); found {
l.Debug(fmt.Sprintf("file `%s` exists in loader cache", subPath))
l.Debug(fmt.Sprintf("Retrieved `%s` from cache", subPath))
a := cached.(asset.Asset)
_, err := a.Seek(0, 0)
@ -98,10 +119,16 @@ func (l *Loader) Load(subPath string) (asset.Asset, error) {
source := l.Sources[idx]
// if the source can open the file, then we cache it and return it
if loadedAsset, err := source.Open(subPath); err == nil {
err := l.Insert(subPath, loadedAsset, defaultCacheEntryWeight)
return loadedAsset, err
loadedAsset, err := source.Open(subPath)
if err != nil {
l.Debug(fmt.Sprintf("Checked `%s`, file not found", source.Path()))
continue
}
srcBase := filepath.Base(source.Path())
l.Info(fmt.Sprintf("from %s, loading %s", srcBase, subPath))
return loadedAsset, l.Insert(subPath, loadedAsset, defaultCacheEntryWeight)
}
return nil, fmt.Errorf(errFmtFileNotFound, subPath)
@ -120,7 +147,7 @@ func (l *Loader) AddSource(path string) (asset.Source, error) {
info, err := os.Lstat(cleanPath)
if err != nil {
l.Warning(err.Error())
l.Error(err.Error())
return nil, err
}
@ -140,7 +167,7 @@ func (l *Loader) AddSource(path string) (asset.Source, error) {
case types.AssetSourceMPQ:
source, err := mpq.NewSource(cleanPath)
if err == nil {
l.Debug(fmt.Sprintf("adding MPQ source `%s`", cleanPath))
l.Info(fmt.Sprintf("adding MPQ source `%s`", cleanPath))
l.Sources = append(l.Sources, source)
return source, nil
@ -150,7 +177,7 @@ func (l *Loader) AddSource(path string) (asset.Source, error) {
Root: cleanPath,
}
l.Debug(fmt.Sprintf("adding filesystem source `%s`", cleanPath))
l.Info(fmt.Sprintf("adding filesystem source `%s`", cleanPath))
l.Sources = append(l.Sources, source)
return source, nil

View File

@ -5,6 +5,8 @@ import (
"log"
"testing"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2loader/asset"
)
@ -24,7 +26,7 @@ const (
)
func TestLoader_NewLoader(t *testing.T) {
loader := NewLoader(nil)
loader, _ := NewLoader(nil, d2util.LogLevelDefault)
if loader.Cache == nil {
t.Error("loader should not be nil")
@ -32,7 +34,7 @@ func TestLoader_NewLoader(t *testing.T) {
}
func TestLoader_AddSource(t *testing.T) {
loader := NewLoader(nil)
loader, _ := NewLoader(nil, d2util.LogLevelDefault)
sourceA, errA := loader.AddSource(sourcePathA)
sourceB, errB := loader.AddSource(sourcePathB)
@ -83,7 +85,7 @@ func TestLoader_AddSource(t *testing.T) {
// nolint:gocyclo // this is just a test, not a big deal if we ignore linter here
func TestLoader_Load(t *testing.T) {
loader := NewLoader(nil)
loader, _ := NewLoader(nil, d2util.LogLevelDefault)
_, err := loader.AddSource(sourcePathB) // we expect files common to any source to come from here
if err != nil {

View File

@ -4,10 +4,11 @@ import (
"fmt"
"io"
"log"
"runtime"
)
// LogLevel determines how verbose the logging is (higher is more verbose)
type LogLevel int
type LogLevel = int
// Log levels
const (
@ -16,20 +17,58 @@ const (
LogLevelWarning
LogLevelInfo
LogLevelDebug
LogLevelUnspecified
)
// LogLevelDefault is the default log level
const LogLevelDefault = LogLevelInfo
const (
red = 1
green = 2
yellow = 3
magenta = 5
cyan = 6
)
const fmtColorEscape = "\033[3%dm"
const colorEscapeReset = "\033[0m"
// Log format strings for log levels
const (
LogFmtDebug = "[DEBUG] %s\n\r"
LogFmtInfo = "[INFO] %s\n\r"
LogFmtWarning = "[WARNING] %s\n\r"
LogFmtError = "[ERROR] %s\n\r"
fmtPrefix = "[%s]"
LogFmtDebug = "[DEBUG]" + colorEscapeReset + " %s"
LogFmtInfo = "[INFO]" + colorEscapeReset + " %s"
LogFmtWarning = "[WARNING]" + colorEscapeReset + " %s"
LogFmtError = "[ERROR]" + colorEscapeReset + " %s"
)
// NewLogger creates a new logger with a default
func NewLogger() *Logger {
l := &Logger{
level: LogLevelDefault,
colorEnabled: true,
}
l.Writer = log.Writer()
return l
}
// Logger is used to write log messages, and can have a log level to determine verbosity
type Logger struct {
prefix string
io.Writer
level LogLevel
level LogLevel
colorEnabled bool
}
// SetPrefix sets a prefix for the message.
// example:
// logger.SetPrefix("XYZ")
// logger.Debug("ABC") will print "[XYZ] [DEBUG] ABC"
func (l *Logger) SetPrefix(s string) {
l.prefix = s
}
// SetLevel sets the log level
@ -37,58 +76,106 @@ func (l *Logger) SetLevel(level LogLevel) {
l.level = level
}
// Debug logs a debug message
func (l *Logger) Debug(msg string) {
if l == nil {
return
// SetColorEnabled adds color escape-sequences to the logging output
func (l *Logger) SetColorEnabled(b bool) {
if runtime.GOOS == "windows" {
b = false
}
l.print(LogLevelDebug, msg)
l.colorEnabled = b
}
// Info logs an info message
func (l *Logger) Info(msg string) {
if l == nil {
if l == nil || l.level < LogLevelInfo {
return
}
l.print(LogLevelInfo, msg)
}
// Infof formats and then logs an info message
func (l *Logger) Infof(fmtMsg string, args ...interface{}) {
l.Info(fmt.Sprintf(fmtMsg, args...))
}
// Warning logs a warning message
func (l *Logger) Warning(msg string) {
if l == nil {
if l == nil || l.level < LogLevelWarning {
return
}
l.print(LogLevelWarning, msg)
}
// Warningf formats and then logs a warning message
func (l *Logger) Warningf(fmtMsg string, args ...interface{}) {
l.Warning(fmt.Sprintf(fmtMsg, args...))
}
// Error logs an error message
func (l *Logger) Error(msg string) {
if l == nil {
if l == nil || l.level < LogLevelError {
return
}
l.print(LogLevelError, msg)
}
// Errorf formats and then logs a error message
func (l *Logger) Errorf(fmtMsg string, args ...interface{}) {
l.Error(fmt.Sprintf(fmtMsg, args...))
}
// Debug logs a debug message
func (l *Logger) Debug(msg string) {
if l == nil || l.level < LogLevelDebug {
return
}
l.print(LogLevelDebug, msg)
}
// Debugf formats and then logs a debug message
func (l *Logger) Debugf(fmtMsg string, args ...interface{}) {
l.Debug(fmt.Sprintf(fmtMsg, args...))
}
func (l *Logger) print(level LogLevel, msg string) {
if l == nil || l.level < level {
return
}
colors := map[LogLevel]int{
LogLevelDebug: cyan,
LogLevelInfo: green,
LogLevelWarning: yellow,
LogLevelError: red,
}
fmtString := ""
if l.prefix != "" {
if l.colorEnabled {
fmtString = fmt.Sprintf(fmtColorEscape, magenta)
}
fmtString += fmt.Sprintf(fmtPrefix, l.prefix)
}
if l.colorEnabled {
fmtString += fmt.Sprintf(fmtColorEscape, colors[level])
}
switch level {
case LogLevelDebug:
fmtString = LogFmtDebug
fmtString += LogFmtDebug
case LogLevelInfo:
fmtString = LogFmtInfo
fmtString += LogFmtInfo
case LogLevelWarning:
fmtString = LogFmtWarning
fmtString += LogFmtWarning
case LogLevelError:
fmtString = LogFmtError
fmtString += LogFmtError
case LogLevelNone:
default:
return
@ -103,3 +190,7 @@ func (l *Logger) print(level LogLevel, msg string) {
func format(fmtStr string, fmtInput []byte) []byte {
return []byte(fmt.Sprintf(fmtStr, string(fmtInput)))
}
func (l *Logger) Write(p []byte) (n int, err error) {
return l.Writer.Write(p)
}

View File

@ -16,7 +16,8 @@ func (tw *testWriter) Write(msg []byte) (int, error) {
}
func Test_logger_SetLevel(t *testing.T) {
l := &Logger{Writer: &testWriter{}}
l := NewLogger()
l.Writer = &testWriter{}
tests := []struct {
level LogLevel
@ -39,8 +40,9 @@ func Test_logger_SetLevel(t *testing.T) {
}
func Test_logger_LogLevels(t *testing.T) {
l := NewLogger()
w := &testWriter{}
l := &Logger{Writer: w}
l.Writer = w
noMessage := ""
message := "test"
@ -107,8 +109,12 @@ func Test_logger_LogLevels(t *testing.T) {
msgGot := string(w.data)
if msgGot != msgExpect {
t.Errorf("unexpected log message: expected `%s` but got `%s`", msgExpect, msgGot)
if len(msgGot) > 0 && len(msgExpect) < 1 {
t.Errorf("logger printed when it should not have")
}
if len(msgGot) < 1 && len(msgExpect) > 0 {
t.Errorf("logger didnt print when expected")
}
}
}

View File

@ -2,7 +2,7 @@ package d2util
import "image/color"
// Color converts an rgba uint32 to a color.RGBA
// Color converts an rgba uint32 to a colorEnabled.RGBA
func Color(rgba uint32) color.RGBA {
result := color.RGBA{}
a, b, g, r := 0, 1, 2, 3

View File

@ -3,7 +3,8 @@ package d2asset
import (
"fmt"
"image/color"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data"
@ -39,6 +40,7 @@ const (
// AssetManager loads files and game objects
type AssetManager struct {
logger *d2util.Logger
loader *d2loader.Loader
tables d2interface.Cache
animations d2interface.Cache
@ -49,14 +51,7 @@ type AssetManager struct {
}
func (am *AssetManager) init() error {
rm, err := d2records.NewRecordManager()
if err != nil {
return err
}
am.Records = rm
err = am.initDataDictionaries()
err := am.initDataDictionaries()
if err != nil {
return err
}
@ -66,91 +61,38 @@ func (am *AssetManager) init() error {
func (am *AssetManager) initDataDictionaries() error {
dictPaths := []string{
d2resource.LevelType,
d2resource.LevelPreset,
d2resource.LevelWarp,
d2resource.ObjectType,
d2resource.ObjectDetails,
d2resource.Weapons,
d2resource.Armor,
d2resource.Misc,
d2resource.Books,
d2resource.ItemTypes,
d2resource.UniqueItems,
d2resource.Missiles,
d2resource.SoundSettings,
d2resource.MonStats,
d2resource.MonStats2,
d2resource.MonPreset,
d2resource.MonProp,
d2resource.MonType,
d2resource.MonMode,
d2resource.MagicPrefix,
d2resource.MagicSuffix,
d2resource.ItemStatCost,
d2resource.ItemRatio,
d2resource.StorePage,
d2resource.Overlays,
d2resource.CharStats,
d2resource.Hireling,
d2resource.Experience,
d2resource.Gems,
d2resource.QualityItems,
d2resource.Runes,
d2resource.DifficultyLevels,
d2resource.AutoMap,
d2resource.LevelDetails,
d2resource.LevelMaze,
d2resource.LevelSubstitutions,
d2resource.CubeRecipes,
d2resource.SuperUniques,
d2resource.Inventory,
d2resource.Skills,
d2resource.SkillCalc,
d2resource.MissileCalc,
d2resource.Properties,
d2resource.SkillDesc,
d2resource.BodyLocations,
d2resource.Sets,
d2resource.SetItems,
d2resource.AutoMagic,
d2resource.TreasureClass,
d2resource.TreasureClassEx,
d2resource.States,
d2resource.SoundEnvirons,
d2resource.Shrines,
d2resource.ElemType,
d2resource.PlrMode,
d2resource.PetType,
d2resource.NPC,
d2resource.MonsterUniqueModifier,
d2resource.MonsterEquipment,
d2resource.UniqueAppellation,
d2resource.MonsterLevel,
d2resource.MonsterSound,
d2resource.MonsterSequence,
d2resource.PlayerClass,
d2resource.MonsterPlacement,
d2resource.ObjectGroup,
d2resource.CompCode,
d2resource.MonsterAI,
d2resource.RarePrefix,
d2resource.RareSuffix,
d2resource.Events,
d2resource.Colors,
d2resource.ArmorType,
d2resource.WeaponClass,
d2resource.PlayerType,
d2resource.Composite,
d2resource.HitClass,
d2resource.UniquePrefix,
d2resource.UniqueSuffix,
d2resource.CubeModifier,
d2resource.CubeType,
d2resource.HirelingDescription,
d2resource.LevelType, d2resource.LevelPreset, d2resource.LevelWarp,
d2resource.ObjectType, d2resource.ObjectDetails, d2resource.Weapons,
d2resource.Armor, d2resource.Misc, d2resource.Books, d2resource.ItemTypes,
d2resource.UniqueItems, d2resource.Missiles, d2resource.SoundSettings,
d2resource.MonStats, d2resource.MonStats2, d2resource.MonPreset,
d2resource.MonProp, d2resource.MonType, d2resource.MonMode,
d2resource.MagicPrefix, d2resource.MagicSuffix, d2resource.ItemStatCost,
d2resource.ItemRatio, d2resource.StorePage, d2resource.Overlays,
d2resource.CharStats, d2resource.Hireling, d2resource.Experience,
d2resource.Gems, d2resource.QualityItems, d2resource.Runes,
d2resource.DifficultyLevels, d2resource.AutoMap, d2resource.LevelDetails,
d2resource.LevelMaze, d2resource.LevelSubstitutions, d2resource.CubeRecipes,
d2resource.SuperUniques, d2resource.Inventory, d2resource.Skills,
d2resource.SkillCalc, d2resource.MissileCalc, d2resource.Properties,
d2resource.SkillDesc, d2resource.BodyLocations, d2resource.Sets,
d2resource.SetItems, d2resource.AutoMagic, d2resource.TreasureClass,
d2resource.TreasureClassEx, d2resource.States, d2resource.SoundEnvirons,
d2resource.Shrines, d2resource.ElemType, d2resource.PlrMode,
d2resource.PetType, d2resource.NPC, d2resource.MonsterUniqueModifier,
d2resource.MonsterEquipment, d2resource.UniqueAppellation, d2resource.MonsterLevel,
d2resource.MonsterSound, d2resource.MonsterSequence, d2resource.PlayerClass,
d2resource.MonsterPlacement, d2resource.ObjectGroup, d2resource.CompCode,
d2resource.MonsterAI, d2resource.RarePrefix, d2resource.RareSuffix,
d2resource.Events, d2resource.Colors, d2resource.ArmorType,
d2resource.WeaponClass, d2resource.PlayerType, d2resource.Composite,
d2resource.HitClass, d2resource.UniquePrefix, d2resource.UniqueSuffix,
d2resource.CubeModifier, d2resource.CubeType, d2resource.HirelingDescription,
d2resource.LowQualityItems,
}
am.logger.Info("Initializing asset manager")
for _, path := range dictPaths {
err := am.LoadRecords(path)
if err != nil {
@ -166,11 +108,26 @@ func (am *AssetManager) initDataDictionaries() error {
return nil
}
const (
logPrefix = "Asset Manager"
fmtLoadAsset = "could not load file stream %s (%v)"
fmtLoadAnimation = "loading animation %s with palette %s, draw effect %d"
fmtLoadComposite = "loading composite: type %d, token %s, palette %s"
fmtLoadFont = "loading font: table %s, sprite %s, palette %s"
fmtLoadPalette = "loading palette %s"
fmtLoadStringTable = "loading string table: %s"
fmtLoadTransform = "loading palette transform: %s"
fmtLoadDict = "loading data dictionary: %s"
fmtLoadAnimData = "loading animation data from: %s"
)
// LoadAsset loads an asset
func (am *AssetManager) LoadAsset(filePath string) (asset.Asset, error) {
data, err := am.loader.Load(filePath)
if err != nil {
log.Printf("error loading file stream %s (%v)", filePath, err.Error())
errStr := fmt.Sprintf(fmtLoadAsset, filePath, err.Error())
am.logger.Error(errStr)
}
return data, err
@ -219,6 +176,8 @@ func (am *AssetManager) LoadAnimationWithEffect(animationPath, palettePath strin
return animation.(d2interface.Animation).Clone(), nil
}
am.logger.Debug(fmt.Sprintf(fmtLoadAnimation, animationPath, palettePath, effect))
animAsset, err := am.LoadAsset(animationPath)
if err != nil {
return nil, err
@ -253,6 +212,8 @@ func (am *AssetManager) LoadAnimationWithEffect(animationPath, palettePath strin
// LoadComposite creates a composite object from a ObjectLookupRecord and palettePath describing it
func (am *AssetManager) LoadComposite(baseType d2enum.ObjectType, token, palettePath string) (*Composite, error) {
am.logger.Debug(fmt.Sprintf(fmtLoadComposite, baseType, token, palettePath))
c := &Composite{
AssetManager: am,
baseType: baseType,
@ -288,6 +249,8 @@ func (am *AssetManager) LoadFont(tablePath, spritePath, palettePath string) (*Fo
return nil, fmt.Errorf("invalid font table format: %s", tablePath)
}
am.logger.Debug(fmt.Sprintf(fmtLoadFont, tablePath, spritePath, palettePath))
font := &Font{
table: tableData,
sheet: sheet,
@ -314,6 +277,8 @@ func (am *AssetManager) LoadPalette(palettePath string) (d2interface.Palette, er
return nil, fmt.Errorf("not an instance of a palette: %s", palettePath)
}
am.logger.Debug(fmt.Sprintf(fmtLoadPalette, palettePath))
data, err := am.LoadFile(palettePath)
if err != nil {
return nil, err
@ -345,6 +310,8 @@ func (am *AssetManager) LoadStringTable(tablePath string) (d2tbl.TextDictionary,
return nil, fmt.Errorf("table not found: %s", tablePath)
}
am.logger.Debug(fmt.Sprintf(fmtLoadStringTable, tablePath))
err = am.tables.Insert(tablePath, table, defaultCacheEntryWeight)
return table, err
@ -366,6 +333,8 @@ func (am *AssetManager) LoadPaletteTransform(path string) (*d2pl2.PL2, error) {
return nil, err
}
am.logger.Debug(fmt.Sprintf(fmtLoadTransform, path))
if err := am.transforms.Insert(path, pl2, 1); err != nil {
return nil, err
}
@ -386,6 +355,8 @@ func (am *AssetManager) LoadDataDictionary(path string) (*d2txt.DataDictionary,
return nil, err
}
am.logger.Debug(fmt.Sprintf(fmtLoadDict, path))
return d2txt.LoadDataDictionary(data), nil
}
@ -450,8 +421,12 @@ func (am *AssetManager) initAnimationData(path string) error {
return err
}
am.logger.Debug(fmt.Sprintf(fmtLoadAnimData, path))
animData := d2data.LoadAnimationData(animDataBytes)
am.logger.Infof("Loaded %d animation data records", len(animData))
am.Records.Animation.Data = animData
return nil

View File

@ -3,23 +3,38 @@ package d2asset
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2cache"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2loader"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2records"
)
// NewAssetManager creates and assigns all necessary dependencies for the AssetManager top-level functions to work correctly
func NewAssetManager(config *d2config.Configuration) (*AssetManager, error) {
func NewAssetManager(config *d2config.Configuration, l d2util.LogLevel) (*AssetManager, error) {
loader, err := d2loader.NewLoader(config, l)
if err != nil {
return nil, err
}
records, err := d2records.NewRecordManager(l)
if err != nil {
return nil, err
}
manager := &AssetManager{
d2loader.NewLoader(config),
d2util.NewLogger(),
loader,
d2cache.CreateCache(tableBudget),
d2cache.CreateCache(animationBudget),
d2cache.CreateCache(fontBudget),
d2cache.CreateCache(paletteBudget),
d2cache.CreateCache(paletteTransformBudget),
&d2records.RecordManager{},
records,
}
err := manager.init()
manager.logger.SetPrefix(logPrefix)
manager.logger.SetLevel(l)
err = manager.init()
if err != nil {
return nil, err
}

View File

@ -2,11 +2,11 @@ package d2config
import (
"encoding/json"
"errors"
"log"
"os"
"path"
"strings"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
)
// Config holds the configuration from config.json
@ -25,12 +25,19 @@ type Configuration struct {
RunInBackground bool
VsyncEnabled bool
Backend string
LogLevel d2util.LogLevel
path string
}
// Load loads a configuration object from disk
func Load() error {
Config = new(Configuration)
return Config.Load()
if Config.Load() != nil {
return Config.Save()
}
return nil
}
// Load loads a configuration object from disk
@ -60,9 +67,7 @@ func (c *Configuration) Load() error {
return err
}
if err := verifyMpqFileReferences(); err != nil {
return err
}
c.path = configPath
return nil
}
@ -71,10 +76,6 @@ func (c *Configuration) Load() error {
Config = defaultConfig()
if err := verifyMpqFileReferences(); err != nil {
return err
}
return Config.Save()
}
@ -105,6 +106,15 @@ func (c *Configuration) Save() error {
return configFile.Close()
}
// Path returns the path of the config file
func (c *Configuration) Path() string {
if c.path == "" {
c.path = defaultConfigPath()
}
return c.path
}
func defaultConfigPath() string {
if configDir, err := os.UserConfigDir(); err == nil {
return path.Join(configDir, "OpenDiablo2", "config.json")
@ -116,29 +126,3 @@ func defaultConfigPath() string {
func localConfigPath() string {
return path.Join(path.Dir(os.Args[0]), "config.json")
}
func verifyMpqFileReferences() error {
badFiles := []string{}
for fileIdx := range Config.MpqLoadOrder {
actualPath := path.Join(Config.MpqPath, Config.MpqLoadOrder[fileIdx])
info, err := os.Stat(actualPath)
if !os.IsNotExist(err) {
continue
}
if info != nil && !info.IsDir() {
continue
}
badFiles = append(badFiles, actualPath)
}
if len(badFiles) > 0 {
return errors.New("The following MPQ file(s) could not be found:\n" + strings.Join(badFiles, "\n") +
"\n\nPlease check your configuration file located at:\n" + defaultConfigPath())
}
return nil
}

View File

@ -4,6 +4,8 @@ import (
"os/user"
"path"
"runtime"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
)
func defaultConfig() *Configuration {
@ -35,6 +37,7 @@ func defaultConfig() *Configuration {
"d2video.mpq",
"d2speech.mpq",
},
LogLevel: d2util.LogLevelDefault,
}
switch runtime.GOOS {

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -24,7 +22,7 @@ func armorTypesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Animation.Token.Armor = records
log.Printf("Loaded %d ArmorType records", len(records))
r.Logger.Infof("Loaded %d ArmorType records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -81,7 +79,7 @@ func autoMagicLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d AutoMagic records", len(records))
r.Logger.Infof("Loaded %d AutoMagic records", len(records))
r.Item.AutoMagic = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -39,7 +37,7 @@ func autoMapLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d AutoMapRecord records", len(records))
r.Logger.Infof("Loaded %d AutoMapRecord records", len(records))
r.Level.AutoMaps = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -104,7 +102,7 @@ func beltsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d belts", len(records))
r.Logger.Infof("Loaded %d belts", len(records))
r.Item.Belts = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -21,7 +19,7 @@ func bodyLocationsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
panic(d.Err)
}
log.Printf("Loaded %d Body Location records", len(records))
r.Logger.Infof("Loaded %d Body Location records", len(records))
r.BodyLocations = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -30,7 +28,7 @@ func booksLoader(r *RecordManager, d *d2txt.DataDictionary) error {
panic(d.Err)
}
log.Printf("Loaded %d book items", len(records))
r.Logger.Infof("Loaded %d book items", len(records))
r.Item.Books = records

View File

@ -1,18 +1,16 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
func skillCalcLoader(r *RecordManager, d *d2txt.DataDictionary) error {
records, err := loadCalculations(d)
records, err := loadCalculations(r, d)
if err != nil {
return err
}
log.Printf("Loaded %d Skill Calculation records", len(records))
r.Logger.Infof("Loaded %d Skill Calculation records", len(records))
r.Calculation.Skills = records
@ -20,19 +18,19 @@ func skillCalcLoader(r *RecordManager, d *d2txt.DataDictionary) error {
}
func missileCalcLoader(r *RecordManager, d *d2txt.DataDictionary) error {
records, err := loadCalculations(d)
records, err := loadCalculations(r, d)
if err != nil {
return err
}
log.Printf("Loaded %d Missile Calculation records", len(records))
r.Logger.Infof("Loaded %d Missile Calculation records", len(records))
r.Calculation.Missiles = records
return nil
}
func loadCalculations(d *d2txt.DataDictionary) (Calculations, error) {
func loadCalculations(r *RecordManager, d *d2txt.DataDictionary) (Calculations, error) {
records := make(Calculations)
for d.Next() {
@ -47,7 +45,7 @@ func loadCalculations(d *d2txt.DataDictionary) (Calculations, error) {
return nil, d.Err
}
log.Printf("Loaded %d Skill Calculation records", len(records))
r.Logger.Infof("Loaded %d Skill Calculation records", len(records))
return records, nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -138,7 +136,7 @@ func charStatsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d CharStats records", len(records))
r.Logger.Infof("Loaded %d CharStats records", len(records))
r.Character.Stats = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -24,7 +22,7 @@ func colorsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Colors = records
log.Printf("Loaded %d Color records", len(records))
r.Logger.Infof("Loaded %d Color records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -21,7 +19,7 @@ func componentCodesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d ComponentCode records", len(records))
r.Logger.Infof("Loaded %d ComponentCode records", len(records))
r.ComponentCodes = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -24,7 +22,7 @@ func compositeTypeLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Animation.Token.Composite = records
log.Printf("Loaded %d Composite Type records", len(records))
r.Logger.Infof("Loaded %d Composite Type records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -24,7 +22,7 @@ func cubeModifierLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.Cube.Modifiers = records
log.Printf("Loaded %d Cube Modifier records", len(records))
r.Logger.Infof("Loaded %d Cube Modifier records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -24,7 +22,7 @@ func cubeTypeLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.Cube.Types = records
log.Printf("Loaded %d Cube Type records", len(records))
r.Logger.Infof("Loaded %d Cube Type records", len(records))
return nil
}

View File

@ -83,7 +83,7 @@ func cubeRecipeLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d CubeMainRecord records", len(records))
r.Logger.Infof("Loaded %d CubeMainRecord records", len(records))
r.Item.Cube.Recipes = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -36,7 +34,7 @@ func difficultyLevelsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d DifficultyLevel records", len(records))
r.Logger.Infof("Loaded %d DifficultyLevel records", len(records))
r.DifficultyLevels = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -22,7 +20,7 @@ func elemTypesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d ElemType records", len(records))
r.Logger.Infof("Loaded %d ElemType records", len(records))
r.ElemTypes = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -22,7 +20,7 @@ func eventsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d Event records", len(records))
r.Logger.Infof("Loaded %d Event records", len(records))
r.Character.Events = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -70,7 +68,7 @@ func experienceLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d Experience Breakpoint records", len(breakpoints))
r.Logger.Infof("Loaded %d Experience Breakpoint records", len(breakpoints))
r.Character.MaxLevel = maxLevels
r.Character.Experience = breakpoints

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -21,7 +19,7 @@ func gambleLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d gamble records", len(records))
r.Logger.Infof("Loaded %d gamble records", len(records))
r.Gamble = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -62,7 +60,7 @@ func gemsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d Gems records", len(records))
r.Logger.Infof("Loaded %d Gems records", len(records))
r.Item.Gems = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -24,7 +22,7 @@ func hirelingDescriptionLoader(r *RecordManager, d *d2txt.DataDictionary) error
r.Hireling.Descriptions = records
log.Printf("Loaded %d Hireling Descriptions records", len(records))
r.Logger.Infof("Loaded %d Hireling Descriptions records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -92,7 +90,7 @@ func hirelingLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d Hireling records", len(records))
r.Logger.Infof("Loaded %d Hireling records", len(records))
r.Hireling.Details = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -24,7 +22,7 @@ func hitClassLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Animation.Token.HitClass = records
log.Printf("Loaded %d HitClass records", len(records))
r.Logger.Infof("Loaded %d HitClass records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -132,7 +130,7 @@ func inventoryLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d Inventory Panel records", len(records))
r.Logger.Infof("Loaded %d Inventory Panel records", len(records))
r.Layout.Inventory = records

View File

@ -2,7 +2,6 @@ package d2records
import (
"fmt"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
@ -14,7 +13,7 @@ func magicPrefixLoader(r *RecordManager, d *d2txt.DataDictionary) error {
subType := d2enum.ItemAffixMagic
affixes, groups, err := loadAffixDictionary(d, superType, subType)
affixes, groups, err := loadAffixDictionary(r, d, superType, subType)
if err != nil {
return err
}
@ -31,7 +30,7 @@ func magicSuffixLoader(r *RecordManager, d *d2txt.DataDictionary) error {
subType := d2enum.ItemAffixMagic
affixes, groups, err := loadAffixDictionary(d, superType, subType)
affixes, groups, err := loadAffixDictionary(r, d, superType, subType)
if err != nil {
return err
}
@ -60,6 +59,7 @@ func getAffixString(t1 d2enum.ItemAffixSuperType, t2 d2enum.ItemAffixSubType) st
}
func loadAffixDictionary(
r *RecordManager,
d *d2txt.DataDictionary,
superType d2enum.ItemAffixSuperType,
subType d2enum.ItemAffixSubType,
@ -70,7 +70,7 @@ func loadAffixDictionary(
}
name := getAffixString(superType, subType)
log.Printf("Loaded %d %s records", len(records), name)
r.Logger.Infof("Loaded %d %s records", len(records), name)
return records, groups, nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
@ -18,7 +16,7 @@ func armorLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return err
}
log.Printf("Loaded %d armors", len(records))
r.Logger.Infof("Loaded %d armors", len(records))
r.Item.Armors = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -23,7 +21,7 @@ func lowQualityLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.LowQualityPrefixes = records
log.Printf("Loaded %d Low Item Quality records", len(records))
r.Logger.Infof("Loaded %d Low Item Quality records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
@ -15,7 +13,7 @@ func miscItemsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return err
}
log.Printf("Loaded %d misc items", len(records))
r.Logger.Infof("Loaded %d misc items", len(records))
r.Item.Misc = records

View File

@ -1,7 +1,6 @@
package d2records
import (
"log"
"strconv"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
@ -46,7 +45,7 @@ func itemQualityLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.Quality = records
log.Printf("Loaded %d ItemQualities records", len(records))
r.Logger.Infof("Loaded %d ItemQualities records", len(records))
return nil
}

View File

@ -1,7 +1,6 @@
package d2records
import (
"log"
"strconv"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
@ -56,7 +55,7 @@ func itemRatioLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d ItemRatio records", len(records))
r.Logger.Infof("Loaded %d ItemRatio records", len(records))
r.Item.Ratios = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -78,7 +76,7 @@ func itemTypesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d ItemType records", len(records))
r.Logger.Infof("Loaded %d ItemType records", len(records))
r.Item.Types = records
r.Item.Equivalency = equivMap

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
@ -15,7 +13,7 @@ func weaponsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return err
}
log.Printf("Loaded %d weapons", len(records))
r.Logger.Infof("Loaded %d weapons", len(records))
r.Item.Weapons = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -97,7 +95,7 @@ func itemStatCostLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d ItemStatCost records", len(records))
r.Logger.Infof("Loaded %d ItemStatCost records", len(records))
r.Item.Stats = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
@ -167,7 +165,7 @@ func levelDetailsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d LevelDetails records", len(records))
r.Logger.Infof("Loaded %d LevelDetails records", len(records))
r.Level.Details = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -26,7 +24,7 @@ func levelMazeDetailsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d LevelMazeDetails records", len(records))
r.Logger.Infof("Loaded %d LevelMazeDetails records", len(records))
r.Level.Maze = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -44,7 +42,7 @@ func levelPresetLoader(r *RecordManager, d *d2txt.DataDictionary) error {
records[record.DefinitionID] = record
}
log.Printf("Loaded %d level presets", len(records))
r.Logger.Infof("Loaded %d level presets", len(records))
if d.Err != nil {
return d.Err

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -42,7 +40,7 @@ func levelSubstitutionsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d LevelSubstitution records", len(records))
r.Logger.Infof("Loaded %d LevelSubstitution records", len(records))
r.Level.Sub = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -60,7 +58,7 @@ func levelTypesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d LevelType records", len(records))
r.Logger.Infof("Loaded %d LevelType records", len(records))
r.Level.Types = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -32,7 +30,7 @@ func levelWarpsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d level warps", len(records))
r.Logger.Infof("Loaded %d level warps", len(records))
r.Level.Warp = records

View File

@ -1,7 +1,6 @@
package d2records
import (
"log"
"strings"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
@ -305,7 +304,7 @@ func missilesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d Missile Records", len(records))
r.Logger.Infof("Loaded %d Missile Records", len(records))
r.Missiles = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -21,7 +19,7 @@ func monsterAiLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d MonsterAI records", len(records))
r.Logger.Infof("Loaded %d MonsterAI records", len(records))
r.Monster.AI = records

View File

@ -2,7 +2,6 @@ package d2records
import (
"fmt"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -50,7 +49,7 @@ func monsterEquipmentLoader(r *RecordManager, d *d2txt.DataDictionary) error {
length += len(records[k])
}
log.Printf("Loaded %d MonsterEquipment records", length)
r.Logger.Infof("Loaded %d MonsterEquipment records", length)
r.Monster.Equipment = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -54,7 +52,7 @@ func monsterLevelsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d MonsterLevel records", len(records))
r.Logger.Infof("Loaded %d MonsterLevel records", len(records))
r.Monster.Levels = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -23,7 +21,7 @@ func monsterModeLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d MonMode records", len(records))
r.Logger.Infof("Loaded %d MonMode records", len(records))
r.Monster.Modes = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -20,7 +18,7 @@ func monsterPlacementsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Monster.Placements = records
log.Printf("Loaded %d MonsterPlacement records", len(records))
r.Logger.Infof("Loaded %d MonsterPlacement records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -23,7 +21,7 @@ func monsterPresetLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d MonPreset records", len(records))
r.Logger.Infof("Loaded %d MonPreset records", len(records))
r.Monster.Presets = records

View File

@ -2,7 +2,6 @@ package d2records
import (
"fmt"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -58,7 +57,7 @@ func monsterPropertiesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d MonProp records", len(records))
r.Logger.Infof("Loaded %d MonProp records", len(records))
r.Monster.Props = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -33,7 +31,7 @@ func monsterSequencesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d MonsterSequence records", len(records))
r.Logger.Infof("Loaded %d MonsterSequence records", len(records))
r.Monster.Sequences = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -59,7 +57,7 @@ func monsterSoundsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d Monster Sound records", len(records))
r.Logger.Infof("Loaded %d Monster Sound records", len(records))
r.Monster.Sounds = records

View File

@ -156,7 +156,7 @@ func monsterStats2Loader(r *RecordManager, d *d2txt.DataDictionary) error {
panic(d.Err)
}
log.Printf("Loaded %d MonStats2 records", len(records))
r.Logger.Infof("Loaded %d MonStats2 records", len(records))
r.Monster.Stats2 = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -274,7 +272,7 @@ func monsterStatsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d MonStats records", len(records))
r.Logger.Infof("Loaded %d MonStats records", len(records))
r.Monster.Stats = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -42,7 +40,7 @@ func monsterSuperUniqeLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Monster.Unique.Super = records
log.Printf("Loaded %d SuperUnique records", len(records))
r.Logger.Infof("Loaded %d SuperUnique records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -25,7 +23,7 @@ func monsterTypesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
panic(d.Err)
}
log.Printf("Loaded %d MonType records", len(records))
r.Logger.Infof("Loaded %d MonType records", len(records))
r.Monster.Types = records

View File

@ -2,7 +2,6 @@ package d2records
import (
"fmt"
"log"
"github.com/gravestench/akara"
@ -60,7 +59,7 @@ func uniqueMonsterPrefixLoader(r *RecordManager, d *d2txt.DataDictionary) error
r.Monster.Name.Prefix = records
log.Printf("Loaded %d unique monster prefix records", len(records))
r.Logger.Infof("Loaded %d unique monster prefix records", len(records))
return nil
}
@ -73,7 +72,7 @@ func uniqueMonsterSuffixLoader(r *RecordManager, d *d2txt.DataDictionary) error
r.Monster.Name.Suffix = records
log.Printf("Loaded %d unique monster suffix records", len(records))
r.Logger.Infof("Loaded %d unique monster suffix records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -50,7 +48,7 @@ func monsterUniqModifiersLoader(r *RecordManager, d *d2txt.DataDictionary) error
return d.Err
}
log.Printf("Loaded %d MonsterUniqueModifier records", len(records))
r.Logger.Infof("Loaded %d MonsterUniqueModifier records", len(records))
r.Monster.Unique.Mods = records
r.Monster.Unique.Constants = constants

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -66,7 +64,7 @@ func npcLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.NPCs = records
log.Printf("Loaded %d NPC records", len(records))
r.Logger.Infof("Loaded %d NPC records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -227,7 +225,7 @@ func objectDetailsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d objects", len(records))
r.Logger.Infof("Loaded %d objects", len(records))
r.Object.Details = records

View File

@ -2,7 +2,6 @@ package d2records
import (
"fmt"
"log"
"strconv"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
@ -33,7 +32,7 @@ func objectGroupsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d ObjectGroup records", len(records))
r.Logger.Infof("Loaded %d ObjectGroup records", len(records))
return nil
}

View File

@ -4,6 +4,8 @@ import (
"log"
"testing"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
testify "github.com/stretchr/testify/assert"
@ -13,7 +15,7 @@ import (
func TestIndexObjects(t *testing.T) {
assert := testify.New(t)
r, err := NewRecordManager()
r, err := NewRecordManager(d2util.LogLevelDefault)
if err != nil {
log.Print(err)
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -24,7 +22,7 @@ func objectModesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Object.Modes = records
log.Printf("Loaded %d ObjectMode records", len(records))
r.Logger.Infof("Loaded %d ObjectMode records", len(records))
return nil
}

View File

@ -1,7 +1,6 @@
package d2records
import (
"log"
"strings"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
@ -24,7 +23,7 @@ func objectTypesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d object types", len(records))
r.Logger.Infof("Loaded %d object types", len(records))
r.Object.Types = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -37,7 +35,7 @@ func overlaysLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d Overlay records", len(records))
r.Logger.Infof("Loaded %d Overlay records", len(records))
r.Layout.Overlays = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -41,7 +39,7 @@ func petTypesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d PetType records", len(records))
r.Logger.Infof("Loaded %d PetType records", len(records))
r.PetTypes = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -31,7 +29,7 @@ func playerClassLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return d.Err
}
log.Printf("Loaded %d PlayerClass records", len(records))
r.Logger.Infof("Loaded %d PlayerClass records", len(records))
r.Character.Classes = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -25,7 +23,7 @@ func playerModesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Character.Modes = records
log.Printf("Loaded %d PlayerMode records", len(records))
r.Logger.Infof("Loaded %d PlayerMode records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -26,7 +24,7 @@ func playerTypeLoader(r *RecordManager, d *d2txt.DataDictionary) error {
panic(d.Err)
}
log.Printf("Loaded %d PlayerType records", len(records))
r.Logger.Infof("Loaded %d PlayerType records", len(records))
r.Animation.Token.Player = records

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -69,7 +67,7 @@ func propertyLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Properties = records
log.Printf("Loaded %d Property records", len(records))
r.Logger.Infof("Loaded %d Property records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -14,7 +12,7 @@ func rareItemPrefixLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.Rare.Prefix = records
log.Printf("Loaded %d RarePrefix records", len(records))
r.Logger.Infof("Loaded %d RarePrefix records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -12,7 +10,7 @@ func rareItemSuffixLoader(r *RecordManager, d *d2txt.DataDictionary) error {
return err
}
log.Printf("Loaded %d RareSuffix records", len(records))
r.Logger.Infof("Loaded %d RareSuffix records", len(records))
r.Item.Rare.Suffix = records

View File

@ -4,6 +4,8 @@ import (
"fmt"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2util"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
@ -11,12 +13,20 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
)
const (
logPrefix = "Record Manager"
)
// NewRecordManager creates a new record manager (no loaders are bound!)
func NewRecordManager() (*RecordManager, error) {
func NewRecordManager(l d2util.LogLevel) (*RecordManager, error) {
rm := &RecordManager{
boundLoaders: make(map[string][]recordLoader),
}
rm.Logger = d2util.NewLogger()
rm.Logger.SetPrefix(logPrefix)
rm.Logger.SetLevel(l)
err := rm.init()
if err != nil {
return nil, err
@ -27,6 +37,7 @@ func NewRecordManager() (*RecordManager, error) {
// RecordManager stores all of the records loaded from txt files
type RecordManager struct {
Logger *d2util.Logger
boundLoaders map[string][]recordLoader // there can be more than one loader bound for a file
Animation struct {
Data d2data.AnimationData

View File

@ -2,7 +2,6 @@ package d2records
import (
"fmt"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -90,7 +89,7 @@ func runewordLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.Runewords = records
log.Printf("Loaded %d records records", len(records))
r.Logger.Infof("Loaded %d records records", len(records))
return nil
}

View File

@ -2,7 +2,6 @@ package d2records
import (
"fmt"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -95,7 +94,7 @@ func setItemLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.SetItems = records
log.Printf("Loaded %d SetItem records", len(records))
r.Logger.Infof("Loaded %d SetItem records", len(records))
return nil
}

View File

@ -2,7 +2,6 @@ package d2records
import (
"fmt"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -108,7 +107,7 @@ func setLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.Sets = records
log.Printf("Loaded %d records records", len(records))
r.Logger.Infof("Loaded %d records records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -33,7 +31,7 @@ func shrineLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Object.Shrines = records
log.Printf("Loaded %d shrines", len(records))
r.Logger.Infof("Loaded %d shrines", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2calculation/d2parser"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -141,7 +139,7 @@ func skillDescriptionLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Skill.Descriptions = records
log.Printf("Loaded %d Skill Description records", len(records))
r.Logger.Infof("Loaded %d Skill Description records", len(records))
return nil
}

View File

@ -272,7 +272,7 @@ func skillDetailsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Skill.Details = records
log.Printf("Loaded %d Skill records", len(records))
r.Logger.Infof("Loaded %d Skill records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -48,7 +46,7 @@ func soundDetailsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Sound.Details = records
log.Printf("Loaded %d sound definitions", len(records))
r.Logger.Infof("Loaded %d sound definitions", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -46,7 +44,7 @@ func soundEnvironmentLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Sound.Environment = records
log.Printf("Loaded %d SoundEnviron records", len(records))
r.Logger.Infof("Loaded %d SoundEnviron records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -91,7 +89,7 @@ func statesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.States = records
log.Printf("Loaded %d State records", len(records))
r.Logger.Infof("Loaded %d State records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -23,7 +21,7 @@ func storePagesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.StorePages = records
log.Printf("Loaded %d StorePage records", len(records))
r.Logger.Infof("Loaded %d StorePage records", len(records))
return nil
}

View File

@ -2,7 +2,6 @@ package d2records
import (
"fmt"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -21,7 +20,7 @@ func treasureClassLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.Treasure.Normal = records
log.Printf("Loaded %d treasure class (normal) records", len(records))
r.Logger.Infof("Loaded %d treasure class (normal) records", len(records))
return nil
}
@ -34,7 +33,7 @@ func treasureClassExLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.Treasure.Expansion = records
log.Printf("Loaded %d treasure class (expansion) records", len(records))
r.Logger.Infof("Loaded %d treasure class (expansion) records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -23,7 +21,7 @@ func uniqueAppellationsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Monster.Unique.Appellations = records
log.Printf("Loaded %d UniqueAppellation records", len(records))
r.Logger.Infof("Loaded %d UniqueAppellation records", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -130,7 +128,7 @@ func uniqueItemsLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Item.Unique = records
log.Printf("Loaded %d unique items", len(records))
r.Logger.Infof("Loaded %d unique items", len(records))
return nil
}

View File

@ -1,8 +1,6 @@
package d2records
import (
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2txt"
)
@ -24,7 +22,7 @@ func weaponClassesLoader(r *RecordManager, d *d2txt.DataDictionary) error {
r.Animation.Token.Weapon = records
log.Printf("Loaded %d WeaponClass records", len(records))
r.Logger.Infof("Loaded %d WeaponClass records", len(records))
return nil
}

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"log"
"github.com/OpenDiablo2/OpenDiablo2/d2app"
@ -22,7 +21,6 @@ func main() {
instance := d2app.Create(GitBranch, GitCommit)
if err := instance.Run(); err != nil {
fmt.Println(err)
return
}
}