diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..2b96ddb
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,224 @@
+# Contributing
+
+When contributing to this repository, please first discuss the change you wish to make via
+[GitHub issues](https://github.com/refinedmods/refinedstorage-trinkets-integration/issues), [Discord](https://discordapp.com/invite/VYzsydb),
+or any other method with the owners of this repository before making a change.
+
+## Quickstart
+
+These are the most important things to know before contributing (also explained in more detail later in this document):
+
+- Commit messages must adhere to [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
+- Branch names must be formatted correctly. The format is `{category}/GH-{issue number}/{lowercase-description}`.
+ Category must match a
+ category [used in our Commitlint config](https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional#type-enum).
+- We use [Checkstyle](https://checkstyle.sourceforge.io/) in our build workflow to validate coding style. It is
+ recommended to import the [config/checkstyle/checkstyle.xml](../config/checkstyle/checkstyle.xml)
+ or [config/intellij-code-style.xml](../config/intellij-code-style.xml) file into your
+ IDE, so that formatting rules are respected.
+- Branches are kept up to date by rebasing, not by merging.
+- For non-technical changes, adding a changelog entry is required.
+
+## Pull requests
+
+- Keep your pull request (PR) as small as possible, this makes reviewing easier.
+- Commits serve a clear purpose and have a fitting commit message.
+- Branches are kept up to date by rebasing (updating a branch by merging makes for a confusing Git history).
+- PRs are merged by merging the commits on top of the target branch (which is `develop`).
+- Remember to add your changes in `CHANGELOG.md`. If your changes are merely technical, it's not necessary to update the
+ changelog as it's not relevant for users.
+
+### Commit messages
+
+Commit messages must adhere to [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). We
+use [Commitlint](https://commitlint.js.org/) to validate commit messages.
+
+We use
+the [conventional configuration](https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional)
+for Commitlint.
+
+It is recommended to install
+the [Conventional Commit plugin](https://plugins.jetbrains.com/plugin/13389-conventional-commit) to make it
+easier to write commit messages.
+
+### Branch names
+
+Because we use merge commits when merging a PR, branch names will be part of the history of the repository. That is why
+branch names must follow a certain standard.
+
+The format is `{category}/GH-{issue number}/{lowercase-description}` and a branch name can be maximum 50 characters of
+length.
+
+Category must match a
+category [used in our Commitlint config](https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional#type-enum).
+
+Valid examples are:
+
+- `fix/GH-123/add-branch-linting`
+- `docs/GH-123/cleanup`
+
+## Versioning
+
+This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## Changelog
+
+The changelog is kept in `CHANGELOG.md`.
+
+Keeping a readable, relevant and user-friendly changelog is essential for our end users
+to stay up to date with the project.
+
+Please refrain from using technical terminology or adding entries for technical changes
+that are (generally) not relevant to the end-user.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
+
+## Gitflow
+
+This project uses [Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow).
+
+## Documentation
+
+Documentation must be kept up to date when adding or changing functionality.
+
+### API annotations
+
+Public APIs must be annotated with an `@API` annotation
+from [API Guardian](https://github.com/apiguardian-team/apiguardian).
+
+## Code style
+
+We use [Checkstyle](https://checkstyle.sourceforge.io/) in our build workflow to validate coding style.
+
+It is recommended to import the [config/checkstyle/checkstyle.xml](../config/checkstyle/checkstyle.xml)
+or [config/intellij-code-style.xml](../config/intellij-code-style.xml) file into your
+IDE, so that formatting rules are respected.
+
+Moreover, the [CheckStyle-IDEA plugin](https://plugins.jetbrains.com/plugin/1065-checkstyle-idea) can be used to check
+if there are no style violations.
+
+## Architecture
+
+## Testing
+
+When adding functionality or fixing a bug, it is important to add tests. Tests are important, if not more important,
+than the implementation code.
+
+That means that they need to be first class citizens in the codebase, and must be readable
+at all times.
+
+They ensure that there are no regressions, act as general documentation for the codebase,
+and ensure that the project can evolve over time.
+
+To avoid brittle tests, tests need to validate behavior. A test cannot rely on the internal code structure, so most
+mocking should be avoided.
+
+### Test coverage
+
+Our [SonarQube quality gate](https://sonarcloud.io/organizations/refinedmods/quality_gates/show/9) requires a minimum
+test coverage percentage of 80%.
+
+### Mutation testing
+
+We also use [Pitest](https://pitest.org/) mutation testing.
+
+Our build workflow requires a minimum test coverage percentage of 80% and a minimum mutation
+coverage percentage of 90%.
+
+## Release process
+
+The release process is automated and follows Gitflow.
+
+Before running the "Draft release" workflow to start the release process make sure `CHANGELOG.md` contains all the
+unreleased changes.
+
+To determine the version number to be released, the workflow will ask you which release type this is (major, minor,
+patch).
+The latest version from `CHANGELOG.md` will be used as a base, and that will be incremented
+depending on the release type.
+
+`CHANGELOG.md` will be updated by this workflow, you can review this in the resulting release PR.
+
+If you merge the release PR, the "Publish release" workflow will automatically publish the release. An additional PR
+will be created to merge the changes in `CHANGELOG.md` back into `develop`.
+
+## Hotfix process
+
+The hotfix process is semi-automated and follows Gitflow:
+
+- Create a hotfix branch off `main`.
+- Commit your changes on this branch.
+- Update `CHANGELOG.md` (with version number and release date) manually on this branch.
+- Push the branch and create a PR for it, merging into `main`.
+
+The "Publish release" workflow will take care of the rest.
+
+## Workflows
+
+We have a few GitHub workflows:
+
+- Build (PRs, pushes to `develop` and `main`)
+- Draft release (manual trigger)
+- Publish release (merging a PR to `main`)
+- Validate changelog (PRs)
+ - To validate if `CHANGELOG.md` is valid and updated.
+ - Not every pull request needs a changelog change, so the `skip-changelog` label can be added to the pull request to
+ ignore this.
+- Validate commit messages (PRs)
+ - Validates whether the commits on a pull request
+ respect [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
+ - We use
+ the [conventional configuration](https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional).
+- Validate branch names (PRs)
+- Issue for unsupported version (issues)
+ - Posts a message on a GitHub issue if the issue is about an unsupported version.
+- Lock resolved issues and PRs (every night)
+
+### Build
+
+The build workflow triggers when a pull request is updated or when a commit is pushed to `develop` or `main`.
+
+The build workflow takes care of the following:
+
+- Running a Gradle build, running our tests in the process and generating an aggregated code coverage report for the API
+ modules.
+- Analyzing the code on SonarQube.
+ > Because of
+ > [limitations with SonarQube](https://portal.productboard.com/sonarsource/1-sonarcloud/c/50-sonarcloud-analyzes-external-pull-request),
+ > pull requests originating from a fork aren't analyzed on SonarQube.
+
+- Code style validation with Checkstyle.
+- Mutation and line coverage test with Pitest.
+- Uploading the artifacts on the action.
+
+### Draft release
+
+The draft release workflow is a manual workflow which will create a release branch from `develop`.
+
+To determine the version number to be released, it will extract the latest version number from `CHANGELOG.md` and
+increment it depending on the release type selected.
+
+This workflow takes care of the following:
+
+- Creating the release branch.
+- Updating the changelog on this release branch.
+- Creating a pull request merging the release branch into `main`.
+
+### Publish release
+
+The "publish release" workflow is triggered when a release or hotfix PR is merged to `main`. Usually, this will be the
+PR created earlier in the "Draft release" workflow.
+
+The workflow takes care of the following:
+
+- Extracting the version number from the release or hotfix branch name that is merged in the PR.
+- Extracting the changelog entry for this version number.
+- Running a build.
+- Publishing on [GitHub packages](https://github.com/refinedmods/refinedstorage-trinkets-integration/packages) and
+ CreeperHost Maven.
+- Publishing Javadoc
+ on [GitHub pages](https://github.com/refinedmods/refinedstorage-trinkets-integration/tree/gh-pages).
+- Deploying on [GitHub releases](https://github.com/refinedmods/refinedstorage-trinkets-integration/releases).
+- Announcing the release on Discord and Twitter.
+- Creating a PR that merges `main` back into `develop` to get the changes to `CHANGELOG.md` and `build.gradle`
+ into `develop` from the draft release workflow.
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..bc4961c
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+patreon: raoulvdberge
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
new file mode 100644
index 0000000..60e28f8
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -0,0 +1,59 @@
+name: Bug report
+description: Found a bug or encountered a crash? Please report it here.
+labels: [ bug ]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Provide a summary of the issue in the title above.
+ - type: textarea
+ id: description
+ attributes:
+ label: Describe the bug
+ description: |
+ Be as detailed as possible.
+ If applicable, also tell us what you expected to happen instead.
+ validations:
+ required: true
+ - type: textarea
+ id: reproduce
+ attributes:
+ label: How can we reproduce this bug or crash?
+ description: |
+ Provide us with steps on how to reproduce this issue.
+ placeholder: |
+ 1.
+ 2.
+ 3.
+ validations:
+ required: true
+ - type: dropdown
+ id: minecraft
+ attributes:
+ label: What Minecraft version is this happening on?
+ description: |
+ If your Minecraft version isn't listed here, it means that it's no longer supported. In that case, don't create an issue.
+ options:
+ - Minecraft 1.20.4
+ validations:
+ required: true
+ - type: input
+ id: modloader-version
+ attributes:
+ label: What NeoForge or Fabric version is this happening on?
+ validations:
+ required: true
+ - type: input
+ id: version
+ attributes:
+ label: What version is this happening on?
+ description: |
+ Ensure that you are using the latest version.
+ validations:
+ required: true
+ - type: textarea
+ id: logs
+ attributes:
+ label: Relevant log output
+ description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
+ render: shell
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..9e5add6
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,5 @@
+blank_issues_enabled: true
+contact_links:
+ - name: Discord Community Support
+ url: https://discordapp.com/invite/VYzsydb
+ about: Please ask and answer questions here. Issues should be used for bugs and feature requests.
diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml
new file mode 100644
index 0000000..5509c3a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/enhancement.yml
@@ -0,0 +1,23 @@
+name: Enhancement
+description: Do you have a suggestion for a new feature or improvement? Let us know.
+labels: [ enhancement ]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Provide a summary of the enhancement in the title above.
+
+ Please follow following guidelines before proposing an enchancement:
+ 1) Ensure that you are running on the latest version (to ensure that the enhancement does not exist yet).
+ 2) Ensure that your enhancement hasn't already been posted. Please look in the closed issues as well (for enhancements that have been denied).
+
+ We might close your issue, without explanation, if you do not follow these guidelines.
+ - type: textarea
+ id: describe
+ attributes:
+ label: Describe your enhancement
+ description: |
+ Be as detailed as possible.
+ Tell us how your idea should work. Why should we consider this?
+ validations:
+ required: true
diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md
new file mode 100644
index 0000000..da1d2f6
--- /dev/null
+++ b/.github/SUPPORT.md
@@ -0,0 +1,12 @@
+# Support
+
+If you have a problem and need help, we offer various channels where you can ask for help.
+
+## I have a question
+
+Questions can be asked on [Discord](https://discordapp.com/invite/VYzsydb).
+
+## I have found a bug
+
+If you have found a bug, please report it
+on [GitHub issues](https://github.com/refinedmods/refinedstorage-trinkets-integration/issues).
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..b2a7493
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,14 @@
+name: Build
+on:
+ push:
+ branches:
+ - develop
+ - main
+ pull_request:
+ types: [ opened, synchronize, reopened ]
+jobs:
+ build:
+ uses: refinedmods/refinedarchitect/.github/workflows/build.yml@v0.13.4
+ with:
+ mutation-testing: false
+ secrets: inherit
diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml
new file mode 100644
index 0000000..5ea1d94
--- /dev/null
+++ b/.github/workflows/draft-release.yml
@@ -0,0 +1,24 @@
+name: Draft release
+on:
+ workflow_dispatch:
+ inputs:
+ release-type:
+ description: 'Release type'
+ required: true
+ default: 'minor'
+ type: choice
+ options:
+ - major
+ - minor
+ - patch
+ version-number-override:
+ description: 'Version number override'
+ required: false
+ type: string
+jobs:
+ draft:
+ uses: refinedmods/refinedarchitect/.github/workflows/draft-release.yml@v0.13.4
+ with:
+ release-type: ${{ inputs.release-type }}
+ version-number-override: ${{ inputs.version-number-override }}
+ secrets: inherit
diff --git a/.github/workflows/issue-for-unsupported-version.yml b/.github/workflows/issue-for-unsupported-version.yml
new file mode 100644
index 0000000..9f9ee90
--- /dev/null
+++ b/.github/workflows/issue-for-unsupported-version.yml
@@ -0,0 +1,7 @@
+name: Issue for unsupported version
+on:
+ issues:
+ types: [ labeled, unlabeled, reopened ]
+jobs:
+ unsupported-labeler:
+ uses: refinedmods/refinedarchitect/.github/workflows/issue-for-unsupported-version.yml@v0.13.4
\ No newline at end of file
diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml
new file mode 100644
index 0000000..4c45347
--- /dev/null
+++ b/.github/workflows/publish-release.yml
@@ -0,0 +1,15 @@
+name: Publish release
+on:
+ pull_request:
+ branches:
+ - main
+ types:
+ - closed
+jobs:
+ publish-release:
+ uses: refinedmods/refinedarchitect/.github/workflows/publish-release.yml@v0.13.4
+ secrets: inherit
+ with:
+ project-name: 'Refined Storage - Trinkets Integration'
+ mutation-testing: false
+ javadoc: false
\ No newline at end of file
diff --git a/.github/workflows/resolved-issue-locking.yml b/.github/workflows/resolved-issue-locking.yml
new file mode 100644
index 0000000..16b1cf9
--- /dev/null
+++ b/.github/workflows/resolved-issue-locking.yml
@@ -0,0 +1,7 @@
+name: Lock resolved issues and PRs
+on:
+ schedule:
+ - cron: '0 0 * * *'
+jobs:
+ lock:
+ uses: refinedmods/refinedarchitect/.github/workflows/resolved-issue-locking.yml@v0.13.4
\ No newline at end of file
diff --git a/.github/workflows/validate-branch-name.yml b/.github/workflows/validate-branch-name.yml
new file mode 100644
index 0000000..b2ddb77
--- /dev/null
+++ b/.github/workflows/validate-branch-name.yml
@@ -0,0 +1,5 @@
+name: Validate branch name
+on: [ pull_request ]
+jobs:
+ validate-branch-name:
+ uses: refinedmods/refinedarchitect/.github/workflows/validate-branch-name.yml@v0.13.4
\ No newline at end of file
diff --git a/.github/workflows/validate-changelog.yml b/.github/workflows/validate-changelog.yml
new file mode 100644
index 0000000..2adc54f
--- /dev/null
+++ b/.github/workflows/validate-changelog.yml
@@ -0,0 +1,7 @@
+name: Validate changelog
+on:
+ pull_request:
+ types: [ opened, synchronize, reopened, ready_for_review, labeled, unlabeled ]
+jobs:
+ validate-changelog:
+ uses: refinedmods/refinedarchitect/.github/workflows/validate-changelog.yml@v0.13.4
\ No newline at end of file
diff --git a/.github/workflows/validate-commit-messages.yml b/.github/workflows/validate-commit-messages.yml
new file mode 100644
index 0000000..8ef06cd
--- /dev/null
+++ b/.github/workflows/validate-commit-messages.yml
@@ -0,0 +1,5 @@
+name: Validate commit messages
+on: [ pull_request ]
+jobs:
+ validate-commit-messages:
+ uses: refinedmods/refinedarchitect/.github/workflows/validate-commit-messages.yml@v0.13.4
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8c2b9ee
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,18 @@
+.gradle/
+.nb-gradle/
+.settings/
+build/
+eclipse/
+.classpath
+.nb-gradle-properties
+.project
+*.launch
+*.iml
+*.ipr
+*.iws
+.idea/
+out/
+/bin/
+logs/
+.cache/
+run/
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..d96e506
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,12 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
+to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+### Added
+
+- Initial release.
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..e9057d6
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,20 @@
+# The MIT License (MIT)
+
+Copyright © 2024 Refined Mods
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the “Software”), to deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f3bd3e2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,32 @@
+# Refined Storage - Trinkets Integration [![Build Status](https://github.com/refinedmods/refinedstorage-trinkets-integration/actions/workflows/build.yml/badge.svg?branch=develop)](https://github.com/refinedmods/refinedstorage-trinkets-integration/actions/workflows/build.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=refinedmods_refinedstorage-trinkets-integration&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=refinedmods_refinedstorage-trinkets-integration) [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=refinedmods_refinedstorage-trinkets-integration&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=refinedmods_refinedstorage-trinkets-integration) [![Discord](https://img.shields.io/discord/342942776494653441)](https://discordapp.com/invite/VYzsydb) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE.md)
+
+## About
+
+[Trinkets](https://github.com/emilyploszaj/trinkets) integration for [Refined Storage](https://github.com/refinedmods/refinedstorage2).
+
+## Links
+
+- [GitHub](https://github.com/refinedmods/refinedstorage-trinkets-integration)
+ - [Releases](https://github.com/refinedmods/refinedstorage-trinkets-integration/releases)
+ - [Packages](https://github.com/refinedmods/refinedstorage-trinkets-integration/packages)
+ - [Issues](https://github.com/refinedmods/refinedstorage-trinkets-integration/issues)
+ - [Refined Mods on GitHub](https://github.com/refinedmods)
+- [Discord](https://discordapp.com/invite/VYzsydb)
+- [Twitter](https://twitter.com/refinedmods)
+- [Mastodon](https://anvil.social/@refinedmods)
+
+## Building
+
+Clone the repository and import the Gradle project.
+
+## Contributing
+
+See [CONTRIBUTING.md](.github/CONTRIBUTING.md).
+
+## Support
+
+See [SUPPORT.md](.github/SUPPORT.md).
+
+## Changelog
+
+See [CHANGELOG.md](CHANGELOG.md).
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..d2685d3
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,48 @@
+plugins {
+ id 'java-library'
+}
+
+apply from: "https://raw.githubusercontent.com/refinedmods/refinedarchitect/v0.13.4/helper.gradle"
+
+group = 'com.refinedmods.refinedstorage'
+
+fabricProject("refinedstorage_trinkets_integration")
+
+archivesBaseName = 'refinedstorage-trinkets-integration'
+
+repositories {
+ maven {
+ url = uri("https://maven.pkg.github.com/refinedmods/refinedstorage2")
+ credentials {
+ username = "anything"
+ password = "\u0067hp_oGjcDFCn8jeTzIj4Ke9pLoEVtpnZMP4VQgaX"
+ }
+ }
+ maven {
+ name = 'ModMenu'
+ url 'https://maven.terraformersmc.com/'
+ }
+ maven {
+ name = 'Cloth Config'
+ url 'https://maven.shedaniel.me/'
+ }
+ maven {
+ name = 'NoIndium'
+ url = 'https://maven.cafeteria.dev/releases/'
+ }
+ maven {
+ name = "Trinkets"
+ url = 'https://maven.ladysnake.org/releases'
+ }
+}
+
+dependencies {
+ modApi "com.refinedmods.refinedstorage2:refinedstorage2-platform-fabric:${refinedstorageVersion}"
+ // https://www.curseforge.com/minecraft/mc-mods/trinkets/files
+ modApi "dev.emi:trinkets:${trinketsVersion}"
+ modApi "dev.onyxstudios.cardinal-components-api:cardinal-components-base:${cardinalComponentsVersion}"
+ modApi "dev.onyxstudios.cardinal-components-api:cardinal-components-entity:${cardinalComponentsVersion}"
+}
+
+enablePublishing()
+enableSonarQube("refinedmods_refinedstorage-trinkets-integration")
diff --git a/config/checkstyle/checkstyle-imports.xml b/config/checkstyle/checkstyle-imports.xml
new file mode 100644
index 0000000..6788c49
--- /dev/null
+++ b/config/checkstyle/checkstyle-imports.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/config/checkstyle/checkstyle-suppressions.xml b/config/checkstyle/checkstyle-suppressions.xml
new file mode 100644
index 0000000..a39ac62
--- /dev/null
+++ b/config/checkstyle/checkstyle-suppressions.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
new file mode 100644
index 0000000..87191bb
--- /dev/null
+++ b/config/checkstyle/checkstyle.xml
@@ -0,0 +1,275 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/config/intellij-code-style.xml b/config/intellij-code-style.xml
new file mode 100644
index 0000000..be27458
--- /dev/null
+++ b/config/intellij-code-style.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crowdin.yml b/crowdin.yml
new file mode 100644
index 0000000..e691859
--- /dev/null
+++ b/crowdin.yml
@@ -0,0 +1,128 @@
+project_identifier: refined-storage-trinkets-integration
+commit_message: "chore: update translation %language% from crowdin"
+append_commit_message: false
+api_key_env: CROWDIN_API_KEY
+base_path: .
+pull_request_labels:
+ - skip-changelog
+files:
+ - source: /src/main/resources/assets/refinedstorage_trinkets_integration/lang/en_us.json
+ translation: /src/main/resources/assets/refinedstorage_trinkets_integration/lang/%locale_with_underscore%.json
+ languages_mapping:
+ locale_with_underscore:
+ af: af_za
+ ar: ar_sa
+ ast: ast_es
+ az: az_az
+ ba: ba_ru
+ be: be_by
+ bg: bg_bg
+ br-FR: br_fr
+ bs: bs_ba
+ ca: ca_es
+ cs: cs_cz
+ cy: cy_gb
+ da: da_dk
+ de-AT: de_at
+ de-CH: de_ch
+ de: de_de
+ el: el_gr
+ en-AU: en_au
+ en-CA: en_ca
+ en-GB: en_gb
+ en-NZ: en_nz
+ en-PT: en_pt
+ en-US: en_us
+ en-ZA: en_za
+ eo: eo_uy
+ es-AR: es_ar
+ es-CL: es_cl
+ es-ES: es_es
+ es-MX: es_mx
+ es-UY: es_uy
+ es-VE: es_ve
+ et: et_ee
+ eu: eu_es
+ fa: fa_ir
+ fi: fi_fi
+ fil: fil_ph
+ fo: fo_fo
+ fr-CA: fr_ca
+ fr: fr_fr
+ fra-DE: fra_de
+ fy-NL: fy_nl
+ ga-IE: ga_ie
+ gd: gd_gb
+ gl: gl_es
+ got: got_de
+ gv: gv_im
+ haw: haw_us
+ he: he_il
+ hi: hi_in
+ hr: hr_hr
+ hu: hu_hu
+ hy-AM: hy_am
+ id: id_id
+ ig: ig_ng
+ ido: io_en
+ is: is_is
+ it: it_it
+ ja: ja_jp
+ jbo: jbo_en
+ ka: ka_ge
+ kab: kab_kab
+ kk: kk_kz
+ kn: kn_in
+ ko: ko_kr
+ kw: kw_gb
+ la-LA: la_va
+ lb: lb_lu
+ li: li_li
+ lol: lol_us
+ lt: lt_lt
+ lv: lv_lv
+ mi: mi_nz
+ mk: mk_mk
+ mn: mn_mn
+ moh: moh_ca
+ ms: ms_my
+ mt: mt_mt
+ nb: nb_no
+ nds: nds_de
+ nl-BE: nl_be
+ nl: nl_nl
+ nn-NO: nn_no
+ #no: nn_no
+ oc: oc_fr
+ oj: oj_ca
+ pl: pl_pl
+ pt-BR: pt_br
+ pt-PT: pt_pt
+ qya-AA: qya_aa
+ ro: ro_ro
+ ru: ru_ru
+ sk: sk_sk
+ sl: sl_si
+ so: so_so
+ sq: sq_al
+ sr: sr_sp
+ sr-CS: sr_cs
+ sv-SE: sv_se
+ ta: ta_in
+ th: th_th
+ tl: tl_ph
+ tlh-AA: tlh_aa
+ tr: tr_tr
+ tt-RU: tt_ru
+ tzl: tzl_tzl
+ uk: uk_ua
+ val-ES: val_es
+ vec: vec_it
+ vi: vi_vn
+ yi: yi_de
+ yo: yo_ng
+ zh-CN: zh_cn
+ zh-TW: zh_tw
+ zh-HK: zh_hk
+ fur-IT: fur_it
+ ry: ry_ua
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..d45f2aa
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,5 @@
+refinedstorageVersion=2.0.0-milestone.3.13
+trinketsVersion=3.8.0
+cardinalComponentsVersion=5.4.0
+# Gradle
+org.gradle.jvmargs=-Xmx1G
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..249e583
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..b82aa23
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..a69d9cb
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,240 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f127cfd
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,91 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsRefinedStoragePlugin.java b/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsRefinedStoragePlugin.java
new file mode 100644
index 0000000..d0c759a
--- /dev/null
+++ b/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsRefinedStoragePlugin.java
@@ -0,0 +1,27 @@
+package com.refinedmods.refinedstorage.trinkets;
+
+import com.refinedmods.refinedstorage2.platform.api.PlatformApi;
+import com.refinedmods.refinedstorage2.platform.api.RefinedStoragePlugin;
+import com.refinedmods.refinedstorage2.platform.common.util.IdentifierUtil;
+import net.minecraft.resources.ResourceLocation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TrinketsRefinedStoragePlugin implements RefinedStoragePlugin {
+ public static final String ID = "refinedstorage_trinkets_integration";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(TrinketsRefinedStoragePlugin.class);
+
+ @Override
+ public void onPlatformApiAvailable(final PlatformApi platformApi) {
+ PlatformApi.INSTANCE.getSlotReferenceFactoryRegistry().register(
+ new ResourceLocation(ID, "trinkets"),
+ TrinketsSlotReferenceFactory.INSTANCE
+ );
+ PlatformApi.INSTANCE.addSlotReferenceProvider(new TrinketsSlotReferenceProvider());
+ LOGGER.info(
+ "Refined Storage - Trinkets Integration has loaded. RS2 ModId: {}",
+ IdentifierUtil.MOD_ID
+ );
+ }
+}
diff --git a/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsSlotReference.java b/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsSlotReference.java
new file mode 100644
index 0000000..485a10c
--- /dev/null
+++ b/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsSlotReference.java
@@ -0,0 +1,47 @@
+package com.refinedmods.refinedstorage.trinkets;
+
+import java.util.Optional;
+
+import com.refinedmods.refinedstorage2.platform.api.support.network.bounditem.SlotReference;
+import com.refinedmods.refinedstorage2.platform.api.support.network.bounditem.SlotReferenceFactory;
+import dev.emi.trinkets.api.TrinketsApi;
+import net.minecraft.network.FriendlyByteBuf;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.item.ItemStack;
+
+class TrinketsSlotReference implements SlotReference {
+ private final String groupName;
+ private final String slotName;
+ private final int index;
+
+ TrinketsSlotReference(final String groupName, final String slotName, final int index) {
+ this.groupName = groupName;
+ this.slotName = slotName;
+ this.index = index;
+ }
+
+ @Override
+ public boolean isDisabledSlot(final int playerSlotIndex) {
+ return false;
+ }
+
+ @Override
+ public void writeToBuffer(final FriendlyByteBuf buf) {
+ buf.writeUtf(groupName);
+ buf.writeUtf(slotName);
+ buf.writeInt(index);
+ }
+
+ @Override
+ public Optional resolve(final Player player) {
+ return TrinketsApi.getTrinketComponent(player)
+ .map(trinkets -> trinkets.getInventory().get(groupName))
+ .map(groupMap -> groupMap.get(slotName))
+ .map(trinketInventory -> trinketInventory.getItem(index));
+ }
+
+ @Override
+ public SlotReferenceFactory getFactory() {
+ return TrinketsSlotReferenceFactory.INSTANCE;
+ }
+}
diff --git a/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsSlotReferenceFactory.java b/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsSlotReferenceFactory.java
new file mode 100644
index 0000000..99f7e41
--- /dev/null
+++ b/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsSlotReferenceFactory.java
@@ -0,0 +1,17 @@
+package com.refinedmods.refinedstorage.trinkets;
+
+import com.refinedmods.refinedstorage2.platform.api.support.network.bounditem.SlotReference;
+import com.refinedmods.refinedstorage2.platform.api.support.network.bounditem.SlotReferenceFactory;
+import net.minecraft.network.FriendlyByteBuf;
+
+class TrinketsSlotReferenceFactory implements SlotReferenceFactory {
+ public static final SlotReferenceFactory INSTANCE = new TrinketsSlotReferenceFactory();
+
+ private TrinketsSlotReferenceFactory() {
+ }
+
+ @Override
+ public SlotReference create(final FriendlyByteBuf buf) {
+ return new TrinketsSlotReference(buf.readUtf(), buf.readUtf(), buf.readInt());
+ }
+}
diff --git a/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsSlotReferenceProvider.java b/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsSlotReferenceProvider.java
new file mode 100644
index 0000000..d7e688d
--- /dev/null
+++ b/src/main/java/com/refinedmods/refinedstorage/trinkets/TrinketsSlotReferenceProvider.java
@@ -0,0 +1,29 @@
+package com.refinedmods.refinedstorage.trinkets;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import com.refinedmods.refinedstorage2.platform.api.support.network.bounditem.SlotReference;
+import com.refinedmods.refinedstorage2.platform.api.support.network.bounditem.SlotReferenceProvider;
+import dev.emi.trinkets.api.TrinketsApi;
+import net.minecraft.util.Tuple;
+import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.item.Item;
+
+class TrinketsSlotReferenceProvider implements SlotReferenceProvider {
+ @Override
+ public List find(final Player player, final Set- validItems) {
+ return TrinketsApi.getTrinketComponent(player)
+ .map(trinkets -> trinkets.getEquipped(s -> validItems.contains(s.getItem())))
+ .orElse(Collections.emptyList())
+ .stream()
+ .map(Tuple::getA)
+ .map(trinketsSlotReference -> (SlotReference) new TrinketsSlotReference(
+ trinketsSlotReference.inventory().getSlotType().getGroup(),
+ trinketsSlotReference.inventory().getSlotType().getName(),
+ trinketsSlotReference.index()
+ ))
+ .toList();
+ }
+}
diff --git a/src/main/java/com/refinedmods/refinedstorage/trinkets/package-info.java b/src/main/java/com/refinedmods/refinedstorage/trinkets/package-info.java
new file mode 100644
index 0000000..8769f4d
--- /dev/null
+++ b/src/main/java/com/refinedmods/refinedstorage/trinkets/package-info.java
@@ -0,0 +1,7 @@
+@ParametersAreNonnullByDefault
+@FieldsAndMethodsAreNonnullByDefault
+package com.refinedmods.refinedstorage.trinkets;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
+import com.refinedmods.refinedstorage2.api.core.FieldsAndMethodsAreNonnullByDefault;
diff --git a/src/main/resources/assets/refinedstorage_trinkets_integration/lang/en_us.json b/src/main/resources/assets/refinedstorage_trinkets_integration/lang/en_us.json
new file mode 100644
index 0000000..8b59198
--- /dev/null
+++ b/src/main/resources/assets/refinedstorage_trinkets_integration/lang/en_us.json
@@ -0,0 +1,3 @@
+{
+ "trinkets.slot.refinedstorage_trinkets_integration.wireless": "Refined Storage"
+}
\ No newline at end of file
diff --git a/src/main/resources/assets/refinedstorage_trinkets_integration/textures/slot/trinkets.png b/src/main/resources/assets/refinedstorage_trinkets_integration/textures/slot/trinkets.png
new file mode 100644
index 0000000..2d0f73a
Binary files /dev/null and b/src/main/resources/assets/refinedstorage_trinkets_integration/textures/slot/trinkets.png differ
diff --git a/src/main/resources/data/trinkets/entities/refinedstorage_trinkets_integration.json b/src/main/resources/data/trinkets/entities/refinedstorage_trinkets_integration.json
new file mode 100644
index 0000000..500b43e
--- /dev/null
+++ b/src/main/resources/data/trinkets/entities/refinedstorage_trinkets_integration.json
@@ -0,0 +1,8 @@
+{
+ "entities": [
+ "player"
+ ],
+ "slots": [
+ "refinedstorage_trinkets_integration/wireless"
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/data/trinkets/slots/refinedstorage_trinkets_integration/wireless.json b/src/main/resources/data/trinkets/slots/refinedstorage_trinkets_integration/wireless.json
new file mode 100644
index 0000000..2c48b38
--- /dev/null
+++ b/src/main/resources/data/trinkets/slots/refinedstorage_trinkets_integration/wireless.json
@@ -0,0 +1,5 @@
+{
+ "order": 5,
+ "amount": 2,
+ "icon": "refinedstorage_trinkets_integration:slot/trinkets"
+}
\ No newline at end of file
diff --git a/src/main/resources/data/trinkets/tags/items/refinedstorage_trinkets_integration/wireless.json b/src/main/resources/data/trinkets/tags/items/refinedstorage_trinkets_integration/wireless.json
new file mode 100644
index 0000000..778353b
--- /dev/null
+++ b/src/main/resources/data/trinkets/tags/items/refinedstorage_trinkets_integration/wireless.json
@@ -0,0 +1,7 @@
+{
+ "replace": false,
+ "values": [
+ "refinedstorage2:wireless_grid",
+ "refinedstorage2:creative_wireless_grid"
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json
new file mode 100644
index 0000000..46d8953
--- /dev/null
+++ b/src/main/resources/fabric.mod.json
@@ -0,0 +1,37 @@
+{
+ "schemaVersion": 1,
+ "id": "refinedstorage_trinkets_integration",
+ "version": "${version}",
+ "name": "Refined Storage - Trinkets Integration",
+ "description": "Trinkets integration for Refined Storage.",
+ "authors": [
+ "Refined Mods"
+ ],
+ "contact": {
+ "sources": "https://github.com/refinedmods/refinedstorage-trinkets-integration",
+ "issues": "https://github.com/refinedmods/refinedstorage-trinkets-integration/issues"
+ },
+ "license": "MIT",
+ "environment": "*",
+ "entrypoints": {
+ "refinedstorage_plugin": [
+ "com.refinedmods.refinedstorage.trinkets.TrinketsRefinedStoragePlugin"
+ ]
+ },
+ "custom": {
+ "modmenu": {
+ "links": {
+ "modmenu.discord": "https://discordapp.com/invite/VYzsydb"
+ },
+ "parent": "refinedstorage2"
+ }
+ },
+ "depends": {
+ "fabricloader": ">=0.14.6",
+ "fabric-api": "*",
+ "minecraft": "~1.20.4",
+ "refinedstorage2": "*",
+ "trinkets": ">=3.8",
+ "java": ">=17"
+ }
+}
diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta
new file mode 100644
index 0000000..834e02a
--- /dev/null
+++ b/src/main/resources/pack.mcmeta
@@ -0,0 +1,8 @@
+{
+ "pack": {
+ "description": {
+ "text": "Refined Storage - Trinkets Integration resources"
+ },
+ "pack_format": 18
+ }
+}