diff --git a/.gitignore b/.gitignore index c51bf1e..96c327c 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,6 @@ replay_*.log #Stuff .github/ .architectury-transformer + +# secrets +.env diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..c147fa5 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,166 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +AuctionHouse is a server-side Minecraft mod allowing players to sell items to other players. It's a multi-loader mod supporting both **Fabric** and **NeoForge** using the Architectury framework. + +- **Minecraft Version**: 1.21.8 +- **Java Version**: 21 +- **Build System**: Gradle with Architectury plugin + +## Build Commands + +```bash +# Build all platforms (requires Java 21) +JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-21.jdk/Contents/Home ./gradlew build + +# Build specific loader +./gradlew :fabric:build +./gradlew :neoforge:build + +# Run development server for testing +./gradlew :fabric:runServer +./gradlew :neoforge:runServer +``` + +Output JARs are placed in `/output/` directory with classifiers: `-fabric`, `-neoforge`. + +## Architecture + +### Multi-Loader Structure + +``` +common/ → Shared code (all business logic lives here) +fabric/ → Fabric-specific entry point and mixins +neoforge/ → NeoForge-specific entry point, permissions, and mixins +``` + +The `common` module contains all actual functionality. Loader modules only provide entry points (`AuctionHouseFabricMod`, `AuctionHouseModNeoForge`) and inject server startup hooks via Mixins. + +### Core Packages (in common/) + +- **auction/**: Core auction logic - `AuctionHouse` (item collection), `AuctionItem` (individual listing), `ExpiredItems` +- **command/**: Brigadier commands - 8 commands under `/ah` (main, sell, selling, expired, cancel, return, reload, help) +- **config/**: JSON config via GSON at `./config/auctionhouse.json` +- **economy/**: Abstract `EconomyHandler` with factory pattern - supports Impactor API and RealEconomy +- **gui/**: Server-side GUIs using SGui library with pagination +- **sql/**: SQLite persistence via `DatabaseManager` interface and `SQLiteDatabaseManager` + +### Key Patterns + +- **Factory Pattern**: `EconomyHandler.getHandler()` selects economy implementation at runtime based on loaded mods +- **Mixin Injection**: Both loaders inject into `MinecraftServer` to hook server start/stop lifecycle +- **Interface Abstraction**: `DatabaseManager` interface allows different DB implementations + +### Entry Point Flow + +1. Mixin injects into `MinecraftServer.runServer()` +2. Calls `AuctionHouseMod.onServerStarted(server)` +3. Initializes SQLite DB, loads config, detects economy handler +4. Registers commands via `AuctionHouseMainCommand.register()` + +### Dependencies + +- **SGui**: Server-side GUI library (eu.pb4:sgui) +- **SQLite JDBC**: Database storage +- **LuckPerms API**: Permissions (Fabric) +- **Impactor/RealEconomy**: Economy integrations + +## Required Runtime Mods + +The built mod requires these at runtime: +- SQLite Mod (minecraft-sqlite-jdbc) +- Either Impactor or RealEconomy for economy support + +## Publishing to Modrinth + +The Modrinth API key is stored in `.env` (not versioned). Project ID: `TODO` + +To publish a new version, create one version per loader (fabric, neoforge): + +```bash +# Load API key +source .env + +# Publish Fabric version +curl -X POST "https://api.modrinth.com/v2/version" \ + -H "Authorization: $MODRINTH_API_KEY" \ + -F 'data={ + "name": "AuctionHouse VERSION-fabric", + "version_number": "VERSION-fabric", + "changelog": "Changelog here", + "dependencies": [], + "game_versions": ["MC_VERSION"], + "version_type": "release", + "loaders": ["fabric"], + "featured": true, + "status": "listed", + "project_id": "TODO", + "file_parts": ["file"] + }' \ + -F "file=@output/auctionhouse-VERSION-fabric.jar" + +# Repeat for neoforge (loaders: ["neoforge"]) +``` + +Replace `VERSION` with the version (e.g., `1.2.3+1.21.8`) and `MC_VERSION` with Minecraft version. + +## GitHub Releases + +Create a GitHub release with the build artifacts: + +```bash +gh release create vMC_VERSION \ + --title "vMC_VERSION" \ + --notes "## Port to Minecraft MC_VERSION + +### Changes +- List changes here + +### Downloads +- **Fabric**: \`auctionhouse-VERSION-fabric.jar\` +- **NeoForge**: \`auctionhouse-VERSION-neoforge.jar\` + +Also available on [Modrinth](https://modrinth.com/mod/auctionhouse/versions?g=MC_VERSION)" \ + --target BRANCH_NAME \ + output/auctionhouse-VERSION-fabric.jar \ + output/auctionhouse-VERSION-neoforge.jar +``` + +Replace `MC_VERSION` with Minecraft version (e.g., `1.21.8`), `VERSION` with full version (e.g., `1.2.3+1.21.8`), and `BRANCH_NAME` with the release branch. + +## Publishing to CurseForge + +The CurseForge API key and project ID are stored in `.env`. Project ID: `TODO` + +Game version IDs (find new ones via `https://minecraft.curseforge.com/api/game/versions`): +- **Loaders**: Fabric=`7499`, NeoForge=`10150` +- **Minecraft versions**: check API for current IDs (e.g., 1.21.8=`13620`) + +```bash +# Load API key +source .env + +# Publish Fabric version +curl -X POST "https://minecraft.curseforge.com/api/projects/$CURSEFORGE_PROJECT_ID/upload-file" \ + -H "X-Api-Token: $CURSEFORGE_API_KEY" \ + -F 'metadata={ + "changelog": "Changelog here", + "changelogType": "markdown", + "displayName": "AuctionHouse VERSION-fabric", + "gameVersions": [MC_VERSION_ID, 7499], + "releaseType": "release" + }' \ + -F "file=@output/auctionhouse-VERSION-fabric.jar" + +# Repeat for neoforge (10150) +``` + +Replace `VERSION` with full version, `MC_VERSION_ID` with the numeric Minecraft version ID from the API. + +## Commit/PR Guidelines + +- Do not mention Claude Code or AI assistance in commit messages or PR descriptions +- Always use `git push --force-with-lease` instead of `git push --force` diff --git a/build.gradle b/build.gradle index 193293c..7d792cf 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'dev.architectury.loom' version '1.10-SNAPSHOT' apply false + id 'dev.architectury.loom' version '1.13-SNAPSHOT' apply false id 'architectury-plugin' version '3.4-SNAPSHOT' id 'com.github.johnrengelman.shadow' version '8.1.1' apply false } diff --git a/common/build.gradle b/common/build.gradle index 9952da4..56a6a25 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -23,7 +23,7 @@ dependencies { implementation "co.lemee.realeconomy:realeconomy:0.1.1+1.21.4-dev" modImplementation "org.sqlite:sqlite-jdbc:3.49.1.0" - modImplementation "eu.pb4:sgui:1.6.1+1.21.1" + modImplementation "co.lemee:servui:1.9.1+1.21.10" } publishing { diff --git a/common/libs/servui-1.9.1+1.21.10.jar b/common/libs/servui-1.9.1+1.21.10.jar new file mode 100644 index 0000000..abbf658 Binary files /dev/null and b/common/libs/servui-1.9.1+1.21.10.jar differ diff --git a/common/src/main/java/co/lemee/auctionhouse/auction/AuctionItem.java b/common/src/main/java/co/lemee/auctionhouse/auction/AuctionItem.java index 8ebd6e4..9b0e2b4 100644 --- a/common/src/main/java/co/lemee/auctionhouse/auction/AuctionItem.java +++ b/common/src/main/java/co/lemee/auctionhouse/auction/AuctionItem.java @@ -29,7 +29,7 @@ public AuctionItem(int id, String playerUuid, String owner, ItemStack stack, dou public AuctionItem(int id, String playerUuid, String owner, String nbt, String item, int count, double price, long secondsLeft) { this.id = id; - this.itemStack = new ItemStack(BuiltInRegistries.ITEM.get(ResourceLocation.parse(item)), count); + this.itemStack = new ItemStack(BuiltInRegistries.ITEM.get(ResourceLocation.parse(item)).orElseThrow(), count); this.itemStack.applyComponents(deserialize(JsonParser.parseString(nbt))); this.nbt = nbt; this.uuid = playerUuid; diff --git a/common/src/main/java/co/lemee/auctionhouse/gui/GUIAuctionHouse.java b/common/src/main/java/co/lemee/auctionhouse/gui/GUIAuctionHouse.java index 992c2ec..841b77d 100644 --- a/common/src/main/java/co/lemee/auctionhouse/gui/GUIAuctionHouse.java +++ b/common/src/main/java/co/lemee/auctionhouse/gui/GUIAuctionHouse.java @@ -3,11 +3,11 @@ import co.lemee.auctionhouse.AuctionHouseMod; import co.lemee.auctionhouse.auction.AuctionItem; import co.lemee.auctionhouse.config.ConfigManager; -import eu.pb4.sgui.api.elements.GuiElement; -import eu.pb4.sgui.api.elements.GuiElementBuilder; -import eu.pb4.sgui.api.elements.GuiElementBuilderInterface; -import eu.pb4.sgui.api.elements.GuiElementInterface; -import eu.pb4.sgui.api.gui.SimpleGui; +import co.lemee.servui.api.elements.GuiElement; +import co.lemee.servui.api.elements.GuiElementBuilder; +import co.lemee.servui.api.elements.GuiElementBuilderInterface; +import co.lemee.servui.api.elements.GuiElementInterface; +import co.lemee.servui.api.gui.SimpleGui; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; diff --git a/common/src/main/java/co/lemee/auctionhouse/gui/GUIAuctionItem.java b/common/src/main/java/co/lemee/auctionhouse/gui/GUIAuctionItem.java index 636739c..6a79b5f 100644 --- a/common/src/main/java/co/lemee/auctionhouse/gui/GUIAuctionItem.java +++ b/common/src/main/java/co/lemee/auctionhouse/gui/GUIAuctionItem.java @@ -3,11 +3,11 @@ import co.lemee.auctionhouse.AuctionHouseMod; import co.lemee.auctionhouse.auction.AuctionItem; import co.lemee.auctionhouse.economy.EconomyHandler; -import eu.pb4.sgui.api.elements.GuiElement; -import eu.pb4.sgui.api.elements.GuiElementBuilder; -import eu.pb4.sgui.api.elements.GuiElementBuilderInterface; -import eu.pb4.sgui.api.elements.GuiElementInterface; -import eu.pb4.sgui.api.gui.SimpleGui; +import co.lemee.servui.api.elements.GuiElement; +import co.lemee.servui.api.elements.GuiElementBuilder; +import co.lemee.servui.api.elements.GuiElementBuilderInterface; +import co.lemee.servui.api.elements.GuiElementInterface; +import co.lemee.servui.api.gui.SimpleGui; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; diff --git a/common/src/main/java/co/lemee/auctionhouse/gui/GUIExpiredItems.java b/common/src/main/java/co/lemee/auctionhouse/gui/GUIExpiredItems.java index 91ff4af..564b7f2 100644 --- a/common/src/main/java/co/lemee/auctionhouse/gui/GUIExpiredItems.java +++ b/common/src/main/java/co/lemee/auctionhouse/gui/GUIExpiredItems.java @@ -4,11 +4,11 @@ import co.lemee.auctionhouse.auction.AuctionItem; import co.lemee.auctionhouse.auction.ExpiredItems; import co.lemee.auctionhouse.config.ConfigManager; -import eu.pb4.sgui.api.elements.GuiElement; -import eu.pb4.sgui.api.elements.GuiElementBuilder; -import eu.pb4.sgui.api.elements.GuiElementBuilderInterface; -import eu.pb4.sgui.api.elements.GuiElementInterface; -import eu.pb4.sgui.api.gui.SimpleGui; +import co.lemee.servui.api.elements.GuiElement; +import co.lemee.servui.api.elements.GuiElementBuilder; +import co.lemee.servui.api.elements.GuiElementBuilderInterface; +import co.lemee.servui.api.elements.GuiElementInterface; +import co.lemee.servui.api.gui.SimpleGui; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; diff --git a/common/src/main/java/co/lemee/auctionhouse/gui/GUIPersonalAuctionHouse.java b/common/src/main/java/co/lemee/auctionhouse/gui/GUIPersonalAuctionHouse.java index ddac5eb..19e6a45 100644 --- a/common/src/main/java/co/lemee/auctionhouse/gui/GUIPersonalAuctionHouse.java +++ b/common/src/main/java/co/lemee/auctionhouse/gui/GUIPersonalAuctionHouse.java @@ -4,11 +4,11 @@ import co.lemee.auctionhouse.auction.AuctionHouse; import co.lemee.auctionhouse.auction.AuctionItem; import co.lemee.auctionhouse.config.ConfigManager; -import eu.pb4.sgui.api.elements.GuiElement; -import eu.pb4.sgui.api.elements.GuiElementBuilder; -import eu.pb4.sgui.api.elements.GuiElementBuilderInterface; -import eu.pb4.sgui.api.elements.GuiElementInterface; -import eu.pb4.sgui.api.gui.SimpleGui; +import co.lemee.servui.api.elements.GuiElement; +import co.lemee.servui.api.elements.GuiElementBuilder; +import co.lemee.servui.api.elements.GuiElementBuilderInterface; +import co.lemee.servui.api.elements.GuiElementInterface; +import co.lemee.servui.api.gui.SimpleGui; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; diff --git a/fabric/build.gradle b/fabric/build.gradle index 5a745ef..57dfb6e 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -35,8 +35,11 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:$rootProject.fabric_loader_version" modApi "net.fabricmc.fabric-api:fabric-api:$rootProject.fabric_api_version+$rootProject.minecraft_version" - modImplementation include('me.lucko:fabric-permissions-api:0.2-SNAPSHOT') - modImplementation include("eu.pb4:sgui:1.9.1+1.21.1-fabric") + modImplementation include('me.lucko:fabric-permissions-api:0.5.0') + modImplementation include("eu.pb4:sgui:1.11.0+1.21.9") + + // SQLite JDBC for dev runtime (normally provided by minecraft-sqlite-jdbc mod) + runtimeOnly 'org.xerial:sqlite-jdbc:3.47.0.0' common(project(path: ':common', configuration: 'namedElements')) { transitive false } shadowBundle project(path: ':common', configuration: 'transformProductionFabric') diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 7cf34ff..2bff58f 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -25,7 +25,7 @@ ], "depends": { "fabricloader": ">=0.16.9", - "minecraft": "~1.21.1", + "minecraft": ">=1.21.8", "java": ">=21", "fabric-api": "*" }, diff --git a/gradle.properties b/gradle.properties index 163537d..bc11bfc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,12 +10,12 @@ maven_group=co.lemee.auctionhouse # Fabric Properties # check these on https://fabricmc.net/develop -minecraft_version=1.21.1 -yarnVersion=1.21.1+build.3 -fabric_loader_version=0.16.14 +minecraft_version=1.21.10 +yarnVersion=1.21.10+build.3 +fabric_loader_version=0.18.4 #Fabric api -fabric_api_version=0.115.6 +fabric_api_version=0.138.4 # Dependencies -neoforge_version=21.1.170 +neoforge_version=21.10.64 diff --git a/neoforge/build.gradle b/neoforge/build.gradle index befa965..818a320 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -25,6 +25,7 @@ configurations { } repositories { + mavenCentral() maven { name = 'NeoForged' url = 'https://maven.neoforged.net/releases' @@ -38,7 +39,10 @@ repositories { dependencies { neoForge "net.neoforged:neoforge:$rootProject.neoforge_version" - modImplementation include("eu.pb4:sgui:1.9.1+1.21.1-neoforge") + modImplementation include("eu.pb4:sgui:1.9.1+1.21.10-neoforge") + + // SQLite JDBC for dev runtime (normally provided by minecraft-sqlite-jdbc mod) + implementation 'org.xerial:sqlite-jdbc:3.47.0.0' common(project(path: ':common', configuration: 'namedElements')) { transitive false } shadowBundle project(path: ':common', configuration: 'transformProductionNeoForge') diff --git a/neoforge/libs/sgui-1.9.1+1.21.10-neoforge.jar b/neoforge/libs/sgui-1.9.1+1.21.10-neoforge.jar new file mode 100644 index 0000000..908dfc1 Binary files /dev/null and b/neoforge/libs/sgui-1.9.1+1.21.10-neoforge.jar differ diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index 15e9e1a..b6ce10b 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -17,13 +17,13 @@ logoFile="icon.png" [[dependencies.auctionhouse]] modId="neoforge" type="required" - versionRange="[21.1.1,)" + versionRange="[21.10,)" ordering="NONE" side="BOTH" [[dependencies.auctionhouse]] modId="minecraft" type="required" - versionRange="[1.21.1,1.21.3)" + versionRange="[1.21.10,1.21.11)" ordering="NONE" side="BOTH" diff --git a/output/auctionhouse-1.2.3+1.21.1-fabric.jar b/output/auctionhouse-1.2.3+1.21.1-fabric.jar deleted file mode 100644 index 7ee7ba7..0000000 Binary files a/output/auctionhouse-1.2.3+1.21.1-fabric.jar and /dev/null differ diff --git a/output/auctionhouse-1.2.3+1.21.1-neoforge.jar b/output/auctionhouse-1.2.3+1.21.1-neoforge.jar deleted file mode 100644 index 3394ec1..0000000 Binary files a/output/auctionhouse-1.2.3+1.21.1-neoforge.jar and /dev/null differ diff --git a/output/auctionhouse-1.2.0+1.21.1-fabric.jar b/output/auctionhouse-1.2.4+1.21.10-fabric.jar similarity index 59% rename from output/auctionhouse-1.2.0+1.21.1-fabric.jar rename to output/auctionhouse-1.2.4+1.21.10-fabric.jar index 2113c31..e254559 100644 Binary files a/output/auctionhouse-1.2.0+1.21.1-fabric.jar and b/output/auctionhouse-1.2.4+1.21.10-fabric.jar differ diff --git a/output/auctionhouse-1.2.0+1.21.1-neoforge.jar b/output/auctionhouse-1.2.4+1.21.10-neoforge.jar similarity index 61% rename from output/auctionhouse-1.2.0+1.21.1-neoforge.jar rename to output/auctionhouse-1.2.4+1.21.10-neoforge.jar index e76bf50..0f8fb74 100644 Binary files a/output/auctionhouse-1.2.0+1.21.1-neoforge.jar and b/output/auctionhouse-1.2.4+1.21.10-neoforge.jar differ