more refactoring of db files

This commit is contained in:
2024-08-21 23:38:01 -04:00
parent cd3715b13f
commit 8ae06df805
8 changed files with 26 additions and 400 deletions

View File

@@ -1,90 +1,8 @@
package creatures
import (
"errors"
"fmt"
"github.com/araxiaonline/endgame-item-generator/import/utils"
"github.com/araxiaonline/endgame-item-generator/internal/pkg/db"
_ "github.com/go-sql-driver/mysql"
_ "github.com/jmoiron/sqlx"
)
type Boss struct {
Entry int
Name string
ScriptName string `db:"ScriptName"`
ExperienceModifier int `db:"ExperienceModifier"`
}
type MySql struct {
*db.MySql
}
// NewMySql initializes the MySql struct with the MySQL connection instance
func NewMySql() (*MySql, error) {
client, err := db.ConnectMySql(nil)
if err != nil {
return nil, err
}
return &MySql{MySql: client}, nil
}
func (db Database) GetBossLoot(bossId int) ([]Item, error) {
if bossId == 0 {
return nil, errors.New("bossId cannot be 0")
}
// This will first find items that are not in the reference boss loot table
items := []Item{}
sql := `
SELECT ` + utils.GetItemFields("") + `
from acore_world.item_template
where
entry in
(SELECT item from acore_world.creature_loot_template where entry = ? and GroupId != 0 and Reference = 0)
and Quality > 2
`
udb := db.client.Unsafe()
err := udb.Select(&items, sql, bossId)
if err != nil {
return nil, err
}
// Get all the boss reference items now
var references []int
sql = `
SELECT reference
FROM acore_world.creature_loot_template
WHERE entry = ? AND Reference != 0
`
err = db.client.Select(&references, sql, bossId)
if err != nil {
return nil, fmt.Errorf("failed to get references: %v sql %s", err, sql)
}
if len(references) == 0 {
return items, nil
}
refItems := []Item{}
// For each reference we now need to get the items and add them to the items slice
for _, ref := range references {
sql = `
SELECT ` + utils.GetItemFields("it") + `
FROM acore_world.reference_loot_template rlt
JOIN acore_world.item_template it ON rlt.Item = it.entry
WHERE rlt.Entry = ? and it.Quality > 2 and it.StatsCount > 0
`
err = db.client.Select(&refItems, sql, ref)
if err != nil {
return nil, fmt.Errorf("failed to get ref items: %v sql %s", err, sql)
}
items = append(items, refItems...)
}
return items, nil
}

View File

@@ -1,103 +0,0 @@
package creatures
import (
"errors"
"fmt"
"github.com/araxiaonline/endgame-item-generator/internal/items"
"github.com/araxiaonline/endgame-item-generator/internal/pkg/db"
)
type MySql struct {
*db.MySql
}
func (db *MySql) GetBosses(mapId int) ([]Boss, error) {
if mapId == 0 {
return nil, errors.New("mapId cannot be 0")
}
bosses := []Boss{}
var sql string
// 540 is pre-classic dungeons so XP Multiplier is best way to determine bosses / rare mobs
if mapId < 540 {
sql = `
SELECT ct.entry, ct.name, ct.ScriptName, ct.ExperienceModifier from acore_world.creature c
JOIN acore_world.creature_template ct ON(c.id1 = ct.entry) WHERE map = ? and ExperienceModifier >= 2;
`
} else {
sql = `
SELECT ct.entry, ct.name, ct.ScriptName, ct.ExperienceModifier from acore_world.creature c
JOIN acore_world.creature_template ct ON(c.id1 = ct.entry) WHERE map = ? and ct.ScriptName Like 'boss_%'
`
}
err := db.Select(&bosses, sql, mapId)
if err != nil {
return nil, err
}
return bosses, nil
}
func (db *MySql) GetBossLoot(bossId int) ([]items.Item, error) {
if bossId == 0 {
return nil, errors.New("bossId cannot be 0")
}
// This will first find items that are not in the reference boss loot table
items := []items.Item{}
fields := items.GetItemFields("")
sql := `
SELECT ` + fields + `
from acore_world.item_template
where
entry in
(SELECT item from acore_world.creature_loot_template where entry = ? and GroupId != 0 and Reference = 0)
and Quality > 2
`
udb := db.client.Unsafe()
err := udb.Select(&items, sql, bossId)
if err != nil {
return nil, err
}
// Get all the boss reference items now
var references []int
sql = `
SELECT reference
FROM acore_world.creature_loot_template
WHERE entry = ? AND Reference != 0
`
err = db.client.Select(&references, sql, bossId)
if err != nil {
return nil, fmt.Errorf("failed to get references: %v sql %s", err, sql)
}
if len(references) == 0 {
return items, nil
}
refItems := []items.Item{}
// For each reference we now need to get the items and add them to the items slice
for _, ref := range references {
sql = `
SELECT ` + items.GetItemFields("it") + `
FROM acore_world.reference_loot_template rlt
JOIN acore_world.item_template it ON rlt.Item = it.entry
WHERE rlt.Entry = ? and it.Quality > 2 and it.StatsCount > 0
`
err = db.client.Select(&refItems, sql, ref)
if err != nil {
return nil, fmt.Errorf("failed to get ref items: %v sql %s", err, sql)
}
items = append(items, refItems...)
}
return items, nil
}

