Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: "🐛 Bug Report"
description: Report a bug or unexpected behavior
labels: ["bug"]
body:
- type: input
id: summary
attributes:
label: Summary
description: One-line summary of the bug
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to Reproduce
description: Step-by-step instructions to reproduce
placeholder: |
1. Start server with plugin version X
2. Run command /...
3. Observe error
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected Behavior
description: What should happen?
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual Behavior
description: What actually happens?
validations:
required: true
- type: input
id: plugin_version
attributes:
label: Plugin Version
placeholder: "e.g. v1.2.10"
validations:
required: true
- type: input
id: server_version
attributes:
label: Server Version
description: Output of /version
placeholder: "e.g. Paper 1.21.4-123"
validations:
required: true
- type: input
id: java_version
attributes:
label: Java Version
placeholder: "e.g. Java 21.0.2"
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs / Stacktrace
description: Relevant console output (use code block)
render: shell
- type: textarea
id: extra
attributes:
label: Additional Context
description: Screenshots, configs, other plugins installed, etc.
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: "💬 Discord Support"
url: https://discord.gg/RYFamQzkcB
about: Get help or chat with the community
- name: "📖 Documentation"
url: https://chafficplugins.github.io
about: Check the docs before filing an issue
33 changes: 33 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: "✨ Feature Request"
description: Suggest a new feature or improvement
labels: ["feature"]
body:
- type: textarea
id: problem
attributes:
label: Problem / Motivation
description: What problem does this solve? Why is it needed?
validations:
required: true
- type: textarea
id: solution
attributes:
label: Proposed Solution
description: How should this work?
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives Considered
description: Other approaches you've thought about
- type: textarea
id: acceptance
attributes:
label: Acceptance Criteria
description: How do we know this is done?
placeholder: |
- [ ] Criterion 1
- [ ] Criterion 2
validations:
required: true
25 changes: 25 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## What
<!-- What does this PR do? Keep it short. -->

## Why
<!-- Why is this change needed? Link the issue. -->

Closes #

## How
<!-- How was this implemented? Key technical decisions. -->

## Testing
<!-- How was this tested? -->

- [ ] Unit tests added/updated
- [ ] `mvn verify` passes locally
- [ ] Tested manually on a test server (if applicable)

## Checklist

- [ ] Issue linked above
- [ ] Tests pass
- [ ] No new warnings
- [ ] Docs updated (if user-facing change)
- [ ] Changelog entry added (if user-facing change)
10 changes: 7 additions & 3 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ After first run, MiningLevels creates the following files:
```
plugins/MiningLevels/
├── config.yml # Main configuration
└── config/
├── levels.json # Level definitions
└── blocks.json # Mining block definitions
├── config/
│ ├── levels.json # Level definitions
│ └── blocks.json # Mining block definitions
└── data/
└── players.json # Player progress data
```

