Files

200 lines
7.1 KiB
Go

package transfer
import (
"bamort/database"
"bamort/models"
"fmt"
"time"
)
// CharacterExport contains all data needed to export and import a character
type CharacterExport struct {
Character models.Char `json:"character"`
GSMSkills []models.Skill `json:"gsm_skills"`
GSMWeaponSkills []models.WeaponSkill `json:"gsm_weapon_skills"`
GSMSpells []models.Spell `json:"gsm_spells"`
GSMWeapons []models.Weapon `json:"gsm_weapons"`
GSMEquipment []models.Equipment `json:"gsm_equipment"`
GSMContainers []models.Container `json:"gsm_containers"`
LearningData LearningDataExport `json:"learning_data"`
AuditLogEntries []models.AuditLogEntry `json:"audit_log_entries"`
}
// LearningDataExport contains all learning-related master data
type LearningDataExport struct {
Sources []models.Source `json:"sources"`
CharacterClasses []models.CharacterClass `json:"character_classes"`
SkillCategories []models.SkillCategory `json:"skill_categories"`
SkillDifficulties []models.SkillDifficulty `json:"skill_difficulties"`
SpellSchools []models.SpellSchool `json:"spell_schools"`
ClassCategoryEPCosts []models.ClassCategoryEPCost `json:"class_category_ep_costs"`
ClassSpellSchoolEPCosts []models.ClassSpellSchoolEPCost `json:"class_spell_school_ep_costs"`
SpellLevelLECosts []models.SpellLevelLECost `json:"spell_level_le_costs"`
SkillCategoryDifficulties []models.SkillCategoryDifficulty `json:"skill_category_difficulties"`
SkillImprovementCosts []models.SkillImprovementCost `json:"skill_improvement_costs"`
}
// ExportCharacter exports a complete character with all related data
func ExportCharacter(characterID uint) (*CharacterExport, error) {
var char models.Char
// Load character with all relations
err := database.DB.
Preload("User").
Preload("Lp").
Preload("Ap").
Preload("B").
Preload("Merkmale").
Preload("Eigenschaften").
Preload("Fertigkeiten").
Preload("Waffenfertigkeiten").
Preload("Zauber").
Preload("Bennies").
Preload("Vermoegen").
Preload("Erfahrungsschatz").
Preload("Waffen").
Preload("Behaeltnisse").
Preload("Transportmittel").
Preload("Ausruestung").
First(&char, characterID).Error
if err != nil {
return nil, fmt.Errorf("failed to load character: %w", err)
}
// Remove sensitive user information from export
char.User.PasswordHash = ""
char.User.UpdatedAt = time.Time{}
char.User.ResetPwHash = nil
char.User.ResetPwHashExpires = nil
export := &CharacterExport{
Character: char,
}
// Collect GSM skill data
export.GSMSkills = make([]models.Skill, 0)
export.GSMWeaponSkills = make([]models.WeaponSkill, 0)
skillNames := make(map[string]bool)
for _, skill := range char.Fertigkeiten {
if !skillNames[skill.Name] {
var gsmSkill models.Skill
err := gsmSkill.First(skill.Name)
if err == nil && gsmSkill.ID != 0 {
export.GSMSkills = append(export.GSMSkills, gsmSkill)
skillNames[skill.Name] = true
}
}
}
weaponSkillNames := make(map[string]bool)
for _, skill := range char.Waffenfertigkeiten {
if !weaponSkillNames[skill.Name] {
var weaponSkill models.WeaponSkill
err := weaponSkill.First(skill.Name)
if err == nil && weaponSkill.ID != 0 {
export.GSMWeaponSkills = append(export.GSMWeaponSkills, weaponSkill)
weaponSkillNames[skill.Name] = true
}
}
}
// Collect GSM spell data
export.GSMSpells = make([]models.Spell, 0)
spellNames := make(map[string]bool)
for _, spell := range char.Zauber {
if !spellNames[spell.Name] {
var gsmSpell models.Spell
err := gsmSpell.First(spell.Name)
if err == nil && gsmSpell.ID != 0 {
export.GSMSpells = append(export.GSMSpells, gsmSpell)
spellNames[spell.Name] = true
}
}
}
// Collect GSM weapon data
export.GSMWeapons = make([]models.Weapon, 0)
weaponNames := make(map[string]bool)
for _, weapon := range char.Waffen {
if !weaponNames[weapon.Name] {
var gsmWeapon models.Weapon
err := gsmWeapon.First(weapon.Name)
if err == nil && gsmWeapon.ID != 0 {
export.GSMWeapons = append(export.GSMWeapons, gsmWeapon)
weaponNames[weapon.Name] = true
}
}
}
// Collect GSM equipment data
export.GSMEquipment = make([]models.Equipment, 0)
equipmentNames := make(map[string]bool)
for _, equip := range char.Ausruestung {
if !equipmentNames[equip.Name] {
var gsmEquip models.Equipment
err := gsmEquip.First(equip.Name)
if err == nil && gsmEquip.ID != 0 {
export.GSMEquipment = append(export.GSMEquipment, gsmEquip)
equipmentNames[equip.Name] = true
}
}
}
// Collect GSM container data
export.GSMContainers = make([]models.Container, 0)
containerNames := make(map[string]bool)
for _, container := range char.Behaeltnisse {
if !containerNames[container.Name] {
var gsmContainer models.Container
err := gsmContainer.First(container.Name)
if err == nil && gsmContainer.ID != 0 {
export.GSMContainers = append(export.GSMContainers, gsmContainer)
containerNames[container.Name] = true
}
}
}
for _, container := range char.Transportmittel {
if !containerNames[container.Name] {
var gsmContainer models.Container
err := gsmContainer.First(container.Name)
if err == nil && gsmContainer.ID != 0 {
export.GSMContainers = append(export.GSMContainers, gsmContainer)
containerNames[container.Name] = true
}
}
}
// Load learning data
export.LearningData = LearningDataExport{
Sources: make([]models.Source, 0),
CharacterClasses: make([]models.CharacterClass, 0),
SkillCategories: make([]models.SkillCategory, 0),
SkillDifficulties: make([]models.SkillDifficulty, 0),
SpellSchools: make([]models.SpellSchool, 0),
ClassCategoryEPCosts: make([]models.ClassCategoryEPCost, 0),
ClassSpellSchoolEPCosts: make([]models.ClassSpellSchoolEPCost, 0),
SpellLevelLECosts: make([]models.SpellLevelLECost, 0),
SkillCategoryDifficulties: make([]models.SkillCategoryDifficulty, 0),
SkillImprovementCosts: make([]models.SkillImprovementCost, 0),
}
database.DB.Find(&export.LearningData.Sources)
database.DB.Preload("Source").Find(&export.LearningData.CharacterClasses)
database.DB.Preload("Source").Find(&export.LearningData.SkillCategories)
database.DB.Find(&export.LearningData.SkillDifficulties)
database.DB.Preload("Source").Find(&export.LearningData.SpellSchools)
database.DB.Preload("CharacterClass").Preload("SkillCategory").Find(&export.LearningData.ClassCategoryEPCosts)
database.DB.Preload("CharacterClass").Preload("SpellSchool").Find(&export.LearningData.ClassSpellSchoolEPCosts)
database.DB.Find(&export.LearningData.SpellLevelLECosts)
database.DB.Preload("Skill").Preload("SkillCategory").Preload("SkillDifficulty").Find(&export.LearningData.SkillCategoryDifficulties)
database.DB.Find(&export.LearningData.SkillImprovementCosts)
// Load audit log entries
export.AuditLogEntries = make([]models.AuditLogEntry, 0)
database.DB.Where("character_id = ?", characterID).Order("timestamp ASC").Find(&export.AuditLogEntries)
return export, nil
}