View File

@@ -1,16 +1,11 @@
package maps
package mysql
import (
"fmt"
"github.com/araxiaonline/endgame-item-generator/internal/items"
"github.com/araxiaonline/endgame-item-generator/internal/pkg/db"
)
type MySql struct {
*db.MySql
}
type Dungeon struct {
Id int `db:"Id"`
Name string `db:"Name"`
@@ -79,7 +74,7 @@ var dungeonLevels = map[int]int{
668: 80, // Halls of Reflection
}
func (db *MySql) GetDungeons(expansionId int) ([]Dungeon, error) {
func (db *MySqlDb) GetDungeons(expansionId int) ([]Dungeon, error) {
dungeons := []Dungeon{}
sql := `
@@ -109,7 +104,7 @@ func (db *MySql) GetDungeons(expansionId int) ([]Dungeon, error) {
}
// Gets a list of other rare+ items that drop in a specific instance.
func (db *MySql) GetAddlDungeonDrops(instanceId int) ([]items.Item, error) {
func (db *MySqlDb) GetAddlDungeonDrops(instanceId int) ([]items.Item, error) {
fields := items.GetItemFields("it")
var items []items.Item

View File

@@ -1,4 +1,4 @@
package db
package mysql
import (
"os"
@@ -18,9 +18,9 @@ type MySqlConfig struct {
Database string
}
var MySql MySqlDb
var MySql *MySqlDb
func ConnectMySql(config *MySqlConfig) (*MySqlDb, error) {
func Connect(config *MySqlConfig) (*MySqlDb, error) {
if config == nil {
config = &MySqlConfig{
@@ -37,10 +37,10 @@ func ConnectMySql(config *MySqlConfig) (*MySqlDb, error) {
return nil, err
}
Conn = &MySql{client}
return Conn, nil
MySql = &MySqlDb{client}
return MySql, nil
}
func (db *MySql) Close() {
func (db *MySqlDb) Close() {
db.Close()
}

View File

@@ -1,28 +1,24 @@
package spells
package mysql
import (
"fmt"
"strconv"
"github.com/araxiaonline/endgame-item-generator/internal/pkg/db"
"github.com/araxiaonline/endgame-item-generator/internal/spells"
)
type MySql struct {
*db.MySql
}
func (db *MySql) GetSpell(id int) (Spell, error) {
func (db *MySqlDb) GetSpell(id int) (spells.Spell, error) {
if id == 0 {
return Spell{}, fmt.Errorf("id cannot be 0")
return spells.Spell{}, fmt.Errorf("id cannot be 0")
}
spell := Spell{}
spell := spells.Spell{}
sql := "SELECT " + GetSpellFields() + " FROM `spell_dbc` WHERE ID = ? -- " + strconv.Itoa(id)
err := db.Get(&spell, sql, id)
if err != nil {
return Spell{}, fmt.Errorf("failed to get spell: %v", err)
return spells.Spell{}, fmt.Errorf("failed to get spell: %v", err)
}
return spell, nil
@@ -57,7 +53,7 @@ func GetSpellFields() string {
`
}
func SpellToSql(spell Spell, quality int) string {
func SpellToSql(spell spells.Spell, quality int) string {
entryBump := 30000000
if quality == 4 {

View File

@@ -1,4 +1,4 @@
package db
package sqlite
import (
"database/sql"
@@ -10,7 +10,7 @@ type SqlLite struct {
client *sql.DB
}
func ConnectSqlLite(path string) (*SqlLite, error) {
func Connect(path string) (*SqlLite, error) {
client, err := sql.Open("sqlite3", path)
if err != nil {
return nil, err

View File

@@ -9,6 +9,7 @@ import (
"reflect"
"slices"
"github.com/araxiaonline/endgame-item-generator/internal/config"
"github.com/araxiaonline/endgame-item-generator/internal/spells"
)
@@ -259,7 +260,7 @@ func (item *Item) ScaleDPS(level int) (float64, error) {
}
// Create a Map of stat percentages based on the current stat and how budgets are caluated
func (item Item) GetStatPercents(spellStats []ConvItemStat) map[int]*ItemStat {
func (item Item) GetStatPercents(spellStats []spells.ConvItemStat) map[int]*ItemStat {
statMap := make(map[int]*ItemStat)
statBudget := 0.0
@@ -272,7 +273,7 @@ func (item Item) GetStatPercents(spellStats []ConvItemStat) map[int]*ItemStat {
continue
}
adjValue := float64(statValue) / StatModifiers[int(statType)]
adjValue := float64(statValue) / config.StatModifiers[int(statType)]
statBudget += adjValue
statMap[int(statType)] = &ItemStat{
Value: int(statValue),
@@ -302,13 +303,13 @@ func (item Item) GetStatPercents(spellStats []ConvItemStat) map[int]*ItemStat {
}
// get an array of all the spells set on the item
func (item *Item) GetSpells() ([]Spell, error) {
func (item *Item) GetSpells() ([]spells.Spell, error) {
// dont reload for the same item .
if len(item.Spells) > 0 {
return item.Spells, nil
}
spells := []Spell{}
spells := []spells.Spell{}
values := reflect.ValueOf(item)
for i := 1; i < 4; i++ {
spellId := values.Elem().FieldByName(fmt.Sprintf("SpellId%v", i)).Elem().Int()
@@ -320,7 +321,7 @@ func (item *Item) GetSpells() ([]Spell, error) {
continue
}
spell, err := DB.GetSpell(int(spellId))
spell, err := spells.GetSpell(int(spellId))
if err != nil {
log.Printf("failed to get the spell: %v error: %v", spellId, err)
continue
@@ -332,8 +333,8 @@ func (item *Item) GetSpells() ([]Spell, error) {
return spells, nil
}
func (item *Item) GetNonStatSpells() ([]Spell, error) {
nonStatSpells := []Spell{}
func (item *Item) GetNonStatSpells() ([]spells.Spell, error) {
nonStatSpells := []spells.Spell{}
for i := 1; i < 4; i++ {
spellId, err := item.GetField(fmt.Sprintf("SpellId%v", i))

View File

@@ -1,181 +0,0 @@
package items
import (
"fmt"
"github.com/araxiaonline/endgame-item-generator/internal/pkg/db"
)
type MySql struct {
*db.MySql
}
func (db *MySql) GetItem(entry int) (Item, error) {
if entry == 0 {
return Item{}, fmt.Errorf("entry cannot be 0")
}
item := Item{}
sql := "SELECT " + GetItemFields("") + " FROM item_template WHERE entry = ?"
err := db.Get(&item, sql, entry)
if err != nil {
return Item{}, err
}
return item, nil
}
func GetItemFields(prefix string) string {
pre := ""
if prefix != "" {
pre = prefix + "."
}
return `
` + pre + `entry, ` + pre + `name, ` + pre + `displayid,
quality, ItemLevel, class, subclass, inventoryType,
allowableClass, allowableRace,
armor,material,
requiredSkill, requiredLevel,
dmg_min1, dmg_max1,
dmg_min2,dmg_max2,
dmg_type1, dmg_type2,
delay, sheath, MaxDurability,
statsCount,
stat_type1, stat_value1,
stat_type2, stat_value2,
stat_type3, stat_value3,
stat_type4, stat_value4,
stat_type5, stat_value5,
stat_type6, stat_value6,
stat_type7, stat_value7,
stat_type8, stat_value8,
stat_type9, stat_value9,
stat_type10, stat_value10,
spellid_1, spellid_2, spellid_3,
spelltrigger_1, spelltrigger_2, spelltrigger_3`
}
func ItemToSql(item Item, reqLevel int, difficulty int) string {
entryBump := 20000000
spellBump := 30000000
if difficulty == 4 {
entryBump = 21000000
}
if difficulty == 5 {
entryBump = 22000000
}
if *item.Quality == 4 {
spellBump = 31000000
}
if *item.Quality == 5 {
spellBump = 32000000
}
spells := ""
if len(item.Spells) > 0 {
for i, spell := range item.Spells {
spells += spells.SpellToSql(spell, *item.Quality)
item.UpdateField(fmt.Sprintf("SpellId%v", i), spellBump+spell.ID)
}
}
delete := fmt.Sprintf("DELETE FROM acore_world.item_template WHERE entry = %v;", entryBump+item.Entry)
clone := fmt.Sprintf(`
INSERT INTO acore_world.item_template (
entry, class, subclass, SoundOverrideSubclass, name, displayid, Quality, Flags, FlagsExtra, BuyCount,
BuyPrice, SellPrice, InventoryType, AllowableClass, AllowableRace, ItemLevel, RequiredLevel,
RequiredSkill, RequiredSkillRank, requiredspell, requiredhonorrank, RequiredCityRank,
RequiredReputationFaction, RequiredReputationRank, maxcount, stackable, ContainerSlots, StatsCount,
stat_type1, stat_value1, stat_type2, stat_value2, stat_type3, stat_value3, stat_type4, stat_value4,
stat_type5, stat_value5, stat_type6, stat_value6, stat_type7, stat_value7, stat_type8, stat_value8,
stat_type9, stat_value9, stat_type10, stat_value10, ScalingStatDistribution, ScalingStatValue,
dmg_min1, dmg_max1, dmg_type1, dmg_min2, dmg_max2, dmg_type2, armor, holy_res, fire_res, nature_res,
frost_res, shadow_res, arcane_res, delay, ammo_type, RangedModRange, spellid_1, spelltrigger_1,
spellcharges_1, spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, spellid_2,
spelltrigger_2, spellcharges_2, spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2,
spellid_3, spelltrigger_3, spellcharges_3, spellppmRate_3, spellcooldown_3, spellcategory_3,
spellcategorycooldown_3, spellid_4, spelltrigger_4, spellcharges_4, spellppmRate_4, spellcooldown_4,
spellcategory_4, spellcategorycooldown_4, spellid_5, spelltrigger_5, spellcharges_5, spellppmRate_5,
spellcooldown_5, spellcategory_5, spellcategorycooldown_5, bonding, description, PageText, LanguageID,
PageMaterial, startquest, lockid, Material, sheath, RandomProperty, RandomSuffix, block, itemset,
MaxDurability, area, Map, BagFamily, TotemCategory, socketColor_1, socketContent_1, socketColor_2,
socketContent_2, socketColor_3, socketContent_3, socketBonus, GemProperties, RequiredDisenchantSkill,
ArmorDamageModifier, duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, FoodType,
minMoneyLoot, maxMoneyLoot, flagsCustom, VerifiedBuild
)
SELECT
entry + %v, class, subclass, SoundOverrideSubclass, name, displayid, Quality, Flags, FlagsExtra, BuyCount,
BuyPrice, SellPrice, InventoryType, AllowableClass, AllowableRace, ItemLevel, RequiredLevel,
RequiredSkill, RequiredSkillRank, requiredspell, requiredhonorrank, RequiredCityRank,
RequiredReputationFaction, RequiredReputationRank, maxcount, stackable, ContainerSlots, StatsCount,
stat_type1, stat_value1, stat_type2, stat_value2, stat_type3, stat_value3, stat_type4, stat_value4,
stat_type5, stat_value5, stat_type6, stat_value6, stat_type7, stat_value7, stat_type8, stat_value8,
stat_type9, stat_value9, stat_type10, stat_value10, ScalingStatDistribution, ScalingStatValue,
dmg_min1, dmg_max1, dmg_type1, dmg_min2, dmg_max2, dmg_type2, armor, holy_res, fire_res, nature_res,
frost_res, shadow_res, arcane_res, delay, ammo_type, RangedModRange, spellid_1, spelltrigger_1,
spellcharges_1, spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, spellid_2,
spelltrigger_2, spellcharges_2, spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2,
spellid_3, spelltrigger_3, spellcharges_3, spellppmRate_3, spellcooldown_3, spellcategory_3,
spellcategorycooldown_3, spellid_4, spelltrigger_4, spellcharges_4, spellppmRate_4, spellcooldown_4,
spellcategory_4, spellcategorycooldown_4, spellid_5, spelltrigger_5, spellcharges_5, spellppmRate_5,
spellcooldown_5, spellcategory_5, spellcategorycooldown_5, bonding, description, PageText, LanguageID,
PageMaterial, startquest, lockid, Material, sheath, RandomProperty, RandomSuffix, block, itemset,
MaxDurability, area, Map, BagFamily, TotemCategory, socketColor_1, socketContent_1, socketColor_2,
socketContent_2, socketColor_3, socketContent_3, socketBonus, GemProperties, RequiredDisenchantSkill,
ArmorDamageModifier, duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, FoodType,
minMoneyLoot, maxMoneyLoot, flagsCustom, VerifiedBuild
FROM acore_world.item_template as src
WHERE src.entry = %v ON DUPLICATE KEY UPDATE entry = src.entry + %v;
`, entryBump, item.Entry, entryBump)
update := fmt.Sprintf(`
UPDATE acore_world.item_template
SET
Quality = %v,
ItemLevel = %v,
RequiredLevel = %v,
dmg_min1 = %v,
dmg_max1 = %v,
dmg_min2 = %v,
dmg_max2 = %v,
StatsCount = %v,
stat_type1 = %v,
stat_value1 = %v,
stat_type2 = %v,
stat_value2 = %v,
stat_type3 = %v,
stat_value3 = %v,
stat_type4 = %v,
stat_value4 = %v,
stat_type5 = %v,
stat_value5 = %v,
stat_type6 = %v,
stat_value6 = %v,
stat_type7 = %v,
stat_value7 = %v,
stat_type8 = %v,
stat_value8 = %v,
stat_type9 = %v,
stat_value9 = %v,
stat_type10 = %v,
stat_value10 = %v,
spellid_1 = %v,
spellid_2 = %v,
spellid_3 = %v,
RequiredDisenchantSkill = %v,
DisenchantID = %v,
SellPrice = FLOOR(100000 + (RAND() * 400001)),
Armor = %v
WHERE entry = %v;
`, *item.Quality, *item.ItemLevel, reqLevel, *item.MinDmg1, *item.MaxDmg1, *item.MinDmg2, *item.MaxDmg2, *item.StatsCount,
*item.StatType1, *item.StatValue1, *item.StatType2, *item.StatValue2, *item.StatType3, *item.StatValue3, *item.StatType4, *item.StatValue4,
*item.StatType5, *item.StatValue5, *item.StatType6, *item.StatValue6, *item.StatType7, *item.StatValue7, *item.StatType8, *item.StatValue8,
*item.StatType9, *item.StatValue9, *item.StatType10, *item.StatValue10, *item.SpellId1, *item.SpellId2, *item.SpellId3, 375,
68, *item.Armor, entryBump+item.Entry)
return fmt.Sprintf("%s %s \n %s \n %s", spells, delete, clone, update)
}