mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-13 16:40:01 +00:00
Release v2.2.0 (#741)
* Migrate to TailwindCSS v4 (#740) * Remove "material-tailwind" dependencies due to incompatibility of Stepper component with Tailwind v4 * Clean up Tailwind configs before upgrade * Run HeroUI upgrade * Run TailwindCSS upgrade * Replace PostCSS with Vite * Migrate custom styles to v4 * Remove tailwind.config.ts * Add heroui.ts Add tailwind vite plugin * Fix small UI color inconsistency * Fix theming system Rename purple theme to pink * Re-implement stepper in HeroUI * Fix RoleChip colors * Migrate icon names (#743) * Add migration script for phosphor-icons * Migrate icon usages * Update version to 2.2.0-preview * Revert accidental rename of menu title * Bump stefanzweifel/git-auto-commit-action from 6 to 7 (#750) Bumps [stefanzweifel/git-auto-commit-action](https://github.com/stefanzweifel/git-auto-commit-action) from 6 to 7. - [Release notes](https://github.com/stefanzweifel/git-auto-commit-action/releases) - [Changelog](https://github.com/stefanzweifel/git-auto-commit-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/stefanzweifel/git-auto-commit-action/compare/v6...v7) --- updated-dependencies: - dependency-name: stefanzweifel/git-auto-commit-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Improve library scanning (#749) * Update script to generate example libraries using SteamSpy API * Refactor library scanning process * Display Flyway startup log by default * Fix race condition in CompanyService * Fix race condition in ImageService Remove obsolete table * Fix SMTP config requiring an email as username (#755) * Disable length limit for config values (#757) * Deprecate DockerHub image (#759) * Remove deprecation warning from web UI * Reworked the CICD pipelines * Optimize container image (#761) * Fix Gradle warning * Rework Docker image to improve layer caching * Bump stefanzweifel/git-auto-commit-action from 6 to 7 (#765) Bumps [stefanzweifel/git-auto-commit-action](https://github.com/stefanzweifel/git-auto-commit-action) from 6 to 7. - [Release notes](https://github.com/stefanzweifel/git-auto-commit-action/releases) - [Changelog](https://github.com/stefanzweifel/git-auto-commit-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/stefanzweifel/git-auto-commit-action/compare/v6...v7) --- updated-dependencies: - dependency-name: stefanzweifel/git-auto-commit-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Multi platform support (#764) * Remove migrate-phosphor-icons.js since migration has been successful * Refactor GameMetadata into separate files * Add Platform enum * Implement platform support in Plugin API * Implement platform support in Steam Plugin * Implement platform support in IGDB Plugin * Add database migration for platform support * Implement platform support in GameService * Implement platform support on most endpoints and features, some are still missing Implemented platform support in all bundled plugins (although not finished polishing yet) * Implement platforms in UI * Make GameRequest platform aware * Return headerImages from IGDB * Implement proper PlatformMapper for IGDB plugin * Fix various smaller issues and inconsistencies * Replace placeholder in LibraryOverviewCard (#767) * Bump actions/download-artifact from 5 to 6 (#769) * Bump actions/upload-artifact from 4 to 5 (#770) * Multi platform support (#773) * Fix bug in Plugin API related to state loading/saving * Hide Flyway query logs by default * Extend migration script for multi platform tables * Plugins now store their data and state in ./plugindata * Add "plugindata" directory to entrypoint scripts * Improve download handling (#756) * Process download in background thread to avoid session timeout affecting it * Increase default session timeout to 24h * Use virtual thread pool for download task in background * Make KSP extensions.idx generation more robust * Implement download bandwidth limiter Implement SliderInput Refactor NumberInput * Implement download bandwidth throttling Implement real-time download monitoring * Improve UI for DownloadManagement Track more stats in SessionStats * Update Hilla Use React 19 * Implement real-time graph to track bandwidth usage Implement downloaded data sum over last day Small bug fixes Small refactorings * Update docker-compose.example.yml * Improve DownloadSessionCard (#784) * Fix unit on y-axis of download graph * Show game size and library in tooltip Make game chips interactive in DownloadSessionCard (leads to game page when clicked) Optimize graph settings * Migrate torrent plugin to libtorrent (#775) * Disable TorrentDownloadPlugin in Alpine based Docker image * Improve test coverage (#785) * Fix potential divide by zero bug * Add mockk dependency * Add tests for org.gameyfin.app.core.download * Add tests for Filesytem package Fix DownloadServiceTest * Fix FilesystemServiceTest * Add tests for "job" package * Upgrade Gradle wrapper Enable Gradle config cache * Added more tests * Added tests for the "security" package * Add tests for "game" package * Fix AsyncFileTailer not shutting down properly on Windows * Fix GameServiceTest * Added tests for "libraries" package * Added tests for "media" package * Fix warning in ImageService * Add tests fpr "messages" package Make sure transport is closed even in case an exception is thrown * Add tests for "platforms" package * Add tests for "requests" package * Moved "token" package to "core" package (from "shared") * Add tests for "token" package * Fix issue in RoleEnum.safeValueOf() throwing Exception * Fix potential issue in UserEndpoint.getUserInfo() when auth is null * Added tests for "user" package * Migrate package for "token" in FE * Publish test report in CI * Fix workflow permissions * Remove test because of timing issue in CI * Replaced "unmatched paths" with "ignored paths" (#791) * Use new "AutoComplete" component (#793) * Use ArrayInputAutocomplete in EditGameMetadataModal * Add test for getEnumPropertyValues --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
@@ -12,6 +12,9 @@ dependencies {
|
||||
// PF4J (shared)
|
||||
api("org.pf4j:pf4j:${rootProject.extra["pf4jVersion"]}")
|
||||
|
||||
// Logging
|
||||
implementation("io.github.oshai:kotlin-logging-jvm:7.0.3")
|
||||
|
||||
// JSON serialization
|
||||
compileOnly("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion")
|
||||
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion")
|
||||
|
||||
+2
-5
@@ -82,8 +82,7 @@ abstract class ConfigurableGameyfinPlugin(wrapper: PluginWrapper) : GameyfinPlug
|
||||
*/
|
||||
override fun <T : Serializable> optionalConfig(key: String): T? {
|
||||
val meta = resolveMetadata(key)
|
||||
val value = resolveValue(key)
|
||||
if (value == null) return null
|
||||
val value = resolveValue(key) ?: return null
|
||||
|
||||
return try {
|
||||
castConfigValue(meta, value) as T
|
||||
@@ -101,9 +100,7 @@ abstract class ConfigurableGameyfinPlugin(wrapper: PluginWrapper) : GameyfinPlug
|
||||
*/
|
||||
override fun <T : Serializable> config(key: String): T {
|
||||
val value = optionalConfig<T>(key)
|
||||
if (value == null) {
|
||||
throw PluginConfigError("Required configuration key '$key' is missing or has no value")
|
||||
}
|
||||
?: throw PluginConfigError("Required configuration key '$key' is missing or has no value")
|
||||
return value
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,10 @@ import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||
import org.pf4j.Plugin
|
||||
import org.pf4j.PluginWrapper
|
||||
import java.io.IOException
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.createFile
|
||||
import java.nio.file.StandardOpenOption
|
||||
import kotlin.io.path.exists
|
||||
import kotlin.io.path.fileSize
|
||||
|
||||
@@ -37,7 +38,12 @@ abstract class GameyfinPlugin(wrapper: PluginWrapper) : Plugin(wrapper) {
|
||||
/**
|
||||
* State file for the plugin, used to persist plugin-specific state.
|
||||
*/
|
||||
val stateFile: Path = Path.of("${wrapper.pluginId}.state.json")
|
||||
val stateFile: Path = Path.of("plugindata/${wrapper.pluginId}/state.json")
|
||||
|
||||
/**
|
||||
* Plugin data directory for storing plugin-specific files.
|
||||
*/
|
||||
val dataDirectory: Path = Path.of("plugindata/${wrapper.pluginId}")
|
||||
|
||||
/**
|
||||
* JSON serializer for serializing and deserializing plugin state.
|
||||
@@ -53,11 +59,8 @@ abstract class GameyfinPlugin(wrapper: PluginWrapper) : Plugin(wrapper) {
|
||||
for (format in SUPPORTED_LOGO_FORMATS) {
|
||||
val resourcePath = "$LOGO_FILE_NAME.$format"
|
||||
val inputStream = wrapper.pluginClassLoader.getResourceAsStream(resourcePath)
|
||||
if (inputStream != null) {
|
||||
return true
|
||||
}
|
||||
if (inputStream != null) return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -70,25 +73,37 @@ abstract class GameyfinPlugin(wrapper: PluginWrapper) : Plugin(wrapper) {
|
||||
for (format in SUPPORTED_LOGO_FORMATS) {
|
||||
val resourcePath = "$LOGO_FILE_NAME.$format"
|
||||
val inputStream = wrapper.pluginClassLoader.getResourceAsStream(resourcePath)
|
||||
if (inputStream != null) {
|
||||
return inputStream.readAllBytes()
|
||||
}
|
||||
if (inputStream != null) return inputStream.readAllBytes()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
inline fun <reified T> loadState(): T? {
|
||||
if (!stateFile.exists() || stateFile.fileSize() == 0L) return null
|
||||
return Files.newBufferedReader(stateFile).use {
|
||||
objectMapper.readValue(it.readText(), T::class.java)
|
||||
return try {
|
||||
Files.newBufferedReader(stateFile).use {
|
||||
objectMapper.readValue(it.readText(), T::class.java)
|
||||
}
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <reified T> saveState(state: T) {
|
||||
if (!stateFile.exists()) stateFile.createFile()
|
||||
Files.newBufferedWriter(stateFile).use {
|
||||
it.write(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(state))
|
||||
try {
|
||||
// Ensure parent directories always exist
|
||||
Files.createDirectories(stateFile.parent)
|
||||
// Write JSON, creating or truncating the file atomically
|
||||
Files.newBufferedWriter(
|
||||
stateFile,
|
||||
StandardOpenOption.CREATE,
|
||||
StandardOpenOption.TRUNCATE_EXISTING,
|
||||
StandardOpenOption.WRITE
|
||||
).use {
|
||||
it.write(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(state))
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
throw IllegalStateException("Failed to persist plugin state to $stateFile", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.gameyfin.pluginapi.gamemetadata
|
||||
|
||||
/**
|
||||
* Enum representing the features of a game.
|
||||
*/
|
||||
enum class GameFeature(
|
||||
val displayName: String
|
||||
) {
|
||||
SINGLEPLAYER("Singleplayer"),
|
||||
MULTIPLAYER("Multiplayer"),
|
||||
CO_OP("Co-op"),
|
||||
CROSS_PLATFORM("Cross-Platform"),
|
||||
MODDING("Modding"),
|
||||
VR("VR"),
|
||||
AR("AR"),
|
||||
CLOUD_SAVES("Cloud Saves"),
|
||||
CLOUD_PLAY("Cloud Play"),
|
||||
ACHIEVEMENTS("Achievements"),
|
||||
LEADERBOARDS("Leaderboards"),
|
||||
WORKSHOP("Workshop"),
|
||||
CONTROLLER_SUPPORT("Controller Support"),
|
||||
REMOTE_PLAY("Remote Play"),
|
||||
LOCAL_MULTIPLAYER("Local Multiplayer"),
|
||||
LOCAL_CO_OP("Local Co-op"),
|
||||
ONLINE_MULTIPLAYER("Online Multiplayer"),
|
||||
ONLINE_CO_OP("Online Co-op"),
|
||||
ONLINE_PVP("Online PvP"),
|
||||
ONLINE_PVE("Online PvE"),
|
||||
LOCAL_PVP("Local PvP"),
|
||||
LOCAL_PVE("Local PvE"),
|
||||
CROSSPLAY("Crossplay"),
|
||||
SPLITSCREEN("Splitscreen")
|
||||
}
|
||||
@@ -27,9 +27,10 @@ import java.time.Instant
|
||||
data class GameMetadata(
|
||||
val originalId: String,
|
||||
val title: String,
|
||||
val platforms: Set<Platform>? = null,
|
||||
val description: String? = null,
|
||||
val coverUrls: List<URI>? = null,
|
||||
val headerUrls: List<URI>? = null,
|
||||
val coverUrls: Set<URI>? = null,
|
||||
val headerUrls: Set<URI>? = null,
|
||||
val release: Instant? = null,
|
||||
val userRating: Int? = null,
|
||||
val criticRating: Int? = null,
|
||||
@@ -42,103 +43,4 @@ data class GameMetadata(
|
||||
val videoUrls: Set<URI>? = null,
|
||||
val features: Set<GameFeature>? = null,
|
||||
val perspectives: Set<PlayerPerspective>? = null
|
||||
)
|
||||
|
||||
/**
|
||||
* Enum representing the genre of a game.
|
||||
*/
|
||||
enum class Genre {
|
||||
UNKNOWN,
|
||||
ACTION,
|
||||
PINBALL,
|
||||
ADVENTURE,
|
||||
INDIE,
|
||||
ARCADE,
|
||||
VISUAL_NOVEL,
|
||||
CARD_AND_BOARD_GAME,
|
||||
MOBA,
|
||||
MMO,
|
||||
POINT_AND_CLICK,
|
||||
FIGHTING,
|
||||
SHOOTER,
|
||||
MUSIC,
|
||||
PLATFORM,
|
||||
PUZZLE,
|
||||
RACING,
|
||||
REAL_TIME_STRATEGY,
|
||||
ROLE_PLAYING,
|
||||
SIMULATOR,
|
||||
SPORT,
|
||||
STRATEGY,
|
||||
TURN_BASED_STRATEGY,
|
||||
TACTICAL,
|
||||
HACK_AND_SLASH_BEAT_EM_UP,
|
||||
QUIZ_TRIVIA
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum representing the theme of a game.
|
||||
*/
|
||||
enum class Theme {
|
||||
UNKNOWN,
|
||||
ACTION,
|
||||
FANTASY,
|
||||
SCIENCE_FICTION,
|
||||
HORROR,
|
||||
THRILLER,
|
||||
SURVIVAL,
|
||||
HISTORICAL,
|
||||
STEALTH,
|
||||
COMEDY,
|
||||
BUSINESS,
|
||||
DRAMA,
|
||||
NON_FICTION,
|
||||
SANDBOX,
|
||||
EDUCATIONAL,
|
||||
KIDS,
|
||||
OPEN_WORLD,
|
||||
WARFARE,
|
||||
PARTY,
|
||||
FOUR_X,
|
||||
MYSTERY,
|
||||
EROTIC,
|
||||
ROMANCE
|
||||
}
|
||||
|
||||
enum class GameFeature {
|
||||
SINGLEPLAYER,
|
||||
MULTIPLAYER,
|
||||
CO_OP,
|
||||
CROSS_PLATFORM,
|
||||
MODDING,
|
||||
VR,
|
||||
AR,
|
||||
CLOUD_SAVES,
|
||||
CLOUD_PLAY,
|
||||
ACHIEVEMENTS,
|
||||
LEADERBOARDS,
|
||||
WORKSHOP,
|
||||
CONTROLLER_SUPPORT,
|
||||
REMOTE_PLAY,
|
||||
LOCAL_MULTIPLAYER,
|
||||
LOCAL_CO_OP,
|
||||
ONLINE_MULTIPLAYER,
|
||||
ONLINE_CO_OP,
|
||||
ONLINE_PVP,
|
||||
ONLINE_PVE,
|
||||
LOCAL_PVP,
|
||||
LOCAL_PVE,
|
||||
CROSSPLAY,
|
||||
SPLITSCREEN
|
||||
}
|
||||
|
||||
enum class PlayerPerspective {
|
||||
UNKNOWN,
|
||||
FIRST_PERSON,
|
||||
THIRD_PERSON,
|
||||
BIRD_VIEW_ISOMETRIC,
|
||||
SIDE_VIEW,
|
||||
TEXT,
|
||||
AUDITORY,
|
||||
VIRTUAL_REALITY
|
||||
}
|
||||
)
|
||||
+10
-1
@@ -9,14 +9,23 @@ import org.pf4j.ExtensionPoint
|
||||
* This is typically used to allow plugins to provide metadata for games from various sources.
|
||||
*/
|
||||
interface GameMetadataProvider : ExtensionPoint {
|
||||
|
||||
/**
|
||||
* Returns the set of platforms supported by this metadata provider.
|
||||
*
|
||||
* @return A set of [Platform] enums indicating supported platforms.
|
||||
*/
|
||||
val supportedPlatforms: Set<Platform>
|
||||
|
||||
/**
|
||||
* Fetches a list of game metadata entries matching the given game title.
|
||||
*
|
||||
* @param gameTitle The title of the game to search for.
|
||||
* @param platformFilter A set of [Platform] enums to filter the search results. Only games available on these platforms should be returned.
|
||||
* @param maxResults The maximum number of results to return. Defaults to 1.
|
||||
* @return A list of [GameMetadata] objects matching the title, or an empty list if none found.
|
||||
*/
|
||||
fun fetchByTitle(gameTitle: String, maxResults: Int = 1): List<GameMetadata>
|
||||
fun fetchByTitle(gameTitle: String, platformFilter: Set<Platform>, maxResults: Int = 1): List<GameMetadata>
|
||||
|
||||
/**
|
||||
* Fetches game metadata by its unique identifier.
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.gameyfin.pluginapi.gamemetadata
|
||||
|
||||
/**
|
||||
* Enum representing the genres of a game.
|
||||
*/
|
||||
enum class Genre(
|
||||
val displayName: String
|
||||
) {
|
||||
UNKNOWN("Unknown"),
|
||||
ACTION("Action"),
|
||||
PINBALL("Pinball"),
|
||||
ADVENTURE("Adventure"),
|
||||
INDIE("Indie"),
|
||||
ARCADE("Arcade"),
|
||||
VISUAL_NOVEL("Visual Novel"),
|
||||
CARD_AND_BOARD_GAME("Card & Board Game"),
|
||||
MOBA("MOBA"),
|
||||
MMO("MMO"),
|
||||
POINT_AND_CLICK("Point-and-Click"),
|
||||
FIGHTING("Fighting"),
|
||||
SHOOTER("Shooter"),
|
||||
MUSIC("Music"),
|
||||
PLATFORM("Platform"),
|
||||
PUZZLE("Puzzle"),
|
||||
RACING("Racing"),
|
||||
REAL_TIME_STRATEGY("Real-Time Strategy"),
|
||||
ROLE_PLAYING("Role-Playing"),
|
||||
SIMULATOR("Simulator"),
|
||||
SPORT("Sport"),
|
||||
STRATEGY("Strategy"),
|
||||
TURN_BASED_STRATEGY("Turn-Based Strategy"),
|
||||
TACTICAL("Tactical"),
|
||||
HACK_AND_SLASH_BEAT_EM_UP("Hack and Slash/Beat 'em up"),
|
||||
QUIZ_TRIVIA("Quiz/Trivia")
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
package org.gameyfin.pluginapi.gamemetadata
|
||||
|
||||
/**
|
||||
* Enum representing the platforms of a game.
|
||||
* Source: https://api.igdb.com/v4/platforms
|
||||
*/
|
||||
@Suppress("Unused", "EnumEntryName")
|
||||
enum class Platform(
|
||||
val displayName: String
|
||||
) {
|
||||
// 0-9 (prefixed with underscore because TypeScript enum entries cannot start with a number)
|
||||
_1292_ADVANCED_PROGRAMMABLE_VIDEO_SYSTEM("1292 Advanced Programmable Video System"),
|
||||
_3DO_INTERACTIVE_MULTIPLAYER("3DO Interactive Multiplayer"),
|
||||
_64DD("64DD"),
|
||||
|
||||
// A
|
||||
ACORN_ARCHIMEDES("Acorn Archimedes"),
|
||||
ACORN_ELECTRON("Acorn Electron"),
|
||||
ADVANCED_PICO_BEENA("Advanced Pico Beena"),
|
||||
AIRCONSOLE("AirConsole"),
|
||||
|
||||
AMAZON_FIRE_TV("Amazon Fire TV"),
|
||||
AMIGA("Amiga"),
|
||||
AMIGA_CD32("Amiga CD32"),
|
||||
AMSTRAD_CPC("Amstrad CPC"),
|
||||
AMSTRAD_GX4000("Amstrad GX4000"),
|
||||
AMSTRAD_PCW("Amstrad PCW"),
|
||||
ANDROID("Android"),
|
||||
ANALOGUE_ELECTRONICS("Analogue electronics"),
|
||||
ARCADE("Arcade"),
|
||||
ARCADIA_2001("Arcadia 2001"),
|
||||
ARDUBOY("Arduboy"),
|
||||
APPLE_II("Apple II"),
|
||||
APPLE_IIGS("Apple IIGS"),
|
||||
APPLE_PIPPIN("Apple Pippin"),
|
||||
ATARI_2600("Atari 2600"),
|
||||
ATARI_5200("Atari 5200"),
|
||||
ATARI_7800("Atari 7800"),
|
||||
ATARI_8_BIT("Atari 8-bit"),
|
||||
ATARI_JAGUAR("Atari Jaguar"),
|
||||
ATARI_JAGUAR_CD("Atari Jaguar CD"),
|
||||
ATARI_LYNX("Atari Lynx"),
|
||||
ATARI_ST_STE("Atari ST/STE"),
|
||||
AY_3_8500("AY-3-8500"),
|
||||
AY_3_8603("AY-3-8603"),
|
||||
AY_3_8605("AY-3-8605"),
|
||||
AY_3_8606("AY-3-8606"),
|
||||
AY_3_8607("AY-3-8607"),
|
||||
AY_3_8610("AY-3-8610"),
|
||||
AY_3_8710("AY-3-8710"),
|
||||
AY_3_8760("AY-3-8760"),
|
||||
|
||||
// B
|
||||
BALLY_ASTROCADE("Bally Astrocade"),
|
||||
BBC_MICROCOMPUTER_SYSTEM("BBC Microcomputer System"),
|
||||
BLACKBERRY_OS("BlackBerry OS"),
|
||||
BLU_RAY_PLAYER("Blu-ray Player"),
|
||||
|
||||
// C
|
||||
CALL_A_COMPUTER_TIME_SHARED_MAINFRAME_COMPUTER_SYSTEM("Call-A-Computer time-shared mainframe computer system"),
|
||||
CASIO_LOOPY("Casio Loopy"),
|
||||
CDC_CYBER_70("CDC Cyber 70"),
|
||||
COLECOVISION("ColecoVision"),
|
||||
COMMODORE_16("Commodore 16"),
|
||||
COMMODORE_C64_128_MAX("Commodore C64/128/MAX"),
|
||||
COMMODORE_CDTV("Commodore CDTV"),
|
||||
COMMODORE_PET("Commodore PET"),
|
||||
COMMODORE_PLUS_4("Commodore Plus/4"),
|
||||
COMMODORE_VIC_20("Commodore VIC-20"),
|
||||
|
||||
// D
|
||||
DAYDREAM("Daydream"),
|
||||
DEC_GT40("DEC GT40"),
|
||||
DIGIBLAST("Digiblast"),
|
||||
DONNER_MODEL_30("Donner Model 30"),
|
||||
DOS("DOS"),
|
||||
DRAGON_32_64("Dragon 32/64"),
|
||||
DREAMCAST("Dreamcast"),
|
||||
DUPLICATE_STADIA("DUPLICATE Stadia"),
|
||||
DVD_PLAYER("DVD Player"),
|
||||
|
||||
// E
|
||||
EDSAC("EDSAC"),
|
||||
ELEKTOR_TV_GAMES_COMPUTER("Elektor TV Games Computer"),
|
||||
EPOCH_CASSETTE_VISION("Epoch Cassette Vision"),
|
||||
EPOCH_SUPER_CASSETTE_VISION("Epoch Super Cassette Vision"),
|
||||
EVERCADE("Evercade"),
|
||||
EXIDY_SORCERER("Exidy Sorcerer"),
|
||||
E_READER_CARD_E_READER("e-Reader / Card-e Reader"),
|
||||
|
||||
// F
|
||||
FAMILY_COMPUTER("Family Computer"),
|
||||
FAMILY_COMPUTER_DISK_SYSTEM("Family Computer Disk System"),
|
||||
FAIRCHILD_CHANNEL_F("Fairchild Channel F"),
|
||||
FERRANTI_NIMROD_COMPUTER("Ferranti Nimrod Computer"),
|
||||
FM_TOWNS("FM Towns"),
|
||||
FM_7("FM-7"),
|
||||
|
||||
// G
|
||||
GAME_AND_WATCH("Game & Watch"),
|
||||
GAMATE("Gamate"),
|
||||
GAME_BOY("Game Boy"),
|
||||
GAME_BOY_ADVANCE("Game Boy Advance"),
|
||||
GAME_BOY_COLOR("Game Boy Color"),
|
||||
GAME_COM("Game.com"),
|
||||
GEAR_VR("Gear VR"),
|
||||
GIZMONDO("Gizmondo"),
|
||||
GOOGLE_STADIA("Google Stadia"),
|
||||
|
||||
// H
|
||||
HANDHELD_ELECTRONIC_LCD("Handheld Electronic LCD"),
|
||||
HP_2100("HP 2100"),
|
||||
HP_3000("HP 3000"),
|
||||
HYPER_NEO_GEO_64("Hyper Neo Geo 64"),
|
||||
HYPERSCAN("HyperScan"),
|
||||
|
||||
// I
|
||||
IMLAC_PDS_1("Imlac PDS-1"),
|
||||
INTELLIVISION("Intellivision"),
|
||||
INTELLIVISION_AMICO("Intellivision Amico"),
|
||||
IOS("iOS"),
|
||||
|
||||
// L
|
||||
LASERACTIVE("LaserActive"),
|
||||
LEAPSTER("Leapster"),
|
||||
LEAPSTER_EXPLORER_LEADPAD_EXPLORER("Leapster Explorer/LeadPad Explorer"),
|
||||
LEAPTV("LeapTV"),
|
||||
LEGACY_COMPUTER("Legacy Computer"),
|
||||
LEGACY_MOBILE_DEVICE("Legacy Mobile Device"),
|
||||
LINUX("Linux"),
|
||||
|
||||
// M
|
||||
MAC("Mac"),
|
||||
MEGA_DUCK_COUGAR_BOY("Mega Duck/Cougar Boy"),
|
||||
META_QUEST_2("Meta Quest 2"),
|
||||
META_QUEST_3("Meta Quest 3"),
|
||||
MICROCOMPUTER("Microcomputer"),
|
||||
MICROVISION("Microvision"),
|
||||
MSX("MSX"),
|
||||
MSX2("MSX2"),
|
||||
|
||||
// N
|
||||
N_GAGE("N-Gage"),
|
||||
NEC_PC_6000_SERIES("NEC PC-6000 Series"),
|
||||
NEO_GEO_AES("Neo Geo AES"),
|
||||
NEO_GEO_CD("Neo Geo CD"),
|
||||
NEO_GEO_MVS("Neo Geo MVS"),
|
||||
NEO_GEO_POCKET("Neo Geo Pocket"),
|
||||
NEO_GEO_POCKET_COLOR("Neo Geo Pocket Color"),
|
||||
NEW_NINTENDO_3DS("New Nintendo 3DS"),
|
||||
NINTENDO_3DS("Nintendo 3DS"),
|
||||
NINTENDO_64("Nintendo 64"),
|
||||
NINTENDO_DS("Nintendo DS"),
|
||||
NINTENDO_DSI("Nintendo DSi"),
|
||||
NINTENDO_ENTERTAINMENT_SYSTEM("Nintendo Entertainment System"),
|
||||
NINTENDO_GAMECUBE("Nintendo GameCube"),
|
||||
NINTENDO_SWITCH("Nintendo Switch"),
|
||||
NINTENDO_SWITCH_2("Nintendo Switch 2"),
|
||||
NUON("Nuon"),
|
||||
|
||||
// O
|
||||
OCULUS_GO("Oculus Go"),
|
||||
OCULUS_QUEST("Oculus Quest"),
|
||||
OCULUS_RIFT("Oculus Rift"),
|
||||
OCULUS_VR("Oculus VR"),
|
||||
ODYSSEY("Odyssey"),
|
||||
ODYSSEY_2_VIDEOPAC_G7000("Odyssey 2 / Videopac G7000"),
|
||||
ONLIVE_GAME_SYSTEM("OnLive Game System"),
|
||||
OOPARTS("OOParts"),
|
||||
OUYA("Ouya"),
|
||||
|
||||
// P
|
||||
PALM_OS("Palm OS"),
|
||||
PANASONIC_JUNGLE("Panasonic Jungle"),
|
||||
PANASONIC_M2("Panasonic M2"),
|
||||
PC_MICROSOFT_WINDOWS("PC (Microsoft Windows)"),
|
||||
PC_50X_FAMILY("PC-50X Family"),
|
||||
PC_8800_SERIES("PC-8800 Series"),
|
||||
PC_9800_SERIES("PC-9800 Series"),
|
||||
PC_ENGINE_SUPERGRAFX("PC Engine SuperGrafx"),
|
||||
PC_FX("PC-FX"),
|
||||
PDP_1("PDP-1"),
|
||||
PDP_7("PDP-7"),
|
||||
PDP_8("PDP-8"),
|
||||
PDP_10("PDP-10"),
|
||||
PDP_11("PDP-11"),
|
||||
PHILIPS_CD_I("Philips CD-i"),
|
||||
PLATO("PLATO"),
|
||||
PLAYDATE("Playdate"),
|
||||
PLAYDIA("Playdia"),
|
||||
PLAYSTATION("PlayStation"),
|
||||
PLAYSTATION_2("PlayStation 2"),
|
||||
PLAYSTATION_3("PlayStation 3"),
|
||||
PLAYSTATION_4("PlayStation 4"),
|
||||
PLAYSTATION_5("PlayStation 5"),
|
||||
PLAYSTATION_PORTABLE("PlayStation Portable"),
|
||||
PLAYSTATION_VITA("PlayStation Vita"),
|
||||
PLAYSTATION_VR("PlayStation VR"),
|
||||
PLAYSTATION_VR2("PlayStation VR2"),
|
||||
PLUG_AND_PLAY("Plug & Play"),
|
||||
POCKETSTATION("PocketStation"),
|
||||
POKEMON_MINI("Pokémon mini"),
|
||||
POLYMEGA("Polymega"),
|
||||
|
||||
// R
|
||||
R_ZONE("R-Zone"),
|
||||
|
||||
// S
|
||||
SATELLAVIEW("Satellaview"),
|
||||
SDS_SIGMA_7("SDS Sigma 7"),
|
||||
SEGA_32X("Sega 32X"),
|
||||
SEGA_CD("Sega CD"),
|
||||
SEGA_CD_32X("Sega CD 32X"),
|
||||
SEGA_GAME_GEAR("Sega Game Gear"),
|
||||
SEGA_MASTER_SYSTEM_MARK_III("Sega Master System/Mark III"),
|
||||
SEGA_MEGA_DRIVE_GENESIS("Sega Mega Drive/Genesis"),
|
||||
SEGA_PICO("Sega Pico"),
|
||||
SEGA_SATURN("Sega Saturn"),
|
||||
SG_1000("SG-1000"),
|
||||
SHARP_MZ_2200("Sharp MZ-2200"),
|
||||
SHARP_X1("Sharp X1"),
|
||||
SHARP_X68000("Sharp X68000"),
|
||||
SINCLAIR_QL("Sinclair QL"),
|
||||
SINCLAIR_ZX81("Sinclair ZX81"),
|
||||
SOL_20("Sol-20"),
|
||||
STEAMVR("SteamVR"),
|
||||
SUPER_ACAN("Super A'Can"),
|
||||
SUPER_FAMICOM("Super Famicom"),
|
||||
SUPER_NES_CD_ROM_SYSTEM("Super NES CD-ROM System"),
|
||||
SUPER_NINTENDO_ENTERTAINMENT_SYSTEM("Super Nintendo Entertainment System"),
|
||||
SWANCRYSTAL("SwanCrystal"),
|
||||
|
||||
// T
|
||||
TAPWAVE_ZODIAC("Tapwave Zodiac"),
|
||||
TATUNG_EINSTEIN("Tatung Einstein"),
|
||||
TEXAS_INSTRUMENTS_TI_99("Texas Instruments TI-99"),
|
||||
TEREBIKKO_SEE_N_SAY_VIDEO_PHONE("Terebikko / See 'n Say Video Phone"),
|
||||
THOMSON_MO5("Thomson MO5"),
|
||||
TOMY_TUTOR_PYUTA_GRANDSTAND_TUTOR("Tomy Tutor / Pyuta / Grandstand Tutor"),
|
||||
TRS_80("TRS-80"),
|
||||
TRS_80_COLOR_COMPUTER("TRS-80 Color Computer"),
|
||||
TURBOGRAFX_16_PC_ENGINE_CD("Turbografx-16/PC Engine CD"),
|
||||
TURBOGRAFX_16_PC_ENGINE("TurboGrafx-16/PC Engine"),
|
||||
|
||||
// U
|
||||
UZEBOX("Uzebox"),
|
||||
|
||||
// V
|
||||
V_SMILE("V.Smile"),
|
||||
VC_4000("VC 4000"),
|
||||
VECTREX("Vectrex"),
|
||||
VIRTUAL_BOY("Virtual Boy"),
|
||||
VIRTUAL_CONSOLE("Virtual Console"),
|
||||
VISIONOS("visionOS"),
|
||||
VISUAL_MEMORY_UNIT_VISUAL_MEMORY_SYSTEM("Visual Memory Unit / Visual Memory System"),
|
||||
|
||||
// W
|
||||
WATARA_QUICKSHOT_SUPERVISION("Watara/QuickShot Supervision"),
|
||||
WEB_BROWSER("Web browser"),
|
||||
WII("Wii"),
|
||||
WII_U("Wii U"),
|
||||
WINDOWS_MOBILE("Windows Mobile"),
|
||||
WINDOWS_MIXED_REALITY("Windows Mixed Reality"),
|
||||
WINDOWS_PHONE("Windows Phone"),
|
||||
WONDERSWAN("WonderSwan"),
|
||||
WONDERSWAN_COLOR("WonderSwan Color"),
|
||||
|
||||
// X
|
||||
XBOX("Xbox"),
|
||||
XBOX_360("Xbox 360"),
|
||||
XBOX_ONE("Xbox One"),
|
||||
XBOX_SERIES_X_S("Xbox Series X|S"),
|
||||
|
||||
// Z
|
||||
ZEEBO("Zeebo"),
|
||||
ZX_SPECTRUM("ZX Spectrum");
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.gameyfin.pluginapi.gamemetadata
|
||||
|
||||
/**
|
||||
* Enum representing the perspectives of a game.
|
||||
*/
|
||||
enum class PlayerPerspective(
|
||||
val displayName: String
|
||||
) {
|
||||
UNKNOWN("Unknown"),
|
||||
FIRST_PERSON("First-Person"),
|
||||
THIRD_PERSON("Third-Person"),
|
||||
BIRD_VIEW_ISOMETRIC("Bird View/Isometric"),
|
||||
SIDE_VIEW("Side View"),
|
||||
TEXT("Text"),
|
||||
AUDITORY("Auditory"),
|
||||
VIRTUAL_REALITY("Virtual Reality")
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.gameyfin.pluginapi.gamemetadata
|
||||
|
||||
/**
|
||||
* Enum representing the themes of a game.
|
||||
*/
|
||||
enum class Theme(
|
||||
val displayName: String
|
||||
) {
|
||||
UNKNOWN("Unknown"),
|
||||
ACTION("Action"),
|
||||
FANTASY("Fantasy"),
|
||||
SCIENCE_FICTION("Science Fiction"),
|
||||
HORROR("Horror"),
|
||||
THRILLER("Thriller"),
|
||||
SURVIVAL("Survival"),
|
||||
HISTORICAL("Historical"),
|
||||
STEALTH("Stealth"),
|
||||
COMEDY("Comedy"),
|
||||
BUSINESS("Business"),
|
||||
DRAMA("Drama"),
|
||||
NON_FICTION("Non-Fiction"),
|
||||
SANDBOX("Sandbox"),
|
||||
EDUCATIONAL("Educational"),
|
||||
KIDS("Kids"),
|
||||
OPEN_WORLD("Open World"),
|
||||
WARFARE("Warfare"),
|
||||
PARTY("Party"),
|
||||
FOUR_X("4X"),
|
||||
MYSTERY("Mystery"),
|
||||
EROTIC("Erotic"),
|
||||
ROMANCE("Romance")
|
||||
}
|
||||
Reference in New Issue
Block a user