Migrate to new Hytale plugin template structure
Replaces the previous Kotlin-based Gradle build and template files with a new Java-based Gradle build system and updated example plugin code. Removes old build scripts, plugin template, and configuration, and introduces a new ExamplePlugin with updated manifest, command, and recipe example. Updates documentation and project configuration to match the new structure and usage.
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,2 +0,0 @@
|
|||||||
# Auto detect text files and perform LF normalization
|
|
||||||
* text=auto
|
|
||||||
30
.gitignore
vendored
30
.gitignore
vendored
@@ -1,15 +1,14 @@
|
|||||||
# Gradle
|
### Gradle ###
|
||||||
.gradle/
|
.gradle
|
||||||
build/
|
build/
|
||||||
!gradle/wrapper/gradle-wrapper.jar
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
!**/src/main/**/build/
|
!**/src/main/**/build/
|
||||||
!**/src/test/**/build/
|
!**/src/test/**/build/
|
||||||
.kotlin/
|
|
||||||
|
|
||||||
# Server testing directory
|
### Hytale ###
|
||||||
run/
|
run/
|
||||||
|
|
||||||
# IntelliJ IDEA
|
### IntelliJ IDEA ###
|
||||||
.idea/
|
.idea/
|
||||||
*.iws
|
*.iws
|
||||||
*.iml
|
*.iml
|
||||||
@@ -18,7 +17,7 @@ out/
|
|||||||
!**/src/main/**/out/
|
!**/src/main/**/out/
|
||||||
!**/src/test/**/out/
|
!**/src/test/**/out/
|
||||||
|
|
||||||
# Eclipse
|
### Eclipse ###
|
||||||
.apt_generated
|
.apt_generated
|
||||||
.classpath
|
.classpath
|
||||||
.factorypath
|
.factorypath
|
||||||
@@ -30,28 +29,15 @@ bin/
|
|||||||
!**/src/main/**/bin/
|
!**/src/main/**/bin/
|
||||||
!**/src/test/**/bin/
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
# NetBeans
|
### NetBeans ###
|
||||||
/nbproject/private/
|
/nbproject/private/
|
||||||
/nbbuild/
|
/nbbuild/
|
||||||
/dist/
|
/dist/
|
||||||
/nbdist/
|
/nbdist/
|
||||||
/.nb-gradle/
|
/.nb-gradle/
|
||||||
|
|
||||||
# VS Code
|
### VS Code ###
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
# Mac OS
|
### Mac OS ###
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
# Windows
|
|
||||||
Thumbs.db
|
|
||||||
desktop.ini
|
|
||||||
|
|
||||||
# Logs
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# Temporary files
|
|
||||||
*.tmp
|
|
||||||
*.bak
|
|
||||||
*.swp
|
|
||||||
*~
|
|
||||||
|
|||||||
21
LICENSE
21
LICENSE
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2026 Hytale Modding Community
|
|
||||||
|
|
||||||
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.
|
|
||||||
442
README.md
442
README.md
@@ -1,371 +1,99 @@
|
|||||||
# Hytale Plugin Template
|
# Hytale Example Plugin
|
||||||
|
|
||||||
A minimal, ready-to-use template for creating Hytale plugins with modern build tools and automated testing.
|
An example project that can build and run plugins for the game Hytale!
|
||||||
|
|
||||||
> **✨ Builds immediately without any changes!** Clone and run `./gradlew shadowJar` to get a working plugin JAR.
|
> **⚠️ Warning: Early Access**
|
||||||
|
> The game Hytale is in early access, and so is this project! Features may be
|
||||||
|
> incomplete, unstable, or change frequently. Please be patient and understanding as development
|
||||||
|
> continues.
|
||||||
|
|
||||||
## Features
|
## Introduction
|
||||||
|
This project contains a Gradle project that can be imported into IDEA and used
|
||||||
|
as the foundation for custom Hytale plugins. The template will add the Hytale
|
||||||
|
server to your classpath and create a run configuration that can be used to
|
||||||
|
run your plugin on the server. It can also be used to build a sharable JAR file
|
||||||
|
that contains your plugin.
|
||||||
|
|
||||||
✅ **Modern Build System** - Gradle with Kotlin DSL
|
## Requirements
|
||||||
✅ **Automated Testing** - Custom Gradle plugin for one-command server testing
|
Please ensure all the requirements are met before getting started.
|
||||||
✅ **Java 25** - Latest Java features
|
|
||||||
✅ **ShadowJar** - Automatic dependency bundling
|
|
||||||
✅ **CI/CD Ready** - GitHub Actions workflow included
|
|
||||||
✅ **Minimal Structure** - Only essential files, write your own code
|
|
||||||
|
|
||||||
---
|
1. Download Hytale using the official launcher.
|
||||||
|
2. Have Intellij IDEA installed. Community edition is fine.
|
||||||
|
3. Download Java 25 and set it as the SDK in IDEA.
|
||||||
|
|
||||||
## Quick Start
|
## Configuring Template
|
||||||
|
It is important to configure the project before using it as a template. Doing
|
||||||
|
this before importing the project will help avoid running into caching issues
|
||||||
|
later on.
|
||||||
|
|
||||||
### Prerequisites
|
### 1: Project Name
|
||||||
|
Set the name of the project in `settings.gradle`. This should be the name of
|
||||||
|
your plugin. We recommend capitalizing your project name and avoiding
|
||||||
|
whitespace and most special characters. This will be used as the base name for
|
||||||
|
any files produced by Gradle, like the sharable JAR file.
|
||||||
|
|
||||||
- **Java 25 JDK** - [Download here](https://www.oracle.com/java/technologies/downloads/)
|
### 2: Gradle Properties
|
||||||
- **IntelliJ IDEA** - [Download here](https://www.jetbrains.com/idea/download/) (Community Edition is fine)
|
Review the properties defined in `gradle.properties`. You should change the
|
||||||
- **Git** - [Download here](https://git-scm.com/)
|
`maven_group` to match your project. You should also change the `version`
|
||||||
|
property before making a new release, or set up CI/CD to automate it.
|
||||||
|
|
||||||
### 1. Clone or Download
|
### 3: Manifest
|
||||||
|
The manifest file provides important information about your plugin to Hytale.
|
||||||
|
You should update every property in this file to reflect your project. The
|
||||||
|
most important property to set is `Main` which tells the game which class
|
||||||
|
file to load as the entry point for your plugin. The file can be found at
|
||||||
|
`src/main/resources/manifest.json`.
|
||||||
|
|
||||||
```bash
|
**This template has configured Gradle to automatically update the `Version` and
|
||||||
git clone https://github.com/yourusername/hytale-plugin-template.git
|
`IncludesAssetPack` property to reflect your Gradle properties every time you
|
||||||
cd hytale-plugin-template
|
run the game in development, or build the plugin. This is a workaround to allow
|
||||||
|
the in-game asset editor to be used when working on your project.**
|
||||||
|
|
||||||
|
## Importing into IDEA
|
||||||
|
When opening the project in IDEA it should automatically create the
|
||||||
|
`HytaleServer` run configuration and a `./run` folder. When you run the game it
|
||||||
|
will generate all the relevant files in there. It will also load the default
|
||||||
|
assets from the games.
|
||||||
|
|
||||||
|
**If you do not see the `HytaleServer` run configuration, you may need to open
|
||||||
|
the dropdown or click `Edit Configurations...` once to unhide it.**
|
||||||
|
|
||||||
|
## Importing into VSCode
|
||||||
|
While VSCode is not officially supported, you can generate launch configs by
|
||||||
|
running `./gradlew generateVSCodeLaunch`.
|
||||||
|
|
||||||
|
## Connecting to Server
|
||||||
|
Once the server is running in IDEA you should be able to connect to
|
||||||
|
`Local Server` using your standard Hytale client. If the server does not show
|
||||||
|
up automatically, add the IP as `127.0.0.1` manually.
|
||||||
|
|
||||||
|
### You MUST authenticate your test server!
|
||||||
|
In order to connect to the test server, you must authenticate it with Hytale.
|
||||||
|
This is done by running the `auth login device` command in the server terminal.
|
||||||
|
This command will print a URL that you can use to authenticate the server using
|
||||||
|
your Hytale account. Once authenticated, you can run the
|
||||||
|
`auth persistence Encrypted` command to keep your server authenticated after
|
||||||
|
restarting it.
|
||||||
|
|
||||||
|
**Never share your encrypted auth file!**
|
||||||
|
|
||||||
|
If you are unable to run commands from the IDEA terminal, you can also run the
|
||||||
|
command from code like this. Make sure to remove the code after your server is
|
||||||
|
authenticated.
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Override
|
||||||
|
protected void start() {
|
||||||
|
CommandManager.get().handleCommand(ConsoleSender.INSTANCE, "auth login device");
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**The template builds immediately without any changes!**
|
|
||||||
You can customize it later when you're ready to develop your plugin.
|
|
||||||
|
|
||||||
### 2. Build Immediately (No Changes Needed!)
|
## Verifying The Example Plugin
|
||||||
|
You can verify the Example plugin has loaded by running the `/test` command
|
||||||
|
in game. It will print the name and version of your plugin. This is for
|
||||||
|
demonstration purposes, and should **NOT** be included in your final build.
|
||||||
|
|
||||||
The template works out-of-the-box:
|
The example plugin also includes a recipe defined by an asset pack. This recipe
|
||||||
|
allows you to craft 10 dirt into 1 dirt using the crafting window. This is also
|
||||||
```bash
|
an example and should not be removed before you release the plugin.
|
||||||
# Windows
|
|
||||||
gradlew.bat shadowJar
|
|
||||||
|
|
||||||
# Linux/Mac
|
|
||||||
./gradlew shadowJar
|
|
||||||
```
|
|
||||||
|
|
||||||
Your plugin JAR will be in: `build/libs/TemplatePlugin-1.0.0.jar`
|
|
||||||
|
|
||||||
### 3. Customize Your Plugin (Optional)
|
|
||||||
|
|
||||||
When ready to customize, edit these files:
|
|
||||||
|
|
||||||
**`settings.gradle.kts`:**
|
|
||||||
```kotlin
|
|
||||||
rootProject.name = "your-plugin-name"
|
|
||||||
```
|
|
||||||
|
|
||||||
**`gradle.properties`:**
|
|
||||||
```properties
|
|
||||||
pluginGroup=com.yourname
|
|
||||||
pluginVersion=1.0.0
|
|
||||||
pluginDescription=Your plugin description
|
|
||||||
```
|
|
||||||
|
|
||||||
**`src/main/resources/manifest.json`:**
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Group": "YourName",
|
|
||||||
"Name": "YourPluginName",
|
|
||||||
"Main": "com.yourname.yourplugin.YourPlugin"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Rename the main plugin class:**
|
|
||||||
- Rename `src/main/java/com/example/templateplugin/TemplatePlugin.java`
|
|
||||||
- Update package name to match your `pluginGroup`
|
|
||||||
|
|
||||||
### 4. Build Your Plugin
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Windows
|
|
||||||
gradlew.bat shadowJar
|
|
||||||
|
|
||||||
# Linux/Mac
|
|
||||||
./gradlew shadowJar
|
|
||||||
```
|
|
||||||
|
|
||||||
Your plugin JAR will be in: `build/libs/YourPluginName-1.0.0.jar`
|
|
||||||
|
|
||||||
### 5. Implement Your Plugin
|
|
||||||
|
|
||||||
Write your plugin code in `src/main/java/`:
|
|
||||||
- Commands
|
|
||||||
- Event listeners
|
|
||||||
- Services
|
|
||||||
- Storage
|
|
||||||
- Utilities
|
|
||||||
|
|
||||||
See our [documentation](../Documentation/) for examples and patterns.
|
|
||||||
|
|
||||||
### 6. Test Your Plugin (Automated!)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Windows
|
|
||||||
gradlew.bat runServer
|
|
||||||
|
|
||||||
# Linux/Mac
|
|
||||||
./gradlew runServer
|
|
||||||
```
|
|
||||||
|
|
||||||
This will:
|
|
||||||
1. Download the Hytale server (cached for future runs)
|
|
||||||
2. Build your plugin
|
|
||||||
3. Copy it to the server's plugins folder
|
|
||||||
4. Start the server with interactive console
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
TemplatePlugin/
|
|
||||||
├── .github/workflows/
|
|
||||||
│ └── build.yml # CI/CD workflow
|
|
||||||
├── buildSrc/
|
|
||||||
│ ├── build.gradle.kts # Custom plugin configuration
|
|
||||||
│ └── src/main/kotlin/
|
|
||||||
│ └── RunHytalePlugin.kt # Automated server testing
|
|
||||||
├── src/main/
|
|
||||||
│ ├── java/com/example/templateplugin/
|
|
||||||
│ │ └── TemplatePlugin.java # Minimal main class (example)
|
|
||||||
│ └── resources/
|
|
||||||
│ └── manifest.json # Plugin metadata
|
|
||||||
├── .gitignore # Git ignore rules
|
|
||||||
├── build.gradle.kts # Build configuration
|
|
||||||
├── gradle.properties # Project properties
|
|
||||||
├── settings.gradle.kts # Project settings
|
|
||||||
├── LICENSE # MIT License
|
|
||||||
└── README.md # This file
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note:** This is a minimal template. Create your own folder structure:
|
|
||||||
- `commands/` - For command implementations
|
|
||||||
- `listeners/` - For event listeners
|
|
||||||
- `services/` - For business logic
|
|
||||||
- `storage/` - For data persistence
|
|
||||||
- `utils/` - For utility classes
|
|
||||||
- `config/` - For configuration management
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Development Workflow
|
|
||||||
|
|
||||||
### Building
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Compile only
|
|
||||||
./gradlew compileJava
|
|
||||||
|
|
||||||
# Build plugin JAR
|
|
||||||
./gradlew shadowJar
|
|
||||||
|
|
||||||
# Clean and rebuild
|
|
||||||
./gradlew clean shadowJar
|
|
||||||
```
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run server with your plugin
|
|
||||||
./gradlew runServer
|
|
||||||
|
|
||||||
# Run unit tests
|
|
||||||
./gradlew test
|
|
||||||
|
|
||||||
# Clean test server
|
|
||||||
rm -rf run/
|
|
||||||
```
|
|
||||||
|
|
||||||
### Debugging
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Run server in debug mode
|
|
||||||
./gradlew runServer -Pdebug
|
|
||||||
|
|
||||||
# Then connect your IDE debugger to localhost:5005
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Customization
|
|
||||||
|
|
||||||
### Adding Dependencies
|
|
||||||
|
|
||||||
Edit `build.gradle.kts`:
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
dependencies {
|
|
||||||
// Hytale API (provided by server)
|
|
||||||
compileOnly(files("libs/hytale-server.jar"))
|
|
||||||
|
|
||||||
// Your dependencies (will be bundled)
|
|
||||||
implementation("com.google.code.gson:gson:2.10.1")
|
|
||||||
|
|
||||||
// Test dependencies
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configuring Server Testing
|
|
||||||
|
|
||||||
**Run Hytale Server** - A Gradle plugin to download and run a Hytale server for development and testing purposes. The server files will be located in the `run/` directory of the project. Before starting the server it will compile (shadowJar task) and copy the plugin jar to the server's `plugins/` folder.
|
|
||||||
|
|
||||||
**Usage:**
|
|
||||||
|
|
||||||
Edit `build.gradle.kts`:
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
runHytale {
|
|
||||||
jarUrl = "url to hytale server jar"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Run the server with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Windows
|
|
||||||
gradlew.bat runServer
|
|
||||||
|
|
||||||
# Linux/Mac
|
|
||||||
./gradlew runServer
|
|
||||||
```
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- ✅ Automatic server JAR download and caching
|
|
||||||
- ✅ Compiles and deploys your plugin automatically
|
|
||||||
- ✅ Starts server with interactive console
|
|
||||||
- ✅ One-command workflow: `./gradlew runServer`
|
|
||||||
- ✅ Server files in `run/` directory (gitignored)
|
|
||||||
|
|
||||||
### Implementing Your Plugin
|
|
||||||
|
|
||||||
**Recommended folder structure:**
|
|
||||||
```
|
|
||||||
src/main/java/com/yourname/yourplugin/
|
|
||||||
├── YourPlugin.java # Main class
|
|
||||||
├── commands/ # Commands
|
|
||||||
├── listeners/ # Event listeners
|
|
||||||
├── services/ # Business logic
|
|
||||||
├── storage/ # Data persistence
|
|
||||||
├── config/ # Configuration
|
|
||||||
└── utils/ # Utilities
|
|
||||||
```
|
|
||||||
|
|
||||||
**See our documentation for examples:**
|
|
||||||
- [Getting Started with Plugins](../Documentation/07-getting-started-with-plugins.md)
|
|
||||||
- [Advanced Plugin Patterns](../Documentation/12-advanced-plugin-patterns.md)
|
|
||||||
- [Common Plugin Features](../Documentation/14-common-plugin-features.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## CI/CD
|
|
||||||
|
|
||||||
This template includes a GitHub Actions workflow that:
|
|
||||||
|
|
||||||
1. ✅ Builds your plugin on every push
|
|
||||||
2. ✅ Runs tests
|
|
||||||
3. ✅ Uploads artifacts
|
|
||||||
4. ✅ Creates releases (when you tag)
|
|
||||||
|
|
||||||
### Creating a Release
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git tag v1.0.0
|
|
||||||
git push origin v1.0.0
|
|
||||||
```
|
|
||||||
|
|
||||||
GitHub Actions will automatically build and create a release with your plugin JAR.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Best Practices
|
|
||||||
|
|
||||||
### ✅ DO:
|
|
||||||
|
|
||||||
- Use the Service-Storage pattern for data management
|
|
||||||
- Write unit tests for your business logic
|
|
||||||
- Use structured logging (not `System.out.println`)
|
|
||||||
- Handle errors gracefully
|
|
||||||
- Document your public API
|
|
||||||
- Version your releases semantically (1.0.0, 1.1.0, etc.)
|
|
||||||
|
|
||||||
### ❌ DON'T:
|
|
||||||
|
|
||||||
- Hardcode configuration values
|
|
||||||
- Block the main thread with heavy operations
|
|
||||||
- Ignore exceptions
|
|
||||||
- Use deprecated APIs
|
|
||||||
- Commit sensitive data (API keys, passwords)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Build Fails
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Clean and rebuild
|
|
||||||
./gradlew clean build --refresh-dependencies
|
|
||||||
```
|
|
||||||
|
|
||||||
### Server Won't Start
|
|
||||||
|
|
||||||
1. Check that `jarUrl` in `build.gradle.kts` is correct
|
|
||||||
2. Verify Java 25 is installed: `java -version`
|
|
||||||
3. Check logs in `run/logs/`
|
|
||||||
|
|
||||||
### Plugin Not Loading
|
|
||||||
|
|
||||||
1. Verify `manifest.json` has correct `Main` class
|
|
||||||
2. Check server logs for errors
|
|
||||||
3. Ensure all dependencies are bundled in JAR
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
For detailed guides on plugin development, see:
|
|
||||||
|
|
||||||
- [Hytale Modding Documentation](https://github.com/yourusername/hytale-modding/tree/main/Documentation)
|
|
||||||
- [Getting Started with Plugins](../Documentation/07-getting-started-with-plugins.md)
|
|
||||||
- [Advanced Plugin Patterns](../Documentation/12-advanced-plugin-patterns.md)
|
|
||||||
- [Common Plugin Features](../Documentation/14-common-plugin-features.md)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Contributions are welcome! Please:
|
|
||||||
|
|
||||||
1. Fork the repository
|
|
||||||
2. Create a feature branch
|
|
||||||
3. Make your changes
|
|
||||||
4. Submit a pull request
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This template is released under the MIT License. You are free to use it for any purpose.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
- **Issues:** [GitHub Issues](https://github.com/yourusername/hytale-plugin-template/issues)
|
|
||||||
- **Documentation:** [Hytale Modding Docs](https://github.com/yourusername/hytale-modding)
|
|
||||||
- **Community:** Join the Hytale modding community
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Credits
|
|
||||||
|
|
||||||
Created by the Hytale modding community.
|
|
||||||
|
|
||||||
Based on best practices from production Hytale plugins.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Happy Modding! 🎮**
|
|
||||||
131
build.gradle
Normal file
131
build.gradle
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'org.jetbrains.gradle.plugin.idea-ext' version '1.3'
|
||||||
|
}
|
||||||
|
|
||||||
|
import org.gradle.internal.os.OperatingSystem
|
||||||
|
|
||||||
|
ext {
|
||||||
|
if (project.hasProperty('hytale_home')) {
|
||||||
|
hytaleHome = project.findProperty('hytale_home')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
def os = OperatingSystem.current()
|
||||||
|
if (os.isWindows()) {
|
||||||
|
hytaleHome = "${System.getProperty("user.home")}/AppData/Roaming/Hytale"
|
||||||
|
}
|
||||||
|
else if (os.isMacOsX()) {
|
||||||
|
hytaleHome = "${System.getProperty("user.home")}/Library/Application Support/Hytale"
|
||||||
|
}
|
||||||
|
else if (os.isLinux()) {
|
||||||
|
hytaleHome = "${System.getProperty("user.home")}/.var/app/com.hypixel.HytaleLauncher/data/Hytale"
|
||||||
|
if (!file(hytaleHome).exists()) {
|
||||||
|
hytaleHome = "${System.getProperty("user.home")}/.local/share/Hytale"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!project.hasProperty('hytaleHome')) {
|
||||||
|
throw new GradleException('Your Hytale install could not be detected automatically. If you are on an unsupported platform or using a custom install location, please define the install location using the hytale_home property.');
|
||||||
|
}
|
||||||
|
else if (!file(project.findProperty('hytaleHome')).exists()) {
|
||||||
|
throw new GradleException("Failed to find Hytale at the expected location. Please make sure you have installed the game. The expected location can be changed using the hytale_home property. Currently looking in ${project.findProperty('hytaleHome')}")
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain.languageVersion = JavaLanguageVersion.of(java_version)
|
||||||
|
withSourcesJar()
|
||||||
|
withJavadocJar()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quiet warnings about missing Javadocs.
|
||||||
|
javadoc {
|
||||||
|
options.addStringOption('Xdoclint:-missing', '-quiet')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds the Hytale server as a build dependency, allowing you to reference and
|
||||||
|
// compile against their code. This requires you to have Hytale installed using
|
||||||
|
// the official launcher for now.
|
||||||
|
dependencies {
|
||||||
|
implementation(files("$hytaleHome/install/$patchline/package/game/latest/Server/HytaleServer.jar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the working directory to run the server if it does not already exist.
|
||||||
|
def serverRunDir = file("$projectDir/run")
|
||||||
|
if (!serverRunDir.exists()) {
|
||||||
|
serverRunDir.mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the manifest.json file with the latest properties defined in the
|
||||||
|
// build.properties file. Currently we update the version and if packs are
|
||||||
|
// included with the plugin.
|
||||||
|
tasks.register('updatePluginManifest') {
|
||||||
|
def manifestFile = file('src/main/resources/manifest.json')
|
||||||
|
doLast {
|
||||||
|
if (!manifestFile.exists()) {
|
||||||
|
throw new GradleException("Could not find manifest.json at ${manifestFile.path}!")
|
||||||
|
}
|
||||||
|
def manifestJson = new groovy.json.JsonSlurper().parseText(manifestFile.text)
|
||||||
|
manifestJson.Version = version
|
||||||
|
manifestJson.IncludesAssetPack = includes_pack.toBoolean()
|
||||||
|
manifestFile.text = groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(manifestJson))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Makes sure the plugin manifest is up to date.
|
||||||
|
tasks.named('processResources') {
|
||||||
|
dependsOn 'updatePluginManifest'
|
||||||
|
}
|
||||||
|
|
||||||
|
def createServerRunArguments(String srcDir) {
|
||||||
|
def programParameters = '--allow-op --disable-sentry --assets="' + "${hytaleHome}/install/$patchline/package/game/latest/Assets.zip" + '"'
|
||||||
|
def modPaths = []
|
||||||
|
if (includes_pack.toBoolean()) {
|
||||||
|
modPaths << srcDir
|
||||||
|
}
|
||||||
|
if (load_user_mods.toBoolean()) {
|
||||||
|
modPaths << "${hytaleHome}/UserData/Mods"
|
||||||
|
}
|
||||||
|
if (!modPaths.isEmpty()) {
|
||||||
|
programParameters += ' --mods="' + modPaths.join(',') + '"'
|
||||||
|
}
|
||||||
|
return programParameters
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a run configuration in IDEA that will run the Hytale server with
|
||||||
|
// your plugin and the default assets.
|
||||||
|
idea.project.settings.runConfigurations {
|
||||||
|
'HytaleServer'(org.jetbrains.gradle.ext.Application) {
|
||||||
|
mainClass = 'com.hypixel.hytale.Main'
|
||||||
|
moduleName = project.idea.module.name + '.main'
|
||||||
|
programParameters = createServerRunArguments(sourceSets.main.java.srcDirs.first().parentFile.absolutePath)
|
||||||
|
workingDirectory = serverRunDir.absolutePath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a launch.json file for VSCode with the same configuration
|
||||||
|
tasks.register('generateVSCodeLaunch') {
|
||||||
|
def vscodeDir = file("$projectDir/.vscode")
|
||||||
|
def launchFile = file("$vscodeDir/launch.json")
|
||||||
|
doLast {
|
||||||
|
if (!vscodeDir.exists()) {
|
||||||
|
vscodeDir.mkdirs()
|
||||||
|
}
|
||||||
|
def programParams = createServerRunArguments("\${workspaceFolder}")
|
||||||
|
def launchConfig = [
|
||||||
|
version: "0.2.0",
|
||||||
|
configurations: [
|
||||||
|
[
|
||||||
|
type: "java",
|
||||||
|
name: "HytaleServer",
|
||||||
|
request: "launch",
|
||||||
|
mainClass: "com.hypixel.hytale.Main",
|
||||||
|
args: programParams,
|
||||||
|
cwd: "\${workspaceFolder}/run"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
launchFile.text = groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(launchConfig))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id("java-library")
|
|
||||||
id("com.gradleup.shadow") version "9.3.1"
|
|
||||||
id("run-hytale")
|
|
||||||
}
|
|
||||||
|
|
||||||
group = findProperty("pluginGroup") as String? ?: "com.example"
|
|
||||||
version = findProperty("pluginVersion") as String? ?: "1.0.0"
|
|
||||||
description = findProperty("pluginDescription") as String? ?: "A Hytale plugin template"
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenLocal()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
// Hytale Server API (provided by server at runtime)
|
|
||||||
compileOnly(files("libs/hytale-server.jar"))
|
|
||||||
|
|
||||||
// Common dependencies (will be bundled in JAR)
|
|
||||||
implementation("com.google.code.gson:gson:2.10.1")
|
|
||||||
implementation("org.jetbrains:annotations:24.1.0")
|
|
||||||
|
|
||||||
// Test dependencies
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
|
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure server testing
|
|
||||||
runHytale {
|
|
||||||
// TODO: Update this URL when Hytale server is available
|
|
||||||
// Using Paper server as placeholder for testing the runServer functionality
|
|
||||||
jarUrl = "https://fill-data.papermc.io/v1/objects/d5f47f6393aa647759f101f02231fa8200e5bccd36081a3ee8b6a5fd96739057/paper-1.21.10-115.jar"
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks {
|
|
||||||
// Configure Java compilation
|
|
||||||
compileJava {
|
|
||||||
options.encoding = Charsets.UTF_8.name()
|
|
||||||
options.release = 25
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure resource processing
|
|
||||||
processResources {
|
|
||||||
filteringCharset = Charsets.UTF_8.name()
|
|
||||||
|
|
||||||
// Replace placeholders in manifest.json
|
|
||||||
val props = mapOf(
|
|
||||||
"group" to project.group,
|
|
||||||
"version" to project.version,
|
|
||||||
"description" to project.description
|
|
||||||
)
|
|
||||||
inputs.properties(props)
|
|
||||||
|
|
||||||
filesMatching("manifest.json") {
|
|
||||||
expand(props)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure ShadowJar (bundle dependencies)
|
|
||||||
shadowJar {
|
|
||||||
archiveBaseName.set(rootProject.name)
|
|
||||||
archiveClassifier.set("")
|
|
||||||
|
|
||||||
// Relocate dependencies to avoid conflicts
|
|
||||||
relocate("com.google.gson", "com.yourplugin.libs.gson")
|
|
||||||
|
|
||||||
// Minimize JAR size (removes unused classes)
|
|
||||||
minimize()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure tests
|
|
||||||
test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make build depend on shadowJar
|
|
||||||
build {
|
|
||||||
dependsOn(shadowJar)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure Java toolchain
|
|
||||||
java {
|
|
||||||
toolchain {
|
|
||||||
languageVersion.set(JavaLanguageVersion.of(25))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
plugins {
|
|
||||||
`kotlin-dsl`
|
|
||||||
`java-gradle-plugin`
|
|
||||||
}
|
|
||||||
|
|
||||||
gradlePlugin {
|
|
||||||
plugins {
|
|
||||||
create("runHytale") {
|
|
||||||
id = "run-hytale"
|
|
||||||
implementationClass = "RunHytalePlugin"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
import org.gradle.api.DefaultTask
|
|
||||||
import org.gradle.api.Plugin
|
|
||||||
import org.gradle.api.Project
|
|
||||||
import org.gradle.api.tasks.Input
|
|
||||||
import org.gradle.api.tasks.TaskAction
|
|
||||||
import org.gradle.api.tasks.TaskProvider
|
|
||||||
import java.io.File
|
|
||||||
import java.net.URI
|
|
||||||
import java.security.MessageDigest
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Custom Gradle plugin for automated Hytale server testing.
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* runHytale {
|
|
||||||
* jarUrl = "https://example.com/hytale-server.jar"
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* ./gradlew runServer
|
|
||||||
*/
|
|
||||||
open class RunHytalePlugin : Plugin<Project> {
|
|
||||||
override fun apply(project: Project) {
|
|
||||||
// Create extension for configuration
|
|
||||||
val extension = project.extensions.create("runHytale", RunHytaleExtension::class.java)
|
|
||||||
|
|
||||||
// Register the runServer task
|
|
||||||
val runTask: TaskProvider<RunServerTask> = project.tasks.register(
|
|
||||||
"runServer",
|
|
||||||
RunServerTask::class.java
|
|
||||||
) {
|
|
||||||
jarUrl.set(extension.jarUrl)
|
|
||||||
group = "hytale"
|
|
||||||
description = "Downloads and runs the Hytale server with your plugin"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make runServer depend on shadowJar (build plugin first)
|
|
||||||
project.tasks.findByName("shadowJar")?.let {
|
|
||||||
runTask.configure {
|
|
||||||
dependsOn(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extension for configuring the RunHytale plugin.
|
|
||||||
*/
|
|
||||||
open class RunHytaleExtension {
|
|
||||||
var jarUrl: String = "https://example.com/hytale-server.jar"
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Task that downloads, sets up, and runs a Hytale server with the plugin.
|
|
||||||
*/
|
|
||||||
open class RunServerTask : DefaultTask() {
|
|
||||||
|
|
||||||
@Input
|
|
||||||
val jarUrl = project.objects.property(String::class.java)
|
|
||||||
|
|
||||||
@TaskAction
|
|
||||||
fun run() {
|
|
||||||
// Create directories
|
|
||||||
val runDir = File(project.projectDir, "run").apply { mkdirs() }
|
|
||||||
val pluginsDir = File(runDir, "plugins").apply { mkdirs() }
|
|
||||||
val jarFile = File(runDir, "server.jar")
|
|
||||||
|
|
||||||
// Cache directory for downloaded server JARs
|
|
||||||
val cacheDir = File(
|
|
||||||
project.layout.buildDirectory.asFile.get(),
|
|
||||||
"hytale-cache"
|
|
||||||
).apply { mkdirs() }
|
|
||||||
|
|
||||||
// Compute hash of URL for caching
|
|
||||||
val urlHash = MessageDigest.getInstance("SHA-256")
|
|
||||||
.digest(jarUrl.get().toByteArray())
|
|
||||||
.joinToString("") { "%02x".format(it) }
|
|
||||||
val cachedJar = File(cacheDir, "$urlHash.jar")
|
|
||||||
|
|
||||||
// Download server JAR if not cached
|
|
||||||
if (!cachedJar.exists()) {
|
|
||||||
println("Downloading Hytale server from ${jarUrl.get()}")
|
|
||||||
try {
|
|
||||||
URI.create(jarUrl.get()).toURL().openStream().use { input ->
|
|
||||||
cachedJar.outputStream().use { output ->
|
|
||||||
input.copyTo(output)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println("Server JAR downloaded and cached")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
println("ERROR: Failed to download server JAR")
|
|
||||||
println("Make sure the jarUrl in build.gradle.kts is correct")
|
|
||||||
println("Error: ${e.message}")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
println("Using cached server JAR")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy server JAR to run directory
|
|
||||||
cachedJar.copyTo(jarFile, overwrite = true)
|
|
||||||
|
|
||||||
// Copy plugin JAR to plugins folder
|
|
||||||
project.tasks.findByName("shadowJar")?.outputs?.files?.firstOrNull()?.let { shadowJar ->
|
|
||||||
val targetFile = File(pluginsDir, shadowJar.name)
|
|
||||||
shadowJar.copyTo(targetFile, overwrite = true)
|
|
||||||
println("Plugin copied to: ${targetFile.absolutePath}")
|
|
||||||
} ?: run {
|
|
||||||
println("WARNING: Could not find shadowJar output")
|
|
||||||
}
|
|
||||||
|
|
||||||
println("Starting Hytale server...")
|
|
||||||
println("Press Ctrl+C to stop the server")
|
|
||||||
|
|
||||||
// Check if debug mode is enabled
|
|
||||||
val debugMode = project.hasProperty("debug")
|
|
||||||
val javaArgs = mutableListOf<String>()
|
|
||||||
|
|
||||||
if (debugMode) {
|
|
||||||
javaArgs.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005")
|
|
||||||
println("Debug mode enabled. Connect debugger to port 5005")
|
|
||||||
}
|
|
||||||
|
|
||||||
javaArgs.addAll(listOf("-jar", jarFile.name))
|
|
||||||
|
|
||||||
// Start the server process
|
|
||||||
val process = ProcessBuilder("java", *javaArgs.toTypedArray())
|
|
||||||
.directory(runDir)
|
|
||||||
.start()
|
|
||||||
|
|
||||||
// Handle graceful shutdown
|
|
||||||
project.gradle.buildFinished {
|
|
||||||
if (process.isAlive) {
|
|
||||||
println("\nStopping server...")
|
|
||||||
process.destroy()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forward stdout to console
|
|
||||||
Thread {
|
|
||||||
process.inputStream.bufferedReader().useLines { lines ->
|
|
||||||
lines.forEach { println(it) }
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
|
|
||||||
// Forward stderr to console
|
|
||||||
Thread {
|
|
||||||
process.errorStream.bufferedReader().useLines { lines ->
|
|
||||||
lines.forEach { System.err.println(it) }
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
|
|
||||||
// Forward stdin to server (for commands)
|
|
||||||
Thread {
|
|
||||||
System.`in`.bufferedReader().useLines { lines ->
|
|
||||||
lines.forEach {
|
|
||||||
process.outputStream.write((it + "\n").toByteArray())
|
|
||||||
process.outputStream.flush()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
|
|
||||||
// Wait for server to exit
|
|
||||||
val exitCode = process.waitFor()
|
|
||||||
println("Server exited with code $exitCode")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,32 @@
|
|||||||
# Project Information
|
# The current version of your project. Please use semantic versioning!
|
||||||
pluginGroup=com.example
|
version=0.0.2
|
||||||
pluginVersion=1.0.0
|
|
||||||
pluginDescription=A Hytale plugin template with best practices
|
|
||||||
|
|
||||||
# Gradle Configuration
|
# The group ID used for maven publishing. Usually the same as your package name
|
||||||
org.gradle.parallel=true
|
# but not the same as your plugin group!
|
||||||
org.gradle.caching=true
|
maven_group=org.example
|
||||||
org.gradle.daemon=true
|
|
||||||
org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
|
# The version of Java used by your plugin. The game is built on Java 21 but
|
||||||
|
# actually runs on Java 25.
|
||||||
|
java_version=25
|
||||||
|
|
||||||
|
# Determines if your plugin should also be loaded as an asset pack. If your
|
||||||
|
# pack contains assets, or you intend to use the in-game asset editor, you
|
||||||
|
# want this to be true.
|
||||||
|
includes_pack=true
|
||||||
|
|
||||||
|
# The release channel your plugin should be built and ran against. This is
|
||||||
|
# usually release or pre-release. You can verify your settings in the
|
||||||
|
# official launcher.
|
||||||
|
patchline=release
|
||||||
|
|
||||||
|
# Determines if the development server should also load mods from the user's
|
||||||
|
# standard mods folder. This lets you test mods by installing them where a
|
||||||
|
# normal player would, instead of adding them as dependencies or adding them
|
||||||
|
# to the development server manually.
|
||||||
|
load_user_mods=false
|
||||||
|
|
||||||
|
# If Hytale was installed to a custom location, you must set the home path
|
||||||
|
# manually. You may also want to use a custom path if you are building in
|
||||||
|
# a non-standard environment like a build server. The home path should
|
||||||
|
# the folder that contains the install and UserData folder.
|
||||||
|
# hytale_home=./test-file
|
||||||
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,7 +1,6 @@
|
|||||||
|
#Tue Nov 25 02:23:10 MST 2025
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
|
||||||
networkTimeout=10000
|
|
||||||
validateDistributionUrl=true
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
18
gradlew
vendored
18
gradlew
vendored
@@ -55,7 +55,7 @@
|
|||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (3) This script is generated from the Groovy template
|
||||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
@@ -80,11 +80,11 @@ do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# This is normally unused
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
APP_BASE_NAME=${0##*/}
|
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
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.
|
# 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"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
@@ -143,16 +143,12 @@ fi
|
|||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
max*)
|
||||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
|
||||||
# shellcheck disable=SC3045
|
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
'' | soft) :;; #(
|
'' | soft) :;; #(
|
||||||
*)
|
*)
|
||||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
|
||||||
# shellcheck disable=SC3045
|
|
||||||
ulimit -n "$MAX_FD" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
@@ -209,12 +205,6 @@ set -- \
|
|||||||
org.gradle.wrapper.GradleWrapperMain \
|
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.
|
# Use "xargs" to parse quoted args.
|
||||||
#
|
#
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
|||||||
15
gradlew.bat
vendored
15
gradlew.bat
vendored
@@ -14,7 +14,7 @@
|
|||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%" == "" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
@@ -25,8 +25,7 @@
|
|||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%"=="" set DIRNAME=.
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
@rem This is normally unused
|
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@@ -41,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
@@ -76,15 +75,13 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
set EXIT_CODE=%ERRORLEVEL%
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
exit /b 1
|
||||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
|
||||||
exit /b %EXIT_CODE%
|
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|||||||
1
settings.gradle
Normal file
1
settings.gradle
Normal file
@@ -0,0 +1 @@
|
|||||||
|
rootProject.name = 'ExamplePlugin'
|
||||||
@@ -1 +0,0 @@
|
|||||||
rootProject.name = "TemplatePlugin"
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package com.example.templateplugin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main plugin class.
|
|
||||||
*
|
|
||||||
* TODO: Implement your plugin logic here.
|
|
||||||
*
|
|
||||||
* @author YourName
|
|
||||||
* @version 1.0.0
|
|
||||||
*/
|
|
||||||
public class TemplatePlugin {
|
|
||||||
|
|
||||||
private static TemplatePlugin instance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor - Called when plugin is loaded.
|
|
||||||
*/
|
|
||||||
public TemplatePlugin() {
|
|
||||||
instance = this;
|
|
||||||
System.out.println("[TemplatePlugin] Plugin loaded!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when plugin is enabled.
|
|
||||||
*/
|
|
||||||
public void onEnable() {
|
|
||||||
System.out.println("[TemplatePlugin] Plugin enabled!");
|
|
||||||
|
|
||||||
// TODO: Initialize your plugin here
|
|
||||||
// - Load configuration
|
|
||||||
// - Register event listeners
|
|
||||||
// - Register commands
|
|
||||||
// - Start services
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when plugin is disabled.
|
|
||||||
*/
|
|
||||||
public void onDisable() {
|
|
||||||
System.out.println("[TemplatePlugin] Plugin disabled!");
|
|
||||||
|
|
||||||
// TODO: Cleanup your plugin here
|
|
||||||
// - Save data
|
|
||||||
// - Stop services
|
|
||||||
// - Close connections
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get plugin instance.
|
|
||||||
*/
|
|
||||||
public static TemplatePlugin getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
29
src/main/java/org/example/plugin/ExampleCommand.java
Normal file
29
src/main/java/org/example/plugin/ExampleCommand.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package org.example.plugin;
|
||||||
|
|
||||||
|
import com.hypixel.hytale.protocol.GameMode;
|
||||||
|
import com.hypixel.hytale.server.core.Message;
|
||||||
|
import com.hypixel.hytale.server.core.command.system.CommandContext;
|
||||||
|
import com.hypixel.hytale.server.core.command.system.basecommands.CommandBase;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is an example command that will simply print the name of the plugin in chat when used.
|
||||||
|
*/
|
||||||
|
public class ExampleCommand extends CommandBase {
|
||||||
|
|
||||||
|
private final String pluginName;
|
||||||
|
private final String pluginVersion;
|
||||||
|
|
||||||
|
public ExampleCommand(String pluginName, String pluginVersion) {
|
||||||
|
super("test", "Prints a test message from the " + pluginName + " plugin.");
|
||||||
|
this.setPermissionGroup(GameMode.Adventure); // Allows the command to be used by anyone, not just OP
|
||||||
|
this.pluginName = pluginName;
|
||||||
|
this.pluginVersion = pluginVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void executeSync(@Nonnull CommandContext ctx) {
|
||||||
|
ctx.sendMessage(Message.raw("Hello from the " + pluginName + " v" + pluginVersion + " plugin!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/main/java/org/example/plugin/ExamplePlugin.java
Normal file
27
src/main/java/org/example/plugin/ExamplePlugin.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package org.example.plugin;
|
||||||
|
|
||||||
|
import com.hypixel.hytale.logger.HytaleLogger;
|
||||||
|
import com.hypixel.hytale.server.core.plugin.JavaPlugin;
|
||||||
|
import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class serves as the entrypoint for your plugin. Use the setup method to register into game registries or add
|
||||||
|
* event listeners.
|
||||||
|
*/
|
||||||
|
public class ExamplePlugin extends JavaPlugin {
|
||||||
|
|
||||||
|
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
|
||||||
|
|
||||||
|
public ExamplePlugin(@Nonnull JavaPluginInit init) {
|
||||||
|
super(init);
|
||||||
|
LOGGER.atInfo().log("Hello from " + this.getName() + " version " + this.getManifest().getVersion().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setup() {
|
||||||
|
LOGGER.atInfo().log("Setting up plugin " + this.getName());
|
||||||
|
this.getCommandRegistry().registerCommand(new ExampleCommand(this.getName(), this.getManifest().getVersion().toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/main/resources/Server/Item/Recipes/Example_Recipe.json
Normal file
22
src/main/resources/Server/Item/Recipes/Example_Recipe.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"Input": [
|
||||||
|
{
|
||||||
|
"ItemId": "Soil_Dirt",
|
||||||
|
"Quantity": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"PrimaryOutput": {
|
||||||
|
"ItemId": "Soil_Dirt",
|
||||||
|
"Quantity": 1
|
||||||
|
},
|
||||||
|
"BenchRequirement": [
|
||||||
|
{
|
||||||
|
"Id": "Fieldcraft",
|
||||||
|
"Type": "Crafting",
|
||||||
|
"Categories": [
|
||||||
|
"Tools"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Seconds": 1
|
||||||
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"pluginName": "TemplatePlugin",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"debugMode": false
|
|
||||||
}
|
|
||||||
@@ -1,19 +1,22 @@
|
|||||||
{
|
{
|
||||||
"Group": "TemplatePlugin",
|
"Group": "Example",
|
||||||
"Name": "TemplatePlugin",
|
"Name": "ExamplePlugin",
|
||||||
"Version": "1.0.0",
|
"Version": "0.0.2",
|
||||||
"Description": "A Hytale plugin template",
|
"Description": "An example plugin for HyTale!",
|
||||||
"Authors": [
|
"Authors": [
|
||||||
{
|
{
|
||||||
"Name": "YourName",
|
"Name": "It's you!"
|
||||||
"Email": "your.email@example.com",
|
|
||||||
"Url": "https://your-website.com"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"Website": "https://github.com/yourusername/hytale-plugin-template",
|
"Website": "example.org",
|
||||||
"Main": "com.example.templateplugin.TemplatePlugin",
|
|
||||||
"ServerVersion": "*",
|
"ServerVersion": "*",
|
||||||
"Dependencies": {},
|
"Dependencies": {
|
||||||
"OptionalDependencies": {},
|
|
||||||
"DisabledByDefault": false
|
},
|
||||||
|
"OptionalDependencies": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"DisabledByDefault": false,
|
||||||
|
"Main": "org.example.plugin.ExamplePlugin",
|
||||||
|
"IncludesAssetPack": true
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user