This commit is contained in:
anibus 2026-07-27 01:32:14 +03:00
parent b0081aae16
commit f21aeba92e
32 changed files with 311 additions and 226 deletions

Binary file not shown.

View File

@ -6,5 +6,5 @@ data class BuildCost(
val population: Double?,
val faith: Double?,
val souls: Double?,
val time: Int?,
val time: Double?,
)

View File

@ -16,7 +16,7 @@ data class SergeantDto(
val buildCostPopulation: Double?,
val buildCostFaith: Double?,
val buildCostSouls: Double?,
val buildCostTime: Int?,
val buildCostTime: Double?,
val faithIncome: Double?,
val powerIncome: Double?,
val requisitionIncome: Double?,

View File

@ -19,7 +19,7 @@ data class UnitFullDto(
val buildCostPopulation: Double?,
val buildCostFaith: Double?,
val buildCostSouls: Double?,
val buildCostTime: Int?,
val buildCostTime: Double?,
val faithIncome: Double?,
val powerIncome: Double?,
val requisitionIncome: Double?,
@ -46,7 +46,7 @@ data class UnitFullDto(
val reinforceCostPopulation: Double?,
val reinforceCostFaith: Double?,
val reinforceCostSouls: Double?,
val reinforceTime: Int?,
val reinforceTime: Double?,
val repairMax: Int?,
val repairSpeed: Int?,
val repairCostPercent: Int?,

View File

@ -10,7 +10,7 @@ data class WeaponDto(
val description: String?,
val costRequisition: Double?,
val costPower: Double?,
val costTimeSeconds: Int?,
val costTimeSeconds: Double?,
val accuracy: Double?,
val reloadTime: Double?,
val minRange: Double?,

View File

@ -12,7 +12,7 @@ data class BuildingAddonDto(
val addonCostPopulation: Double?,
val addonCostFaith: Double?,
val addonCostSouls: Double?,
val addonCostTime: Int?,
val addonCostTime: Double?,
val addonModifiers: Set<ModifierDto>,
val affectedData: AffectedDataDto,
val addonRequirement: RequirementDto?,

View File

@ -18,7 +18,7 @@ data class BuildingFullDto(
var buildCostPopulation: Double?,
var buildCostFaith: Double?,
var buildCostSouls: Double?,
var buildCostTime: Int?,
var buildCostTime: Double?,
var faithIncome: Double?,
var powerIncome: Double?,
var requisitionIncome: Double?,

View File

@ -12,7 +12,7 @@ data class ResearchDto(
val costPower: Double?,
val costFaith: Double?,
val costSouls: Double?,
val costTime: Int?,
val costTime: Double?,
val modifiers: List<ModifierDto>,
val requirements: RequirementDto?,
val affectedData: AffectedDataDto,

View File

@ -12,6 +12,7 @@ class Mod {
var id: Long? = null
var name: String? = null
var order: Int = 0
var version: String? = null
var technicalName: String? = null
var isBeta: Boolean = true

View File

@ -4,6 +4,7 @@ import com.dowstats.data.dto.controllers.ModifierDto
import com.dowstats.data.rgd.RgdData
import com.dowstats.data.rgd.RgdDataUtil.getBooleanByName
import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
import com.dowstats.data.rgd.RgdDataUtil.getPureIntByName
import com.dowstats.data.rgd.RgdDataUtil.getRgdTableByName
import com.dowstats.data.rgd.RgdDataUtil.getStringByName
import jakarta.persistence.GeneratedValue
@ -53,7 +54,9 @@ open class ModifiersBase {
this.value = try{ rgdData.getDoubleByName("value") } catch (e: Exception) { null }
this.applicationType = rgdData.getRgdTableByName("application_type")?.getStringByName("\$REF")
this.exclusive = try { rgdData.getBooleanByName("exclusive") } catch (e: Exception) { false }
this.probabilityOfApplying = rgdData.getDoubleByName("probability_of_applying")
this.probabilityOfApplying = try { rgdData.getDoubleByName("probability_of_applying") } catch (e: Exception) {
rgdData.getPureIntByName("probability_of_applying")?.toDouble()
}
return this
}
}

View File

@ -36,7 +36,7 @@ class BuildingAddon {
var addonCostPopulation: Double? = null
var addonCostFaith: Double? = null
var addonCostSouls: Double? = null
var addonCostTime: Int? = null
var addonCostTime: Double? = null
@OneToMany(mappedBy = "addon", cascade = [CascadeType.ALL])
var addonModifiers: MutableSet<AddonModifiers> = mutableSetOf()

View File

@ -53,7 +53,7 @@ class Building {
var buildCostPopulation: Double? = null
var buildCostFaith: Double? = null
var buildCostSouls: Double? = null
var buildCostTime: Int? = null
var buildCostTime: Double? = null
var health: Int? = null
var armour: Double? = null
var healthRegeneration: Double? = null

View File

@ -30,7 +30,7 @@ class Research {
var costPower: Double? = null
var costFaith: Double? = null
var costSouls: Double? = null
var costTime: Int? = null
var costTime: Double? = null
var uiIndexHint: Int = 0
var uiHotkeyName: String? = null
var icon: String? = null

View File

@ -49,7 +49,7 @@ class Sergeant {
var buildCostPopulation: Double? = null
var buildCostFaith: Double? = null
var buildCostSouls: Double? = null
var buildCostTime: Int? = null
var buildCostTime: Double? = null
var health: Int? = null
var armour: Double? = null
var healthRegeneration: Double? = null

View File

@ -49,7 +49,7 @@ class DowUnit {
var buildCostPopulation: Double? = null
var buildCostFaith: Double? = null
var buildCostSouls: Double? = null
var buildCostTime: Int? = null
var buildCostTime: Double? = null
var capInfantry: Int? = null
var capSupport: Int? = null
var squadStartSize: Int? = null
@ -75,7 +75,7 @@ class DowUnit {
var reinforceCostPopulation: Double? = null
var reinforceCostFaith: Double? = null
var reinforceCostSouls: Double? = null
var reinforceTime: Int? = null
var reinforceTime: Double? = null
var maxSergeants: Int? = null
var faithIncome: Double? = null
var powerIncome: Double? = null

View File

@ -27,7 +27,7 @@ class Weapon {
var description: String? = null
var costRequisition: Double? = null
var costPower: Double? = null
var costTimeSeconds: Int? = null
var costTimeSeconds: Double? = null
var accuracy: Double? = null
var reloadTime: Double? = null
var minRange: Double? = null

View File

@ -25,6 +25,10 @@ object RgdDataUtil{
return (this.find { it.name == name }?.value as Double?)?.toInt()
}
fun List<RgdData>.getPureIntByName(name: String): Int? {
return (this.find { it.name == name }?.value as Int?)
}
fun List<RgdData>.getStringByName(name: String): String? {
return this.find { it.name == name }?.value as String?
}

View File

@ -22,25 +22,4 @@ object CommonMapping {
)
}
fun isNotCompanyEntity(fileName: String): Boolean =
!fileName.contains("_dxp3.") &&
!fileName.contains("_dxp3_") &&
!fileName.contains("sp_eldar_") &&
!fileName.contains("_sp_") &&
!fileName.contains("_sp.") &&
!fileName.contains("_nis.") &&
!fileName.contains("_interface_relay.") &&
!fileName.contains("necron_tunnel.rgd") &&
!fileName.contains("_exarch_council.") &&
!fileName.contains("_dark_reapers_base.") &&
!fileName.contains("eldar_deep_strike_building.rgd") &&
!fileName.contains("ork_deep_strike_building.rgd") &&
!fileName.contains("_caravel_ai.rgd") &&
!fileName.contains("sisters_tanktrap_ai.rgd") &&
!fileName.contains("sisters_hq_ktgm.rgd") &&
!fileName.contains("tau_squad_slave_murdered") &&
!fileName.contains("single_player_only") &&
!fileName.contains("space_marine_drop_pod_building.rgd")
}

View File

@ -65,7 +65,7 @@ class CommonParseRgdService @Autowired constructor(
costResources?.getDoubleByName("population"),
costResources?.getDoubleByName("faith"),
costResources?.getDoubleByName("souls"),
cost?.getDoubleByName("time_seconds")?.toInt()
cost?.getDoubleByName("time_seconds")
)
}

View File

@ -70,6 +70,15 @@ class ModParserService @Autowired constructor(
val value = kv.drop(1).joinToString(" ").replace("\u0000", "")
defaultDictionary[key] = value
}
RgdParserService::class.java.getClassLoader().getResourceAsStream("Engine.ucs").bufferedReader(Charsets.UTF_8)
.lines().forEach {
val kv = it.split("\\s+".toRegex())
if (kv.size < 2) return@forEach
val key = kv.first().filter { it.isDigit() }.toInt()
val value = kv.drop(1).joinToString(" ").replace("\u0000", "")
defaultDictionary[key] = value
}
}
val log = LoggerFactory.getLogger(ModParserService::class.java)

View File

@ -1,130 +0,0 @@
package com.dowstats.service.w40k
import com.dowstats.data.rgd.RgdData
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.io.DataInputStream
import java.io.File
@Service
class ModsDiffService @Autowired constructor(
val rgdParseService: RgdParserService,
val rgdService: RgdService,
val modStorageService: ModAttribPathService,
) {
val spaceMarinesPath = "space_marines"
val chaosPath = "chaos"
val eldarPath = "eldar"
val orksPath = "orks"
val guardPath = "guard"
val necronPath = "necrons"
val tauPath = "tau"
val sistersPath = "sisters"
val racesWikiPaths =
setOf(spaceMarinesPath, chaosPath, eldarPath, orksPath, guardPath, necronPath, tauPath, sistersPath)
fun getUnitsAndSquadsDiff(modFolderData: String, oldModFolderData: String? = null): String {
val oldModFolderPath =
if (oldModFolderData != null) oldModFolderData else modStorageService.pathToWanilaData
var totalDiff = ""
racesWikiPaths.forEach { racePath ->
val rgdDataOld = getRgdDataMapFromFolder(modStorageService.getSbpsAttribsPath(oldModFolderPath, racePath))
val rgdDataNew = getRgdDataMapFromFolder(modStorageService.getSbpsAttribsPath(modFolderData, racePath))
val rgdDataUnitsOld = getRgdDataMapFromFolder(modStorageService.getEbpsTroopsAttribsPath(oldModFolderPath, racePath))
val rgdDataUnitsNew = getRgdDataMapFromFolder(modStorageService.getEbpsTroopsAttribsPath(modFolderData, racePath))
rgdDataNew.forEach { newSquad ->
val oldSquad = rgdDataOld[newSquad.key]
val baseUnitPath = ((newSquad.value?.find { it.name == "squad_loadout_ext" }?.value as List<RgdData>)
.find { it.name == "trooper_base" }?.value as List<RgdData>)
.find { it.name == "type" }?.value as String
val baseUnitName = baseUnitPath.split("\\").last().replace(".lua", ".rgd")
val newUnit = rgdDataUnitsNew[baseUnitName]
val oldUnit = rgdDataUnitsOld[baseUnitName]
if (oldSquad != newSquad.value || oldUnit != newUnit) {
totalDiff += (newSquad.key.replace(".rgd", "").uppercase() + "\n")
totalDiff += rgdService.getRgdDiff(newSquad.value, oldSquad)
if (oldSquad != newSquad.value && oldUnit != newUnit) totalDiff += "-\n"
totalDiff += rgdService.getRgdDiff(newUnit, oldUnit)
totalDiff += "---\n"
}
}
}
return totalDiff
}
fun getAllWeaponsDiff(modFolderData: String, oldModFolderData: String? = null): String {
val oldModFolderPath =
if (oldModFolderData != null) oldModFolderData else modStorageService.pathToWanilaData
val wanillaRgdData = getRgdDataMapFromFolder(modStorageService.getWeaponAttribsPath(modStorageService.pathToWanilaData))
val oldRgdData = getRgdDataMapFromFolder(modStorageService.getWeaponAttribsPath(oldModFolderPath))
val newRgdData = getRgdDataMapFromFolder(modStorageService.getWeaponAttribsPath(modFolderData))
var totalDiff = ""
newRgdData.forEach {newWeapon ->
val oldWeapon = oldRgdData[newWeapon.key]
if(oldWeapon != newWeapon.value){
totalDiff += (newWeapon.key.replace(".rgd", "").uppercase()) + "\n"
if(oldWeapon != null){
totalDiff += rgdService.getRgdDiff(newWeapon.value, oldWeapon) + "\n"
}else{
totalDiff += "NOT EXIST IN PREV VERSION\n"
totalDiff += rgdService.getRgdDiff(newWeapon.value, wanillaRgdData[newWeapon.key]) + "\n"
}
totalDiff += "---\n"
}
}
return totalDiff
}
fun getAllBuildingsDiff(modFolderData: String, oldModFolderData: String? = null): String {
var totalDiff = ""
racesWikiPaths.forEach { racePath ->
val oldModFolderPath =
if (oldModFolderData != null) oldModFolderData else modStorageService.pathToWanilaData
val oldRgdData = getRgdDataMapFromFolder(modStorageService.geBuildingAttribsPath(oldModFolderPath, racePath))
val newRgdData = getRgdDataMapFromFolder(modStorageService.geBuildingAttribsPath(modFolderData, racePath))
newRgdData.forEach { newBuilding ->
val oldBuilding = oldRgdData[newBuilding.key]
if (oldBuilding != newBuilding.value) {
totalDiff += (newBuilding.key.replace(".rgd", "").uppercase()) + "\n"
totalDiff += rgdService.getRgdDiff(newBuilding.value, oldBuilding) + "\n"
totalDiff += "---\n"
}
}
}
return totalDiff
}
private fun getRgdDataMapFromFolder(folderPath: String): Map<String, List<RgdData>?> =
File(folderPath).walkTopDown().map {
val rgdData = if (it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")) {
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
null
}
it.name to rgdData
}.filter { it.second != null }
.sortedBy { it.first }
.toMap()
}

View File

@ -89,7 +89,7 @@ class RgdParserService @Autowired constructor(
val data: Any = when (type) {
0 -> { // Float
val entityData = byteList.subList(dataOffset, dataOffset + 4).toByteArray().reversedArray().getFloat()
entityData.toBigDecimal().setScale(2, RoundingMode.HALF_UP).toDouble()
entityData.toBigDecimal().setScale(4, RoundingMode.HALF_UP).toDouble()
}
1 -> { // Int
val entityData = byteList.subList(dataOffset, dataOffset + 8).getInt()

View File

@ -217,7 +217,7 @@ class UnitRgdExtractService @Autowired constructor(
getCost(cost.population),
getCost(cost.faith),
getCost(cost.souls),
getCost(cost.time?.toDouble())?.toInt()
getCost(cost.time)
)
}

View File

@ -12,6 +12,7 @@ import com.dowstats.data.entities.weapon.WeaponRequirements
import com.dowstats.data.rgd.RgdData
import com.dowstats.data.rgd.RgdDataUtil.getBooleanByName
import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
import com.dowstats.data.rgd.RgdDataUtil.getPureIntByName
import com.dowstats.data.rgd.RgdDataUtil.getRgdTableByName
import com.dowstats.data.rgd.RgdDataUtil.getStringByName
import org.slf4j.LoggerFactory
@ -44,7 +45,7 @@ class WeaponRgdExtractService @Autowired constructor(
val cost = commonParseRgdService.getBuildCost(weaponData.getRgdTableByName("cost"))
weapon.costRequisition = cost.requisition ?: 0.0
weapon.costPower = cost.power ?: 0.0
weapon.costTimeSeconds = cost.time ?: 0
weapon.costTimeSeconds = cost.time
weapon.accuracy = weaponData.getDoubleByName("accuracy") ?: 1.0
weapon.accuracyReductionMoving = weaponData.getDoubleByName("accuracy_reduction_when_moving")
weapon.minRange = weaponData.getDoubleByName("min_range")
@ -100,7 +101,11 @@ class WeaponRgdExtractService @Autowired constructor(
if (m.name.contains("modifier_")) {
val mTable = m.value as List<RgdData>
val modifier = mTable.getRgdTableByName("modifier")
val maxLifetime = mTable.getDoubleByName("max_lifetime")
val maxLifetime = try {
mTable.getDoubleByName("max_lifetime")
} catch (e: Exception) {
mTable.getPureIntByName("max_lifetime")?.toDouble()
}
if (modifier?.getStringByName("\$REF") == "modifiers\\no_modifier.lua" || modifier == null) null else {
WeaponModifiers().also {
it.weapon = weapon

View File

@ -1,4 +1,4 @@
package com.dowstats.service.w40k
package com.dowstats.service.w40k.helpscripts
import com.dowstats.data.rgd.RgdData
import org.springframework.stereotype.Service
@ -35,7 +35,10 @@ class RgdService {
}
// Удалить как будет готова вики
fun printRgdDiff(first: List<RgdData>?, second: List<RgdData>?, path: String = "", out: PrintWriter = PrintWriter(System.out)){
fun printRgdDiff(first: List<RgdData>?, second: List<RgdData>?, path: String = "", out: PrintWriter = PrintWriter(
System.out
)
){
first?.sortedBy { it.name }?.forEach{rgdFirst ->
val name = rgdFirst.name
val rgdSecond = second?.find{it.name == name}

Binary file not shown.

View File

@ -0,0 +1,18 @@
CREATE OR REPLACE PROCEDURE delete_campaign_entities(mod_id_p bigint)
LANGUAGE SQL
AS $$
DELETE FROM units WHERE mod_id = mod_id_p AND (fileName_squad LIKE '%\_dxp3.%' OR fileName_squad LIKE '%\_dxp3.%' OR fileName_squad LIKE '%sp\_eldar\_%' OR fileName_squad LIKE '%\_sp\_%' OR fileName_squad LIKE '%\_sp.%' OR fileName_squad LIKE '%\_nis.%' OR fileName_squad LIKE '%\_interface\_relay.%' OR fileName_squad LIKE '%necron\_tunnel.rgd%' OR fileName_squad LIKE '%\_exarch\_council.%' OR fileName_squad LIKE '%\_dark\_reapers\_base.%' OR fileName_squad LIKE '%eldar\_deep\_strike\_building.rgd%' OR fileName_squad LIKE '%ork\_deep\_strike\_building.rgd%' OR fileName_squad LIKE '%\_caravel\_ai.rgd%' OR fileName_squad LIKE '%sisters\_tanktrap\_ai.rgd%' OR fileName_squad LIKE '%sisters\_hq\_ktgm.rgd%' OR fileName_squad LIKE '%tau\_squad\_slave\_murdered%' OR fileName_squad LIKE '%single\_player\_only%' OR fileName_squad LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR fileName_squad LIKE '%advance\_sp%' OR fileName_squad LIKE '%\_no\_limit.rgd%');
DELETE FROM buildings WHERE mod_id = mod_id_p AND (filename LIKE '%\_dxp3.%' OR filename LIKE '%\_dxp3.%' OR filename LIKE '%sp\_eldar\_%' OR filename LIKE '%\_sp\_%' OR filename LIKE '%\_sp.%' OR filename LIKE '%\_nis.%' OR filename LIKE '%\_interface\_relay.%' OR filename LIKE '%necron\_tunnel.rgd%' OR filename LIKE '%\_exarch\_council.%' OR filename LIKE '%\_dark\_reapers\_base.%' OR filename LIKE '%eldar\_deep\_strike\_building.rgd%' OR filename LIKE '%ork\_deep\_strike\_building.rgd%' OR filename LIKE '%\_caravel\_ai.rgd%' OR filename LIKE '%sisters\_tanktrap\_ai.rgd%' OR filename LIKE '%sisters\_hq\_ktgm.rgd%' OR filename LIKE '%tau\_squad\_slave\_murdered%' OR filename LIKE '%single\_player\_only%' OR filename LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR filename LIKE '%advance\_sp%' OR filename LIKE '%night\_lords\_hq\_aep%' OR filename LIKE '%\_ktgm.rgd%' OR filename LIKE '%salamander\_hq\_aep.rgd%' OR filename LIKE '%\_no\_limit.rgd%');
DELETE FROM buildings USING building_requirements WHERE mod_id = mod_id_p AND buildings.id = building_requirements.building_id AND building_requirements.reference = 'requirements\required_cap.lua' AND building_requirements.value = '0';
DELETE FROM weapons WHERE mod_id = mod_id_p AND (filename LIKE '%\_dxp3.%' OR filename LIKE '%\_dxp3.%' OR filename LIKE '%sp\_eldar\_%' OR filename LIKE '%\_sp\_%' OR filename LIKE '%\_sp.%' OR filename LIKE '%\_nis.%' OR filename LIKE '%\_interface\_relay.%' OR filename LIKE '%necron\_tunnel.rgd%' OR filename LIKE '%\_exarch\_council.%' OR filename LIKE '%\_dark\_reapers\_base.%' OR filename LIKE '%eldar\_deep\_strike\_building.rgd%' OR filename LIKE '%ork\_deep\_strike\_building.rgd%' OR filename LIKE '%\_caravel\_ai.rgd%' OR filename LIKE '%sisters\_tanktrap\_ai.rgd%' OR filename LIKE '%sisters\_hq\_ktgm.rgd%' OR filename LIKE '%tau\_squad\_slave\_murdered%' OR filename LIKE '%single\_player\_only%' OR filename LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR filename LIKE '%advance\_sp%');
DELETE FROM weapons WHERE EXISTS (SELECT 1 FROM weapons AS w2
LEFT JOIN buildings_weapons ON w2.id = buildings_weapons.weapon_id
LEFT JOIN units_weapons ON w2.id = units_weapons.weapon_id
LEFT JOIN sergeants_weapons ON w2.id = sergeants_weapons.weapon_id
WHERE mod_id = mod_id_p AND weapons.id = w2.id AND buildings_weapons.building_id IS NULL AND units_weapons.unit_id IS NULL AND sergeants_weapons.sergeant_id IS NULL) AND mod_id = mod_id_p;
DELETE FROM researches WHERE mod_id = mod_id_p AND (filename LIKE '%\_dxp3.%' OR filename LIKE '%\_dxp3.%' OR filename LIKE '%sp\_eldar\_%' OR filename LIKE '%\_sp\_%' OR filename LIKE '%\_sp.%' OR filename LIKE '%\_nis.%' OR filename LIKE '%\_interface\_relay.%' OR filename LIKE '%necron\_tunnel.rgd%' OR filename LIKE '%\_exarch\_council.%' OR filename LIKE '%\_dark\_reapers\_base.%' OR filename LIKE '%eldar\_deep\_strike\_building.rgd%' OR filename LIKE '%ork\_deep\_strike\_building.rgd%' OR filename LIKE '%\_caravel\_ai.rgd%' OR filename LIKE '%sisters\_tanktrap\_ai.rgd%' OR filename LIKE '%sisters\_hq\_ktgm.rgd%' OR filename LIKE '%tau\_squad\_slave\_murdered%' OR filename LIKE '%single\_player\_only%' OR filename LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR filename LIKE '%advance\_sp%');
DELETE FROM research_modifiers USING researches WHERE researches.mod_id = mod_id_p AND researches.id = research_id AND (target LIKE '%\_dxp3%' OR target LIKE '%\_dxp3%' OR target LIKE '%sp\_eldar\_%' OR target LIKE '%\_sp\_%' OR target LIKE '%\_sp.%' OR target LIKE '%\_sp' OR target LIKE '%\_nis.%' OR target LIKE '%\_interface\_relay.%' OR target LIKE '%necron\_tunnel.rgd%' OR target LIKE '%\_exarch\_council.%' OR target LIKE '%\_dark\_reapers\_base.%' OR target LIKE '%eldar\_deep\_strike\_building.rgd%' OR target LIKE '%ork\_deep\_strike\_building.rgd%' OR target LIKE '%\_caravel\_ai.rgd%' OR target LIKE '%sisters\_tanktrap\_ai.rgd%' OR target LIKE '%sisters\_hq\_ktgm.rgd%' OR target LIKE '%tau\_squad\_slave\_murdered%' OR target LIKE '%single\_player\_only%' OR target LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR target LIKE '%\_clone%' OR target LIKE '%\_dxp3');
DELETE FROM addon_modifiers USING building_addons WHERE building_addons.mod_id = mod_id_p AND building_addons.id = addon_modifiers.addon_id AND (target LIKE '%\_dxp3%' OR target LIKE '%\_dxp3%' OR target LIKE '%sp\_eldar\_%' OR target LIKE '%\_sp\_%' OR target LIKE '%\_sp.%' OR target LIKE '%\_sp' OR target LIKE '%\_nis.%' OR target LIKE '%\_interface\_relay.%' OR target LIKE '%necron\_tunnel.rgd%' OR target LIKE '%\_exarch\_council.%' OR target LIKE '%\_dark\_reapers\_base.%' OR target LIKE '%eldar\_deep\_strike\_building.rgd%' OR target LIKE '%ork\_deep\_strike\_building.rgd%' OR target LIKE '%\_caravel\_ai.rgd%' OR target LIKE '%sisters\_tanktrap\_ai.rgd%' OR target LIKE '%sisters\_hq\_ktgm.rgd%' OR target LIKE '%tau\_squad\_slave\_murdered%' OR target LIKE '%single\_player\_only%' OR target LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR target LIKE '%\_clone%' OR target LIKE '%\_dxp3');
DELETE FROM building_addons USING buildings WHERE buildings.mod_id = mod_id_p AND buildings.id = building_addons.building_id AND (building_addons.filename LIKE '%\_dxp3%' OR building_addons.filename LIKE '%\_dxp3%' OR building_addons.filename LIKE '%sp\_eldar\_%' OR building_addons.filename LIKE '%\_sp\_%' OR building_addons.filename LIKE '%\_sp.%' OR building_addons.filename LIKE '%\_nis.%' OR building_addons.filename LIKE '%\_interface\_relay.%' OR building_addons.filename LIKE '%necron\_tunnel.rgd%' OR building_addons.filename LIKE '%\_exarch\_council.%' OR building_addons.filename LIKE '%\_dark\_reapers\_base.%' OR building_addons.filename LIKE '%eldar\_deep\_strike\_building.rgd%' OR building_addons.filename LIKE '%ork\_deep\_strike\_building.rgd%' OR building_addons.filename LIKE '%\_caravel\_ai.rgd%' OR building_addons.filename LIKE '%sisters\_tanktrap\_ai.rgd%' OR building_addons.filename LIKE '%sisters\_hq\_ktgm.rgd%' OR building_addons.filename LIKE '%tau\_squad\_slave\_murdered%' OR building_addons.filename LIKE '%single\_player\_only%' OR building_addons.filename LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR building_addons.filename LIKE '%advance\_sp%' OR building_addons.filename LIKE '%addon\_necron\_hq\_3%');
DELETE FROM abilities WHERE mod_id = mod_id_p AND (filename LIKE '%\_dxp3.%' OR filename LIKE '%\_dxp3.%' OR filename LIKE '%sp\_eldar\_%' OR filename LIKE '%\_sp\_%' OR filename LIKE '%\_sp.%' OR filename LIKE '%\_nis.%' OR filename LIKE '%\_interface\_relay.%' OR filename LIKE '%necron\_tunnel.rgd%' OR filename LIKE '%\_exarch\_council.%' OR filename LIKE '%\_dark\_reapers\_base.%' OR filename LIKE '%eldar\_deep\_strike\_building.rgd%' OR filename LIKE '%ork\_deep\_strike\_building.rgd%' OR filename LIKE '%\_caravel\_ai.rgd%' OR filename LIKE '%sisters\_tanktrap\_ai.rgd%' OR filename LIKE '%sisters\_hq\_ktgm.rgd%' OR filename LIKE '%tau\_squad\_slave\_murdered%' OR filename LIKE '%single\_player\_only%' OR filename LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR filename LIKE '%advance\_sp%');
$$;

View File

@ -0,0 +1,29 @@
{
"databaseChangeLog": [
{
"changeSet": {
"id": "Add order to mod table",
"author": "anibus",
"changes": [
{
"addColumn": {
"columns": [
{
"column": {
"name": "order",
"type": "int",
"defaultValue": 0
},
"constraints": {
"nullable": false
}
}
],
"tableName": "mods"
}
}
]
}
}
]
}

View File

@ -0,0 +1,94 @@
{
"databaseChangeLog": [
{
"changeSet": {
"id": "Change build_cost_time to double in units",
"author": "anibus",
"changes": [
{
"modifyDataType": {
"columnName": "build_cost_time",
"newDataType": "number",
"tableName": "units"
}
}
]
}
},
{
"changeSet": {
"id": "Change build_cost_time to double in sergeants",
"author": "anibus",
"changes": [
{
"modifyDataType": {
"columnName": "build_cost_time",
"newDataType": "number",
"tableName": "sergeants"
}
}
]
}
},
{
"changeSet": {
"id": "Change build_cost_time to double in buildings",
"author": "anibus",
"changes": [
{
"modifyDataType": {
"columnName": "build_cost_time",
"newDataType": "number",
"tableName": "buildings"
}
}
]
}
},
{
"changeSet": {
"id": "Change reinforce_time to double in units",
"author": "anibus",
"changes": [
{
"modifyDataType": {
"columnName": "reinforce_time",
"newDataType": "number",
"tableName": "units"
}
}
]
}
},
{
"changeSet": {
"id": "Change cost_time to double in researches",
"author": "anibus",
"changes": [
{
"modifyDataType": {
"columnName": "cost_time",
"newDataType": "number",
"tableName": "researches"
}
}
]
}
},
{
"changeSet": {
"id": "Change addon_cost_time to double in building_addons",
"author": "anibus",
"changes": [
{
"modifyDataType": {
"columnName": "addon_cost_time",
"newDataType": "number",
"tableName": "building_addons"
}
}
]
}
}
]
}

View File

@ -445,6 +445,22 @@
"include": {
"file": "db/0.0.5/procedures/delete_mod_data_procedure.sql"
}
},{
"include": {
"file": "db/0.0.5/schema/mods.json"
}
},{
"include": {
"file": "db/0.0.5/procedures/delete_campaign_entities.sql"
}
},{
"include": {
"file": "db/0.0.5/procedures/delete_campaign_entities2.sql"
}
},{
"include": {
"file": "db/0.0.6/schema/column_types.json"
}
}
]
}

View File

@ -3,16 +3,14 @@ import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
import com.dowstats.data.rgd.RgdDataUtil.getRgdTableByName
import com.dowstats.data.rgd.RgdDataUtil.getStringByName
import com.dowstats.service.w40k.RgdParserService
import com.dowstats.service.w40k.RgdService
import com.dowstats.service.w40k.helpscripts.RgdService
import org.junit.jupiter.api.Test
import java.io.DataInputStream
import java.io.File
import java.io.PrintWriter
import java.nio.ByteBuffer
class ModDiffPrinter {
val zeroByte: Byte = 0
class ModDiffPrinterScript {
val rgdDictionary: MutableMap<Int, String> = mutableMapOf()
@ -20,8 +18,8 @@ class ModDiffPrinter {
val rgdService = RgdService()
val prevVersion = "wanila"
val currentVersion = "Definitive_Edition2.1.1"
val prevVersion = "wanila2.8.0"
val currentVersion = "wanila"
val spaceMarinesPath = "space_marines"
val chaosPath = "chaos"
@ -33,8 +31,7 @@ class ModDiffPrinter {
val sistersPath = "sisters"
val darkPath = "dark_eldar"
val racesWikiPaths = setOf(spaceMarinesPath, chaosPath, eldarPath, orksPath, guardPath, necronPath, tauPath, sistersPath)
val racesWikiPaths2 = setOf("black_templars")
val racesWikiPaths = setOf(spaceMarinesPath, chaosPath, eldarPath, orksPath, guardPath, necronPath, tauPath, sistersPath, darkPath)
fun readDictionary() {
File("src/test/resources/RGD_DIC.TXT").forEachLine {
@ -50,7 +47,7 @@ class ModDiffPrinter {
private fun getUnitsAndSquadsDiff(out: PrintWriter) {
racesWikiPaths.forEach{racePath ->
val rgdDataOld = File("D:/home/cnb/mods/$prevVersion/Data/attrib/sbps/races/$racePath").walkTopDown().map {
val rgdDataOld = File("E:/home/cnb/$prevVersion/attrib/sbps/races/$racePath").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
@ -60,7 +57,7 @@ class ModDiffPrinter {
}.filter { it.second != null }
.toMap()
val rgdDataNew = File("D:/home/cnb/mods/$currentVersion/Data/attrib/sbps/races/$racePath").walkTopDown().map {
val rgdDataNew = File("E:/home/cnb/$currentVersion/attrib/sbps/races/$racePath").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
}else{
@ -71,7 +68,7 @@ class ModDiffPrinter {
.sortedBy { it.first }
.toMap()
val rgdDataUnitsOld = File("D:/home/cnb/mods/$prevVersion/Data/attrib/ebps/races/$racePath/troops").walkTopDown().map {
val rgdDataUnitsOld = File("E:/home/cnb/$prevVersion/attrib/ebps/races/$racePath/troops").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
}else{
@ -81,7 +78,7 @@ class ModDiffPrinter {
}.filter { it.second != null }
.toMap()
val rgdDataUnitsNew = File("D:/home/cnb/mods/$currentVersion/Data/attrib/ebps/races/$racePath/troops").walkTopDown().map {
val rgdDataUnitsNew = File("E:/home/cnb/$currentVersion/attrib/ebps/races/$racePath/troops").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
}else{
@ -124,7 +121,8 @@ class ModDiffPrinter {
fun getAllWeaponsDiff(out: PrintWriter) {
val wanillaRgdData = File("D:/home/cnb/wanila/attrib/weapon").walkTopDown().map {
val classicRgdData = File("E:/home/cnb/$prevVersion/attrib/weapon").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
@ -134,17 +132,7 @@ class ModDiffPrinter {
}.filter { it.second != null }
.toMap()
val classicRgdData = File("D:/home/cnb/mods/$prevVersion/Data/attrib/weapon").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
null
}
it.name to rgdData
}.filter { it.second != null }
.toMap()
val newRgdData = File("D:/home/cnb/mods/$currentVersion/Data/attrib/weapon").walkTopDown().map {
val newRgdData = File("E:/home/cnb/$currentVersion/attrib/weapon").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
@ -164,7 +152,85 @@ class ModDiffPrinter {
rgdService.printRgdDiff(newWeapon.value, oldWeapon, out = out)
}else{
out.println("NOT EXIST IN PREV VERSION")
rgdService.printRgdDiff(newWeapon.value, wanillaRgdData[newWeapon.key], out = out)
}
out.println("---")
}
}
}
fun getAllAbilitiesDiff(out: PrintWriter) {
val classicRgdData = File("E:/home/cnb/$prevVersion/attrib/abilities").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
null
}
it.name to rgdData
}.filter { it.second != null }
.toMap()
val newRgdData = File("E:/home/cnb/$currentVersion/attrib/abilities").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
null
}
it.name to rgdData
}.filter { it.second != null }
.sortedBy { it.first }
.toMap()
newRgdData.forEach {newWeapon ->
val oldWeapon = classicRgdData[newWeapon.key]
if(oldWeapon != newWeapon.value){
out.println(newWeapon.key.replace(".rgd", "").uppercase())
if(oldWeapon != null){
rgdService.printRgdDiff(newWeapon.value, oldWeapon, out = out)
}else{
out.println("NOT EXIST IN PREV VERSION")
}
out.println("---")
}
}
}
fun getAllResearchDiff(out: PrintWriter) {
val classicRgdData = File("E:/home/cnb/$prevVersion/attrib/research").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
null
}
it.name to rgdData
}.filter { it.second != null }
.toMap()
val newRgdData = File("E:/home/cnb/$currentVersion/attrib/research").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
null
}
it.name to rgdData
}.filter { it.second != null }
.sortedBy { it.first }
.toMap()
newRgdData.forEach {newWeapon ->
val oldWeapon = classicRgdData[newWeapon.key]
if(oldWeapon != newWeapon.value){
out.println(newWeapon.key.replace(".rgd", "").uppercase())
if(oldWeapon != null){
rgdService.printRgdDiff(newWeapon.value, oldWeapon, out = out)
}else{
out.println("NOT EXIST IN PREV VERSION")
// rgdService.printRgdDiff(newWeapon.value, wanillaRgdData[newWeapon.key], out = out)
}
out.println("---")
}
@ -176,7 +242,7 @@ class ModDiffPrinter {
return racesWikiPaths.map{racePath ->
val rgdData42 = File("D:/home/cnb/mods/$currentVersion/Data/attrib/sbps/races/$racePath").walkTopDown().map {
val rgdData42 = File("E:/home/cnb/$currentVersion/attrib/sbps/races/$racePath").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
}else{
@ -186,7 +252,7 @@ class ModDiffPrinter {
}.filter { it.second != null }
.toMap()
val newUnits = File("D:/home/cnb/mods/$currentVersion/Data/attrib/ebps/races/$racePath/troops").walkTopDown().map {
val newUnits = File("E:/home/cnb/$currentVersion/attrib/ebps/races/$racePath/troops").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
}else{
@ -211,7 +277,7 @@ class ModDiffPrinter {
fun getWeaponRgdMap(): Map<String, List<RgdData>?> {
return File("D:/home/cnb/mods/$currentVersion/Data/attrib/weapon").walkTopDown().map {
return File("E:/home/cnb/$currentVersion/attrib/weapon").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
@ -291,7 +357,7 @@ class ModDiffPrinter {
racesWikiPaths.forEach { racePath ->
val classicRgdData =
File("D:/home/cnb/mods/$prevVersion/Data/attrib/ebps/races/$racePath/structures").walkTopDown().map {
File("E:/home/cnb/$prevVersion/attrib/ebps/races/$racePath/structures").walkTopDown().map {
val rgdData = if (it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")) {
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
@ -301,7 +367,7 @@ class ModDiffPrinter {
}.filter { it.second != null }
.toMap()
val newRgdData = File("D:/home/cnb/mods/$currentVersion/Data/attrib/ebps/races/$racePath/structures").walkTopDown().map {
val newRgdData = File("E:/home/cnb/$currentVersion/attrib/ebps/races/$racePath/structures").walkTopDown().map {
val rgdData = if (it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")) {
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
@ -337,21 +403,14 @@ class ModDiffPrinter {
File(buildingsFileName).printWriter().use { out ->
getAllBuildingsDiff(out)
}
val abilityFileName = "$prevVersion-$currentVersion-abilities.txt"
File(abilityFileName).printWriter().use { out ->
getAllAbilitiesDiff(out)
}
private fun findStrategicPointCaptureRate(rgdDataList: List<RgdData>): Double? {
val capRgdData = rgdDataList.find { it.name == "squad_capture_strategic_point_ext" }?.value as List<RgdData>?
val canCapture = capRgdData?.find { it.name == "able_to_capture" }?.value == "[1]"
val captureRate = capRgdData?.find { it.name == "capture_rate" }
return if(canCapture){
captureRate?.value as Double?
} else null
val researchFileName = "$prevVersion-$currentVersion-research.txt"
File(researchFileName).printWriter().use { out ->
getAllResearchDiff(out)
}
private fun findVisionCaptureRate(rgdDataList: List<RgdData>): Double? {
val visionRgdData = rgdDataList.find { it.name == "sight_ext" }?.value as List<RgdData>?
return visionRgdData?.find { it.name == "sight_radius" }?.value as Double?
}
private fun String.decodeHex(): ByteArray {
@ -361,11 +420,6 @@ class ModDiffPrinter {
.toByteArray()
}
private fun ByteArray.getFloat(): Float {
val buffer = ByteBuffer.wrap(this)
return buffer.float
}
private fun ByteArray.getUIntAt(idx: Int): UInt =
((this[idx].toUInt() and 0xFFu) shl 24) or
((this[idx + 1].toUInt() and 0xFFu) shl 16) or

View File

@ -23,7 +23,7 @@ class RtxConvertScript {
@Test
fun convertAllRtx(){
val folder = "D:\\home\\cnb\\wanila\\art\\ui\\ingame"
val folder = "E:\\home\\cnb\\wanila\\art\\ui\\ingame"
File(folder).walkTopDown().map {fileOrFolder ->
if(fileOrFolder.isFile && fileOrFolder.name.endsWith(".dds") ){
try {