Small refactoring + correct delete mod data
This commit is contained in:
parent
97537b6ccf
commit
fb94b26c83
@ -0,0 +1,29 @@
|
||||
package com.dowstats.controllers
|
||||
|
||||
import com.dowstats.service.integrations.ModStorageIntegrationService
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("api/v1/custom-mod")
|
||||
class CustomModsController @Autowired constructor(
|
||||
val modStorageIntegrationService: ModStorageIntegrationService
|
||||
) {
|
||||
|
||||
@PostMapping("/reload/{modId}")
|
||||
fun reloadMod(@PathVariable modId: Long): String {
|
||||
modStorageIntegrationService.reloadMod(modId)
|
||||
return "Successfully reload mod"
|
||||
}
|
||||
|
||||
@PostMapping("/upload")
|
||||
fun uploadMod(@RequestParam("file") file: MultipartFile?,
|
||||
@RequestParam("name") name: String,
|
||||
@RequestParam("technicalName") technicalName: String,
|
||||
@RequestParam("version") version: String?): String {
|
||||
modStorageIntegrationService.saveModFromRequest(file, name, technicalName, version?:"1.0.0")
|
||||
return "Successfully upload mod"
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
package com.dowstats.controllers
|
||||
|
||||
import com.dowstats.service.integrations.ModStorageIntegrationService
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.web.bind.annotation.PostMapping
|
||||
import org.springframework.web.bind.annotation.RequestParam
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("api/v1/upload-mod")
|
||||
class UploadCustomModController @Autowired constructor(
|
||||
val modStorageIntegrationService: ModStorageIntegrationService
|
||||
) {
|
||||
|
||||
@PostMapping
|
||||
fun uploadMod(@RequestParam("file") file: MultipartFile,
|
||||
@RequestParam("name") name: String,
|
||||
@RequestParam("technicalName") technicalName: String,
|
||||
@RequestParam("version") version: String?): String {
|
||||
|
||||
val log = LoggerFactory.getLogger(UploadCustomModController::class.java)
|
||||
|
||||
modStorageIntegrationService.saveModFromRequest(file.bytes.inputStream(), name, technicalName, version?:"1.0.0")
|
||||
log.info("${file.originalFilename} successfull uploaded. Name: $name, version: $version")
|
||||
|
||||
return "Successfull upload mod"
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,16 @@
|
||||
package com.dowstats.data.repositories
|
||||
|
||||
import com.dowstats.data.entities.Mod
|
||||
import org.springframework.data.jpa.repository.Modifying
|
||||
import org.springframework.data.jpa.repository.Query
|
||||
import org.springframework.data.repository.*
|
||||
|
||||
interface ModRepository : CrudRepository<Mod, Long>{
|
||||
fun findByTechnicalNameAndVersion(techName: String, version: String): Mod?
|
||||
|
||||
@Query("""
|
||||
CALL delete_mod_data(:modId)
|
||||
""", nativeQuery = true)
|
||||
@Modifying
|
||||
fun clearModData(modId: Long)
|
||||
}
|
||||
@ -9,7 +9,9 @@ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import org.springframework.util.FileSystemUtils
|
||||
import org.springframework.web.multipart.MultipartFile
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
@ -70,9 +72,16 @@ class ModStorageIntegrationService(
|
||||
}
|
||||
}
|
||||
|
||||
fun saveModFromRequest(fileStream: InputStream, name: String, techName: String, version: String) {
|
||||
val modDirectoryTo = "$name$version"
|
||||
unzip(fileStream, modDirectoryTo)
|
||||
@Transactional
|
||||
fun reloadMod(modId: Long) {
|
||||
val mod = modRepository.findById(modId).orElseThrow { IllegalArgumentException("Mod not found") }
|
||||
modRepository.clearModData(modId)
|
||||
modParserService.parceModFilesAndSaveToDb(mod)
|
||||
}
|
||||
|
||||
|
||||
fun saveModFromRequest(file: MultipartFile?, name: String, techName: String, version: String) {
|
||||
|
||||
val uploadingMod = modRepository.findByTechnicalNameAndVersion(techName, version)
|
||||
val savedMod = uploadingMod ?: modRepository.save(Mod().also {
|
||||
it.version = version
|
||||
@ -80,7 +89,14 @@ class ModStorageIntegrationService(
|
||||
it.name = name
|
||||
it.technicalName = techName
|
||||
})
|
||||
modParserService.parceModFilesAndSaveToDb(savedMod)
|
||||
|
||||
file?.let {
|
||||
val modDirectoryTo = "$name$version"
|
||||
val fileStream = file.bytes.inputStream()
|
||||
unzip(fileStream, modDirectoryTo)
|
||||
modParserService.parceModFilesAndSaveToDb(savedMod)
|
||||
log.info("${file.originalFilename} successfull uploaded. Name: $name, version: $version")
|
||||
}
|
||||
}
|
||||
|
||||
private fun downloadAndExtractMod(modTechName: String, version: String) {
|
||||
|
||||
@ -11,8 +11,6 @@ class Schedulers (
|
||||
val modStorageIntegrationService: ModStorageIntegrationService
|
||||
) {
|
||||
|
||||
private val log = LogFactory.getLog(javaClass)
|
||||
|
||||
@Scheduled(fixedDelay = 600000)
|
||||
fun synchronizeLastMods() {
|
||||
modStorageIntegrationService.requestAvailableMods()
|
||||
|
||||
@ -22,11 +22,12 @@ class IconsService @Autowired constructor(
|
||||
*/
|
||||
fun convertTgaToJpegImage(iconPathInMod: String, pathToTgaIcon: String, modName: String? = null): String? {
|
||||
try{
|
||||
val image: BufferedImage = try {
|
||||
|
||||
val image: BufferedImage = if(File(pathToTgaIcon).exists()) {
|
||||
ImageIO.read(File(pathToTgaIcon))
|
||||
} catch (e: Exception){
|
||||
} else if (File(pathToTgaIcon.lowercase()).exists()) {
|
||||
ImageIO.read(File(pathToTgaIcon.lowercase()))
|
||||
}
|
||||
} else return null
|
||||
|
||||
val modFolder = modName?.let { "${File.separator}$modName" } ?: ""
|
||||
|
||||
|
||||
@ -18,6 +18,9 @@ class ModAttribPathService @Autowired constructor(
|
||||
fun getUcsFolder(modFolderData: String): String =
|
||||
"${modFolderData.replace("Data", "")}Locale${File.separator}English${File.separator}"
|
||||
|
||||
fun getUcsFolderRus(modFolderData: String): String =
|
||||
"${modFolderData.replace("Data", "")}Locale${File.separator}Russian${File.separator}"
|
||||
|
||||
fun getWeaponAttribsPath(modFolderData: String): String =
|
||||
"$modFolderData${File.separator}attrib${File.separator}weapon"
|
||||
|
||||
|
||||
@ -65,11 +65,26 @@ class ModParserService @Autowired constructor(
|
||||
unitRepository.deleteAllByModIdAndRaceId(mod.id!!, it)
|
||||
}
|
||||
|
||||
val modDictionary: MutableMap<Int, String> = mutableMapOf()
|
||||
val modDictionary: Map<Int, String> = getModDictionary(mod, modFolderData)
|
||||
|
||||
log.info("Extract dictionaries from $modFolderData")
|
||||
File(modAttribPathService.getUcsFolder(modFolderData)).listFiles().forEach {
|
||||
it.bufferedReader(Charsets.UTF_8).lines().forEach {
|
||||
|
||||
val enrichedModDictionary = defaultDictionary + modDictionary
|
||||
|
||||
val weapons = saveWeapons(modFolderData, mod, enrichedModDictionary)
|
||||
saveUnits(modFolderData, weapons, racesList, mod, enrichedModDictionary)
|
||||
|
||||
saveBuildings(modFolderData, weapons, racesList, mod, enrichedModDictionary)
|
||||
|
||||
}
|
||||
|
||||
private fun getModDictionary(mod: Mod, modFolderData: String): Map<Int,String>{
|
||||
val folder = if (mod.technicalName == "multidungeon_rightpocalypse") modAttribPathService.getUcsFolderRus(modFolderData) else modAttribPathService.getUcsFolder(modFolderData)
|
||||
|
||||
val modDictionary = mutableMapOf<Int, String>()
|
||||
|
||||
File(folder).listFiles()?.forEach {
|
||||
it.bufferedReader(Charsets.UTF_16).lines().forEach {
|
||||
val kv = it.split("\\s+".toRegex())
|
||||
if (kv.size < 2) return@forEach
|
||||
val key = try {kv.first().filter { it.isDigit() }.toInt()} catch(e: Exception) {
|
||||
@ -81,16 +96,10 @@ class ModParserService @Autowired constructor(
|
||||
}
|
||||
}
|
||||
|
||||
val enrichedModDictionary = modDictionary + defaultDictionary
|
||||
|
||||
val weapons = saveWeapons(modFolderData, mod, enrichedModDictionary)
|
||||
saveUnits(modFolderData, weapons, racesList, mod, enrichedModDictionary)
|
||||
|
||||
saveBuildings(modFolderData, weapons, racesList, mod, enrichedModDictionary)
|
||||
|
||||
return modDictionary
|
||||
}
|
||||
|
||||
fun saveUnits(modFolderData: String, weapons: Set<Weapon>, racesList: List<String>, mod: Mod, modDictionary: Map<Int, String>) {
|
||||
private fun saveUnits(modFolderData: String, weapons: Set<Weapon>, racesList: List<String>, mod: Mod, modDictionary: Map<Int, String>) {
|
||||
|
||||
val races = raceRepository.findAll().toList()
|
||||
val armorTypes = armorTypeRepository.findAll().toList()
|
||||
@ -186,7 +195,7 @@ class ModParserService @Autowired constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun saveBuildings(modFolderData: String,
|
||||
private fun saveBuildings(modFolderData: String,
|
||||
weapons: Set<Weapon>,
|
||||
racesList: List<String>,
|
||||
mod: Mod, modDictionary: Map<Int, String>) {
|
||||
@ -249,7 +258,7 @@ class ModParserService @Autowired constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun getAddonsRgdData(modFolderData: String): Map<String, List<RgdData>> {
|
||||
private fun getAddonsRgdData(modFolderData: String): Map<String, List<RgdData>> {
|
||||
|
||||
val classicAddons = rgdParserService.parseFolderToRgdFiles("${modAttribPathService.pathToWanilaData}/attrib/addons")
|
||||
|
||||
@ -259,7 +268,7 @@ class ModParserService @Autowired constructor(
|
||||
return classicAddons + modAddons
|
||||
}
|
||||
|
||||
fun saveWeapons(modFolderData: String, mod: Mod, modDictionary: Map<Int, String>): Set<Weapon> {
|
||||
private fun saveWeapons(modFolderData: String, mod: Mod, modDictionary: Map<Int, String>): Set<Weapon> {
|
||||
|
||||
val classicWeapons = rgdParserService.parseFolderToRgdFiles("${modAttribPathService.pathToWanilaData}/attrib/weapon")
|
||||
|
||||
|
||||
@ -26,8 +26,6 @@ class ModsDiffService @Autowired constructor(
|
||||
setOf(spaceMarinesPath, chaosPath, eldarPath, orksPath, guardPath, necronPath, tauPath, sistersPath)
|
||||
|
||||
|
||||
|
||||
|
||||
fun getUnitsAndSquadsDiff(modFolderData: String, oldModFolderData: String? = null): String {
|
||||
|
||||
val oldModFolderPath =
|
||||
|
||||
@ -115,23 +115,23 @@ class WeaponRgdExtractService @Autowired constructor(
|
||||
|
||||
val armourDamage = areaEffect
|
||||
?.getRgdTableByName("weapon_damage")
|
||||
?.getRgdTableByName("armour_damage")!!
|
||||
val minDamage = armourDamage.getDoubleByName("min_damage")!!
|
||||
val maxDamage = armourDamage.getDoubleByName("max_damage")!!
|
||||
val minDamageValue = armourDamage.getDoubleByName("min_damage_value")!!
|
||||
val moraleDamage = armourDamage.getDoubleByName("morale_damage")!!
|
||||
?.getRgdTableByName("armour_damage")
|
||||
val minDamage = armourDamage?.getDoubleByName("min_damage") ?: 0.0
|
||||
val maxDamage = armourDamage?.getDoubleByName("max_damage") ?: 0.0
|
||||
val minDamageValue = armourDamage?.getDoubleByName("min_damage_value") ?: 0.0
|
||||
val moraleDamage = armourDamage?.getDoubleByName("morale_damage") ?: 0.0
|
||||
|
||||
|
||||
val defaultArmourPiercing = armourDamage.getDoubleByName("armour_piercing")
|
||||
val defaultArmourPiercing = armourDamage?.getDoubleByName("armour_piercing")
|
||||
val weaponDmgMap: Map<String, Double> =
|
||||
armourDamage.getRgdTableByName("armour_piercing_types")!!.mapNotNull { armour_piercing ->
|
||||
armourDamage?.getRgdTableByName("armour_piercing_types")?.mapNotNull { armour_piercing ->
|
||||
if (armour_piercing.name.contains("entry")) {
|
||||
val entry = armour_piercing.value as List<RgdData>
|
||||
val dmgType = entry.getRgdTableByName("armour_type")?.getStringByName("\$REF")?.replace("type_armour\\tp_","")?.replace(".lua","")
|
||||
val dmgValue = entry.getDoubleByName("armour_piercing_value")
|
||||
dmgType!! to dmgValue!!
|
||||
} else null
|
||||
}.toMap()
|
||||
}?.toMap() ?: emptyMap()
|
||||
|
||||
val armoursPiercing = armorTypes.map {
|
||||
val weaponArmourPiercing = WeaponArmorPiercing()
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
CREATE OR REPLACE PROCEDURE delete_mod_data(mod_id_p bigint)
|
||||
LANGUAGE SQL
|
||||
AS $$
|
||||
DELETE FROM units WHERE mod_id = mod_id_p;
|
||||
DELETE FROM buildings WHERE mod_id = mod_id_p;
|
||||
DELETE FROM weapons WHERE mod_id = mod_id_p;
|
||||
$$;
|
||||
@ -53,7 +53,8 @@
|
||||
"baseTableName": "addon_modifiers",
|
||||
"constraintName": "fk_building_addons_addon_modifiers",
|
||||
"referencedColumnNames": "id",
|
||||
"referencedTableName": "building_addons"
|
||||
"referencedTableName": "building_addons",
|
||||
"onDelete": "CASCADE"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -53,7 +53,8 @@
|
||||
"baseTableName": "addon_requires",
|
||||
"constraintName": "fk_building_addons_addon_requires",
|
||||
"referencedColumnNames": "id",
|
||||
"referencedTableName": "building_addons"
|
||||
"referencedTableName": "building_addons",
|
||||
"onDelete": "CASCADE"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -94,7 +94,8 @@
|
||||
"baseTableName": "building_addons",
|
||||
"constraintName": "fk_building_addons_buildings",
|
||||
"referencedColumnNames": "id",
|
||||
"referencedTableName": "buildings"
|
||||
"referencedTableName": "buildings",
|
||||
"onDelete": "CASCADE"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -62,7 +62,8 @@
|
||||
"baseTableName": "buildings_weapons",
|
||||
"constraintName": "fk_buildings_buildings_weapons",
|
||||
"referencedColumnNames": "id",
|
||||
"referencedTableName": "buildings"
|
||||
"referencedTableName": "buildings",
|
||||
"onDelete": "CASCADE"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -72,7 +73,8 @@
|
||||
"baseTableName": "buildings_weapons",
|
||||
"constraintName": "fk_weapons_buildings_weapons",
|
||||
"referencedColumnNames": "id",
|
||||
"referencedTableName": "weapons"
|
||||
"referencedTableName": "weapons",
|
||||
"onDelete": "CASCADE"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"databaseChangeLog": [
|
||||
{
|
||||
"changeSet": {
|
||||
"id": "Creade delete_mod_data_procedure",
|
||||
"author": "anibus",
|
||||
"changes": [
|
||||
{
|
||||
"createProcedure": {
|
||||
"path": "db/0.0.1/procedures/delete_mod_data_procedure.sql"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -149,7 +149,8 @@
|
||||
"baseTableName": "sergeants",
|
||||
"constraintName": "fk_sergeants_units",
|
||||
"referencedColumnNames": "id",
|
||||
"referencedTableName": "units"
|
||||
"referencedTableName": "units",
|
||||
"onDelete": "CASCADE"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -62,7 +62,8 @@
|
||||
"baseTableName": "sergeants_weapons",
|
||||
"constraintName": "fk_sergeants_sergeants_weapons",
|
||||
"referencedColumnNames": "id",
|
||||
"referencedTableName": "sergeants"
|
||||
"referencedTableName": "sergeants",
|
||||
"onDelete": "CASCADE"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -72,7 +73,8 @@
|
||||
"baseTableName": "sergeants_weapons",
|
||||
"constraintName": "fk_weapons_sergeants_weapons",
|
||||
"referencedColumnNames": "id",
|
||||
"referencedTableName": "weapons"
|
||||
"referencedTableName": "weapons",
|
||||
"onDelete": "CASCADE"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -62,7 +62,8 @@
|
||||
"baseTableName": "units_weapons",
|
||||
"constraintName": "fk_units_units_weapons",
|
||||
"referencedColumnNames": "id",
|
||||
"referencedTableName": "units"
|
||||
"referencedTableName": "units",
|
||||
"onDelete": "CASCADE"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -72,7 +73,8 @@
|
||||
"baseTableName": "units_weapons",
|
||||
"constraintName": "fk_weapons_units_weapons",
|
||||
"referencedColumnNames": "id",
|
||||
"referencedTableName": "weapons"
|
||||
"referencedTableName": "weapons",
|
||||
"onDelete": "CASCADE"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@ -53,7 +53,8 @@
|
||||
"baseColumnNames": "weapon_id",
|
||||
"baseTableName": "weapons_armors_damage",
|
||||
"referencedColumnNames": "id",
|
||||
"referencedTableName": "weapons"
|
||||
"referencedTableName": "weapons",
|
||||
"onDelete": "CASCADE"
|
||||
}
|
||||
},{
|
||||
"addForeignKeyConstraint":
|
||||
@ -55,7 +55,7 @@
|
||||
}
|
||||
},{
|
||||
"include": {
|
||||
"file": "db/0.0.1/schema/weapons_armors_damage.json"
|
||||
"file": "db/0.0.1/schema/weapons_armors_piercing.json"
|
||||
}
|
||||
},{
|
||||
"include": {
|
||||
@ -69,6 +69,10 @@
|
||||
"include": {
|
||||
"file": "db/0.0.1/data/races.json"
|
||||
}
|
||||
},{
|
||||
"include": {
|
||||
"file": "db/0.0.1/schema/procedure_delete_mod_data.json"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user