Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow region loading even when xtea is missing (but warn) #49

Merged
merged 1 commit into from
Jul 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/kotlin/cache/definitions/LocationsDefinition.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package cache.definitions

data class LocationsDefinition(
val regionId: Int = 0,
val locations: ArrayList<Location> = ArrayList<Location>()
val locations: ArrayList<Location> = ArrayList()
)

data class Location(
Expand Down
16 changes: 11 additions & 5 deletions src/main/kotlin/cache/loaders/LocationsLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import cache.definitions.LocationsDefinition
import cache.utils.readUnsignedShortSmart
import cache.utils.readUnsignedSmartShortExtended
import com.displee.cache.CacheLibrary
import org.slf4j.LoggerFactory
import java.nio.BufferUnderflowException
import java.nio.ByteBuffer

Expand All @@ -14,29 +15,35 @@ class LocationsLoader(
private val xtea: XteaManager,
private val locationsDefinitionCache: HashMap<Int, LocationsDefinition?> = HashMap()
) {
private val logger = LoggerFactory.getLogger(LocationsLoader::class.java)

fun get(regionId: Int): LocationsDefinition? {
if (locationsDefinitionCache.containsKey(regionId)) {
return locationsDefinitionCache[regionId]
}
return try {
val location = try {
loadLocations(regionId)
} catch (e: BufferUnderflowException) {
e.printStackTrace() // Alert an attentive user that an issue has occurred
null
}
locationsDefinitionCache[regionId] = location
return location
}

private fun loadLocations(regionId: Int): LocationsDefinition? {
val locationsDefinition = LocationsDefinition(regionId)

val x = (regionId shr 8) and 0xFF
val y = regionId and 0xFF
val landscape = library.data(5, "l${x}_$y", xtea.getKeys(regionId))
if (landscape == null) {
locationsDefinitionCache[regionId] = null
val xteaKeys = xtea.getKeys(regionId)
if (xteaKeys == null) {
logger.warn("Could not get xtea keys for region $regionId ($x, $y)")
return null
}

val landscape = library.data(5, "l${x}_$y", xteaKeys) ?: return null

val buffer = ByteBuffer.wrap(landscape)

var objId = -1
Expand Down Expand Up @@ -74,7 +81,6 @@ class LocationsLoader(
idOffset = buffer.readUnsignedShortSmart()
}

locationsDefinitionCache[regionId] = locationsDefinition
return locationsDefinition
}
}
4 changes: 4 additions & 0 deletions src/main/kotlin/cache/loaders/RegionLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ import cache.definitions.RegionDefinition.Companion.Y
import cache.definitions.RegionDefinition.Companion.Z
import cache.utils.readUnsignedByte
import com.displee.cache.CacheLibrary
import org.slf4j.LoggerFactory
import utils.Utils
import java.nio.ByteBuffer

class RegionLoader(
private val cacheLibrary: CacheLibrary,
private val regionDefinitionCache: HashMap<Int, RegionDefinition?> = HashMap()
) {
private val logger = LoggerFactory.getLogger(RegionLoader::class.java)

fun get(regionId: Int): RegionDefinition? {
if (regionDefinitionCache.containsKey(regionId)) {
return regionDefinitionCache[regionId]
Expand All @@ -27,6 +30,7 @@ class RegionLoader(
val regionY = regionId and 0xFF
val map = cacheLibrary.data(IndexType.MAPS.id, "m${regionX}_$regionY")
if (map == null) {
logger.warn("Could not load region (tile) data for $regionId")
regionDefinitionCache[regionId] = null // Negative cache entry
return null
}
Expand Down
7 changes: 6 additions & 1 deletion src/main/kotlin/models/scene/SceneRegionBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class SceneRegionBuilder @Inject constructor(
// int regionId = (x >>> 6 << 8) | y >>> 6;
fun loadRegion(regionId: Int, isAnimationEnabled: Boolean): SceneRegion? {
val region: RegionDefinition = regionLoader.get(regionId) ?: return null
val locations: LocationsDefinition = locationsLoader.get(regionId) ?: return null
val locations: LocationsDefinition = locationsLoader.get(regionId) ?: fakeLocationsDefinition(regionId)
val sceneRegion = SceneRegion(locations)
val baseX: Int = region.baseX
val baseY: Int = region.baseY
Expand Down Expand Up @@ -378,6 +378,11 @@ class SceneRegionBuilder @Inject constructor(
return sceneRegion
}

private fun fakeLocationsDefinition(regionId: Int): LocationsDefinition {
logger.warn("Could not find location (entity) data for region $regionId")
return LocationsDefinition(regionId)
}

private fun getEntity(
objectDefinition: ObjectDefinition,
type: Int,
Expand Down