Default `levels.json` and `blocks.json` are bundled inside the plugin JAR and copied automatically on first run. No internet connection is required for setup.
12 changes: 7 additions & 5 deletions src/main/java/de/chafficplugins/mininglevels/MiningLevels.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,13 @@ public void onEnable() {

@Override
public void onDisable() {
// Plugin shutdown logic
try {
MiningPlayer.save();
} catch (IOException e) {
error("Failed to save files.");
// Only save if startup completed successfully (fileManager was initialized)
if (fileManager != null) {
try {
MiningPlayer.save();
} catch (IOException e) {
error("Failed to save files.");
}
}
Bukkit.getScheduler().cancelTasks(this);
log(ChatColor.DARK_GREEN + getDescription().getName() + " is now disabled (Version: " + getDescription().getVersion() + ")");
Expand Down
50 changes: 28 additions & 22 deletions src/main/java/de/chafficplugins/mininglevels/io/FileManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,28 @@
import io.github.chafficui.CrucialLib.io.Json;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;

import static de.chafficplugins.mininglevels.utils.ConfigStrings.*;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

public class FileManager {
private final static MiningLevels plugin = MiningLevels.getPlugin(MiningLevels.class);
public final static String PLAYERS = plugin.getDataFolder() + "/data/players.json";
public final static String BLOCKS = plugin.getDataFolder() + "/config/blocks.json";
public final static String LEVELS = plugin.getDataFolder() + "/config/levels.json";
private static MiningLevels plugin;
private static MiningLevels getPlugin() {
if (plugin == null) plugin = MiningLevels.getPlugin(MiningLevels.class);
return plugin;
}

public static String PLAYERS;
public static String BLOCKS;
public static String LEVELS;

static {
MiningLevels p = getPlugin();
PLAYERS = p.getDataFolder() + "/data/players.json";
BLOCKS = p.getDataFolder() + "/config/blocks.json";
LEVELS = p.getDataFolder() + "/config/levels.json";
}

public FileManager() throws IOException {
setupFiles();
Expand All @@ -39,27 +48,24 @@ private void setupFiles() throws IOException {
}
File blocksFile = new File(BLOCKS);
if (!blocksFile.exists()) {
downloadFile(blocksFile, MINING_BLOCKS_JSON);
copyDefault("defaults/blocks.json", blocksFile);
}
File levelsFile = new File(LEVELS);
if (!levelsFile.exists()) {
downloadFile(levelsFile, MINING_LEVELS_JSON);
copyDefault("defaults/levels.json", levelsFile);
}
}

private void downloadFile(File file, String downloadURL) throws IOException {
File dir = file.getParentFile();
private void copyDefault(String resourcePath, File destination) throws IOException {
File dir = destination.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}
try {
URL url = new URL(DOWNLOAD_URL + downloadURL);
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
FileOutputStream fos = new FileOutputStream(file);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
} catch (IOException e) {
e.printStackTrace();
throw new IOException("Could not download " + file.getAbsolutePath() + ".");
try (InputStream in = getPlugin().getResource(resourcePath)) {
if (in == null) {
throw new IOException("Bundled default resource not found: " + resourcePath);
}
Files.copy(in, destination.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ public class ConfigStrings {

public static String PREFIX = "§8[§6ML§8] §r";

public final static String DOWNLOAD_URL = "https://drive.google.com/uc?export=download&id=";
public final static String MINING_LEVELS_JSON = "145W6qtWM2-PA3vyDlOpa3nnYrn0bUVyb";
public final static String MINING_BLOCKS_JSON = "1W1EN0NIJKH69cokExNKVglOw6YPbEBYT";

//Permissions
public final static String PERMISSION_ADMIN = "mininglevels.*";
public final static String PERMISSION_SET_LEVEL = "mininglevels.setlevel";
Expand Down
73 changes: 73 additions & 0 deletions src/main/resources/defaults/blocks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
[
{
"materials": [
"STONE"
],
"xp": 1,
"minLevel": 0
},
{
"materials": [
"DEEPSLATE_REDSTONE_ORE",
"REDSTONE_ORE"
],
"xp": 1,
"minLevel": 0
},
{
"materials": [
"DEEPSLATE_LAPIS_ORE",
"LAPIS_ORE"
],
"xp": 1,
"minLevel": 3
},
{
"materials": [
"DEEPSLATE_COAL_ORE",
"COAL_ORE"
],
"xp": 10,
"minLevel": 0
},
{
"materials": [
"DEEPSLATE_GOLD_ORE",
"GOLD_ORE"
],
"xp": 100,
"minLevel": 2
},
{
"materials": [
"DEEPSLATE_EMERALD_ORE",
"EMERALD_ORE"
],
"xp": 10,
"minLevel": 3
},
{
"materials": [
"DEEPSLATE_COPPER_ORE",
"COPPER_ORE"
],
"xp": 5,
"minLevel": 2
},
{
"materials": [
"DEEPSLATE_IRON_ORE",
"IRON_ORE"
],
"xp": 50,
"minLevel": 1
},
{
"materials": [
"DEEPSLATE_DIAMOND_ORE",
"DIAMOND_ORE"
],
"xp": 1000,
"minLevel": 5
}
]
Loading