mirror of
https://github.com/izzy2lost/WeeU.git
synced 2026-07-06 00:19:59 -07:00
added more gameids to download covers and additional game info
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -4,15 +4,24 @@ import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.izzy2lost.weeu.common.ui.components.ScreenContent
|
||||
import com.izzy2lost.weeu.common.ui.localization.regionToString
|
||||
import com.izzy2lost.weeu.common.ui.localization.tr
|
||||
import com.izzy2lost.weeu.gamelist.cover.GameTitleMapper
|
||||
import com.izzy2lost.weeu.nativeinterface.NativeGameTitles.Game
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
@@ -23,23 +32,81 @@ fun GameDetailsScreen(game: Game?, navigateBack: () -> Unit) {
|
||||
if (game == null)
|
||||
return
|
||||
|
||||
val context = LocalContext.current
|
||||
var gameInfo by remember { mutableStateOf<GameInfo?>(null) }
|
||||
|
||||
LaunchedEffect(game.titleId) {
|
||||
GameTitleMapper.initialize(context)
|
||||
val titleIdHex = game.titleId.toString(16).uppercase().padStart(16, '0')
|
||||
val gameId = GameTitleMapper.getGameCodeFromTitleId(titleIdHex)
|
||||
if (gameId != null) {
|
||||
gameInfo = GameInfoLoader.loadGameInfo(context, gameId)
|
||||
}
|
||||
}
|
||||
|
||||
ScreenContent(
|
||||
appBarText = tr("About title"),
|
||||
contentModifier = Modifier.padding(16.dp),
|
||||
contentModifier = Modifier
|
||||
.padding(16.dp)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
contentVerticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
navigateBack = navigateBack,
|
||||
) {
|
||||
GameDetails(game)
|
||||
GameDetails(game, gameInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GameDetails(game: Game) {
|
||||
fun GameDetails(game: Game, gameInfo: GameInfo?) {
|
||||
GameIcon(
|
||||
game = game,
|
||||
modifier = Modifier.size(128.dp),
|
||||
)
|
||||
TitleDetailsEntry(entryName = tr("Title name"), entryData = game.name)
|
||||
|
||||
// Game database information
|
||||
if (gameInfo != null) {
|
||||
gameInfo.title?.let {
|
||||
TitleDetailsEntry(entryName = tr("Title"), entryData = it)
|
||||
}
|
||||
gameInfo.developer?.let {
|
||||
TitleDetailsEntry(entryName = tr("Developer"), entryData = it)
|
||||
}
|
||||
gameInfo.publisher?.let {
|
||||
TitleDetailsEntry(entryName = tr("Publisher"), entryData = it)
|
||||
}
|
||||
gameInfo.releaseDate?.let {
|
||||
TitleDetailsEntry(entryName = tr("Release Date"), entryData = it)
|
||||
}
|
||||
gameInfo.genre?.let {
|
||||
TitleDetailsEntry(entryName = tr("Genre"), entryData = it)
|
||||
}
|
||||
gameInfo.rating?.let {
|
||||
TitleDetailsEntry(entryName = tr("Rating"), entryData = it)
|
||||
}
|
||||
if (gameInfo.ratingDescriptors.isNotEmpty()) {
|
||||
TitleDetailsEntry(
|
||||
entryName = tr("Content Descriptors"),
|
||||
entryData = gameInfo.ratingDescriptors.joinToString(", ")
|
||||
)
|
||||
}
|
||||
gameInfo.players?.let {
|
||||
TitleDetailsEntry(entryName = tr("Players"), entryData = it)
|
||||
}
|
||||
gameInfo.wifiPlayers?.let {
|
||||
TitleDetailsEntry(entryName = tr("Wi-Fi Players"), entryData = it)
|
||||
}
|
||||
if (gameInfo.wifiFeatures.isNotEmpty()) {
|
||||
TitleDetailsEntry(
|
||||
entryName = tr("Wi-Fi Features"),
|
||||
entryData = gameInfo.wifiFeatures.joinToString(", ")
|
||||
)
|
||||
}
|
||||
gameInfo.synopsis?.let {
|
||||
TitleDetailsEntry(entryName = tr("Synopsis"), entryData = it)
|
||||
}
|
||||
}
|
||||
|
||||
// Local game information
|
||||
TitleDetailsEntry(entryName = tr("Title ID"), entryData = game.titleId)
|
||||
TitleDetailsEntry(entryName = tr("Version"), entryData = game.version)
|
||||
TitleDetailsEntry(entryName = tr("DLC"), entryData = game.dlc)
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
package com.izzy2lost.weeu.gamelist
|
||||
|
||||
import android.content.Context
|
||||
import org.xmlpull.v1.XmlPullParser
|
||||
import org.xmlpull.v1.XmlPullParserFactory
|
||||
import java.io.InputStreamReader
|
||||
|
||||
data class GameInfo(
|
||||
val id: String,
|
||||
val title: String?,
|
||||
val synopsis: String?,
|
||||
val developer: String?,
|
||||
val publisher: String?,
|
||||
val releaseDate: String?,
|
||||
val genre: String?,
|
||||
val rating: String?,
|
||||
val ratingDescriptors: List<String>,
|
||||
val players: String?,
|
||||
val wifiPlayers: String?,
|
||||
val wifiFeatures: List<String>
|
||||
)
|
||||
|
||||
object GameInfoLoader {
|
||||
private var gameInfoCache: MutableMap<String, GameInfo> = mutableMapOf()
|
||||
|
||||
fun loadGameInfo(context: Context, gameId: String): GameInfo? {
|
||||
// Check cache first
|
||||
if (gameInfoCache.containsKey(gameId)) {
|
||||
return gameInfoCache[gameId]
|
||||
}
|
||||
|
||||
try {
|
||||
val inputStream = context.assets.open("wiiutdb.xml")
|
||||
val reader = InputStreamReader(inputStream)
|
||||
val factory = XmlPullParserFactory.newInstance()
|
||||
val parser = factory.newPullParser()
|
||||
parser.setInput(reader)
|
||||
|
||||
var eventType = parser.eventType
|
||||
var currentGameId: String? = null
|
||||
var title: String? = null
|
||||
var synopsis: String? = null
|
||||
var developer: String? = null
|
||||
var publisher: String? = null
|
||||
var releaseDate: String? = null
|
||||
var genre: String? = null
|
||||
var rating: String? = null
|
||||
val ratingDescriptors = mutableListOf<String>()
|
||||
var players: String? = null
|
||||
var wifiPlayers: String? = null
|
||||
val wifiFeatures = mutableListOf<String>()
|
||||
var inGame = false
|
||||
var inLocale = false
|
||||
var inRating = false
|
||||
var inWifi = false
|
||||
var inInput = false
|
||||
|
||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||
when (eventType) {
|
||||
XmlPullParser.START_TAG -> {
|
||||
when (parser.name) {
|
||||
"game" -> {
|
||||
inGame = true
|
||||
// Reset values for new game
|
||||
currentGameId = null
|
||||
title = null
|
||||
synopsis = null
|
||||
developer = null
|
||||
publisher = null
|
||||
releaseDate = null
|
||||
genre = null
|
||||
rating = null
|
||||
ratingDescriptors.clear()
|
||||
players = null
|
||||
wifiPlayers = null
|
||||
wifiFeatures.clear()
|
||||
}
|
||||
"id" -> {
|
||||
if (inGame) {
|
||||
parser.next()
|
||||
currentGameId = parser.text
|
||||
}
|
||||
}
|
||||
"locale" -> {
|
||||
if (inGame && parser.getAttributeValue(null, "lang") == "EN") {
|
||||
inLocale = true
|
||||
}
|
||||
}
|
||||
"title" -> {
|
||||
if (inLocale) {
|
||||
parser.next()
|
||||
title = parser.text
|
||||
}
|
||||
}
|
||||
"synopsis" -> {
|
||||
if (inLocale) {
|
||||
parser.next()
|
||||
synopsis = parser.text
|
||||
}
|
||||
}
|
||||
"developer" -> {
|
||||
if (inGame) {
|
||||
parser.next()
|
||||
developer = parser.text
|
||||
}
|
||||
}
|
||||
"publisher" -> {
|
||||
if (inGame) {
|
||||
parser.next()
|
||||
publisher = parser.text
|
||||
}
|
||||
}
|
||||
"date" -> {
|
||||
if (inGame) {
|
||||
val year = parser.getAttributeValue(null, "year")
|
||||
val month = parser.getAttributeValue(null, "month")
|
||||
val day = parser.getAttributeValue(null, "day")
|
||||
releaseDate = "$year-$month-$day"
|
||||
}
|
||||
}
|
||||
"genre" -> {
|
||||
if (inGame) {
|
||||
parser.next()
|
||||
genre = parser.text
|
||||
}
|
||||
}
|
||||
"rating" -> {
|
||||
if (inGame) {
|
||||
inRating = true
|
||||
val type = parser.getAttributeValue(null, "type")
|
||||
val value = parser.getAttributeValue(null, "value")
|
||||
rating = "$type: $value"
|
||||
}
|
||||
}
|
||||
"descriptor" -> {
|
||||
if (inRating) {
|
||||
parser.next()
|
||||
parser.text?.let { ratingDescriptors.add(it) }
|
||||
}
|
||||
}
|
||||
"wi-fi" -> {
|
||||
if (inGame) {
|
||||
inWifi = true
|
||||
wifiPlayers = parser.getAttributeValue(null, "players")
|
||||
}
|
||||
}
|
||||
"feature" -> {
|
||||
if (inWifi) {
|
||||
parser.next()
|
||||
parser.text?.let { wifiFeatures.add(it) }
|
||||
}
|
||||
}
|
||||
"input" -> {
|
||||
if (inGame) {
|
||||
inInput = true
|
||||
players = parser.getAttributeValue(null, "players")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
XmlPullParser.END_TAG -> {
|
||||
when (parser.name) {
|
||||
"game" -> {
|
||||
// Check if this is the game we're looking for
|
||||
if (currentGameId == gameId) {
|
||||
val gameInfo = GameInfo(
|
||||
id = currentGameId,
|
||||
title = title,
|
||||
synopsis = synopsis,
|
||||
developer = developer,
|
||||
publisher = publisher,
|
||||
releaseDate = releaseDate,
|
||||
genre = genre,
|
||||
rating = rating,
|
||||
ratingDescriptors = ratingDescriptors.toList(),
|
||||
players = players,
|
||||
wifiPlayers = wifiPlayers,
|
||||
wifiFeatures = wifiFeatures.toList()
|
||||
)
|
||||
gameInfoCache[gameId] = gameInfo
|
||||
reader.close()
|
||||
return gameInfo
|
||||
}
|
||||
inGame = false
|
||||
}
|
||||
"locale" -> inLocale = false
|
||||
"rating" -> inRating = false
|
||||
"wi-fi" -> inWifi = false
|
||||
"input" -> inInput = false
|
||||
}
|
||||
}
|
||||
}
|
||||
eventType = parser.next()
|
||||
}
|
||||
|
||||
reader.close()
|
||||
} catch (e: Exception) {
|
||||
println("Error loading game info for $gameId: ${e.message}")
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun clearCache() {
|
||||
gameInfoCache.clear()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user