Compare commits
22 Commits
1.0
...
preview-10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a6afd5565 | ||
|
|
3cb145e1d6 | ||
|
|
cdf73058e6 | ||
|
|
eb5ec93be5 | ||
|
|
e90fa7fc44 | ||
|
|
f19def6dc6 | ||
|
|
427d71e2b8 | ||
|
|
feeae861ea | ||
|
|
8c23b627c8 | ||
|
|
54dc959395 | ||
|
|
843d42b0d6 | ||
|
|
5b06b106da | ||
| 66c6cb76c4 | |||
| e37b176a3e | |||
|
|
798841215e | ||
| 70c91b4ad2 | |||
| 8252b23797 | |||
|
|
5443f7f02c | ||
| 4f05bcd479 | |||
| 1f49160eb9 | |||
| 46069f52d9 | |||
| 2f5c9f8e24 |
46
.github/workflows/preview-release.yml
vendored
Normal file
46
.github/workflows/preview-release.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Preview Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '21'
|
||||
distribution: 'temurin'
|
||||
- run: chmod +x gradlew
|
||||
- run: ./gradlew clean build -x test
|
||||
|
||||
# Tag erstellen, bevor Release angelegt wird
|
||||
- name: Create Preview Tag
|
||||
run: |
|
||||
git config user.name "github-actions"
|
||||
git config user.email "github-actions@users.noreply.github.com"
|
||||
git tag preview-${{ github.run_number }}
|
||||
git push origin preview-${{ github.run_number }}
|
||||
|
||||
- name: Create Preview Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: preview-${{ github.run_number }}
|
||||
name: "Preview Build #${{ github.run_number }}"
|
||||
prerelease: true
|
||||
files: build/libs/*.jar
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Cleanup old Preview Releases
|
||||
run: |
|
||||
gh release list --limit 100 --repo $GITHUB_REPOSITORY \
|
||||
| grep preview \
|
||||
| sort -rk2 \
|
||||
| awk 'NR>10 {print $1}' \
|
||||
| xargs -I {} gh release delete {} --repo $GITHUB_REPOSITORY --yes
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
50
.github/workflows/release-on-merge.yml
vendored
Normal file
50
.github/workflows/release-on-merge.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: Release on Merge to Master
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master # oder "main", je nach Repo
|
||||
paths-ignore:
|
||||
- '**.md' # ignoriert reine Dokumentationsänderungen
|
||||
- '.github/**' # ignoriert Änderungen an Actions selbst
|
||||
|
||||
jobs:
|
||||
build-and-release:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write # Berechtigung für Releases hinzufügen
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '21'
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew clean build
|
||||
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: |
|
||||
# Extrahiere die Version aus der build.gradle
|
||||
VERSION=$(./gradlew properties -q | grep "version:" | awk '{print $2}')
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ steps.get_version.outputs.version }}
|
||||
name: "Release v${{ steps.get_version.outputs.version }}"
|
||||
body: |
|
||||
**v${{ steps.get_version.outputs.version }}**
|
||||
- Commit: ${{ github.sha }}
|
||||
- Branch: ${{ github.ref_name }}
|
||||
- Version: v${{ steps.get_version.outputs.version }}
|
||||
files: |
|
||||
build/libs/*.jar
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
43
.github/workflows/static.yml
vendored
Normal file
43
.github/workflows/static.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# Simple workflow for deploying static content to GitHub Pages
|
||||
name: Deploy static content to Pages
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["master"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Single deploy job since we're just deploying
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
# Upload entire repository
|
||||
path: './web'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Deutschich aka User404
|
||||
|
||||
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.
|
||||
@@ -3,7 +3,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "com.user404_"
|
||||
version = "1.0-SNAPSHOT"
|
||||
version = "1.1"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
@@ -4,6 +4,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -11,22 +12,46 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class InfiniteHomes extends JavaPlugin {
|
||||
public class InfiniteHomes extends JavaPlugin implements TabCompleter {
|
||||
|
||||
private Map<UUID, Map<String, Location>> homes;
|
||||
private Map<UUID, Long> cooldowns;
|
||||
private FileConfiguration homesConfig;
|
||||
private File homesFile;
|
||||
private Map<String, FileConfiguration> translations;
|
||||
private File translationsDir;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
homes = new HashMap<>();
|
||||
cooldowns = new HashMap<>();
|
||||
translations = new HashMap<>();
|
||||
|
||||
setupHomesConfig();
|
||||
loadHomesFromConfig();
|
||||
setupTranslations();
|
||||
|
||||
// Standardkonfiguration erstellen, falls nicht vorhanden
|
||||
getConfig().addDefault("max-homes", -1);
|
||||
getConfig().addDefault("home-cooldown", -1);
|
||||
getConfig().options().copyDefaults(true);
|
||||
saveConfig();
|
||||
|
||||
// TabCompleter registrieren
|
||||
getCommand("home").setTabCompleter(this);
|
||||
getCommand("delhome").setTabCompleter(this);
|
||||
|
||||
getLogger().info("InfiniteHomes plugin enabled!");
|
||||
}
|
||||
|
||||
@@ -36,6 +61,43 @@ public class InfiniteHomes extends JavaPlugin {
|
||||
getLogger().info("InfiniteHomes plugin disabled!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
List<String> completions = new ArrayList<>();
|
||||
|
||||
// Nur für Spieler und für die Befehle home und delhome
|
||||
if (!(sender instanceof Player) || (!command.getName().equalsIgnoreCase("home") &&
|
||||
!command.getName().equalsIgnoreCase("delhome"))) {
|
||||
return completions;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
UUID playerUuid = player.getUniqueId();
|
||||
|
||||
// Wenn der Spieler keine Homes hat, leere Liste zurückgeben
|
||||
if (!homes.containsKey(playerUuid) || homes.get(playerUuid).isEmpty()) {
|
||||
return completions;
|
||||
}
|
||||
|
||||
// Home-Namen des Spielers holen
|
||||
Set<String> homeNames = homes.get(playerUuid).keySet();
|
||||
|
||||
// Wenn kein Argument vorhanden ist, alle Home-Namen zurückgeben
|
||||
if (args.length == 0 || args[0].isEmpty()) {
|
||||
completions.addAll(homeNames);
|
||||
} else {
|
||||
// Home-Namen filtern, die mit dem eingegebenen Text beginnen
|
||||
String input = args[0].toLowerCase();
|
||||
for (String home : homeNames) {
|
||||
if (home.toLowerCase().startsWith(input)) {
|
||||
completions.add(home);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return completions;
|
||||
}
|
||||
|
||||
private void setupHomesConfig() {
|
||||
if (!getDataFolder().exists()) {
|
||||
getDataFolder().mkdirs();
|
||||
@@ -54,6 +116,87 @@ public class InfiniteHomes extends JavaPlugin {
|
||||
homesConfig = YamlConfiguration.loadConfiguration(homesFile);
|
||||
}
|
||||
|
||||
private void setupTranslations() {
|
||||
translationsDir = new File(getDataFolder(), "translations");
|
||||
if (!translationsDir.exists()) {
|
||||
translationsDir.mkdirs();
|
||||
}
|
||||
|
||||
// Standard-Übersetzung (Englisch) aus Ressourcen laden
|
||||
saveResource("translations/texts_en.yml", false);
|
||||
|
||||
// Verfügbare Übersetzungen laden
|
||||
loadTranslations();
|
||||
}
|
||||
|
||||
private void loadTranslations() {
|
||||
translations.clear();
|
||||
|
||||
File[] translationFiles = translationsDir.listFiles((dir, name) ->
|
||||
name.startsWith("texts_") && name.endsWith(".yml"));
|
||||
|
||||
if (translationFiles != null) {
|
||||
for (File file : translationFiles) {
|
||||
try {
|
||||
String locale = file.getName().replace("texts_", "").replace(".yml", "");
|
||||
FileConfiguration config = YamlConfiguration.loadConfiguration(file);
|
||||
translations.put(locale, config);
|
||||
getLogger().info("Loaded translation: " + locale);
|
||||
} catch (Exception e) {
|
||||
getLogger().log(Level.WARNING, "Error loading translation file: " + file.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: Englische Übersetzung aus Ressourcen laden
|
||||
if (!translations.containsKey("en")) {
|
||||
try {
|
||||
InputStream stream = getResource("translations/texts_en.yml");
|
||||
if (stream != null) {
|
||||
FileConfiguration config = YamlConfiguration.loadConfiguration(
|
||||
new InputStreamReader(stream, StandardCharsets.UTF_8));
|
||||
translations.put("en", config);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
getLogger().log(Level.WARNING, "Error loading default English translation", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getMessage(Player player, String key) {
|
||||
// Sprache des Clients ermitteln
|
||||
String clientLanguage = player.getLocale().toLowerCase();
|
||||
|
||||
// Sprache auf Standardformat normalisieren (z.B. "de_de" -> "de")
|
||||
String languageCode = clientLanguage.split("_")[0];
|
||||
|
||||
// Passende Übersetzung finden
|
||||
FileConfiguration translation = translations.get(languageCode);
|
||||
if (translation == null) {
|
||||
// Fallback: Englisch
|
||||
translation = translations.get("en");
|
||||
if (translation == null) {
|
||||
return "Translation not found for key: " + key;
|
||||
}
|
||||
}
|
||||
|
||||
// Nachricht aus der Übersetzung holen
|
||||
String message = translation.getString(key);
|
||||
if (message == null || message.isEmpty()) {
|
||||
// Fallback: Englisch
|
||||
FileConfiguration enTranslation = translations.get("en");
|
||||
if (enTranslation != null) {
|
||||
message = enTranslation.getString(key);
|
||||
}
|
||||
|
||||
if (message == null || message.isEmpty()) {
|
||||
return "Message not found: " + key;
|
||||
}
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
private void loadHomesFromConfig() {
|
||||
try {
|
||||
for (String playerUuidString : homesConfig.getKeys(false)) {
|
||||
@@ -107,7 +250,7 @@ public class InfiniteHomes extends JavaPlugin {
|
||||
|
||||
if (cmd.getName().equalsIgnoreCase("sethome")) {
|
||||
if (args.length != 1) {
|
||||
player.sendMessage("Usage: /sethome <name>");
|
||||
player.sendMessage(getMessage(player, "usage.sethome"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -116,7 +259,7 @@ public class InfiniteHomes extends JavaPlugin {
|
||||
if (maxHomes != -1) {
|
||||
int currentHomes = homes.containsKey(playerUuid) ? homes.get(playerUuid).size() : 0;
|
||||
if (currentHomes >= maxHomes) {
|
||||
player.sendMessage("§cYou have reached the maximum number of homes (" + maxHomes + ").");
|
||||
player.sendMessage(getMessage(player, "homes.limit.reached").replace("{max}", String.valueOf(maxHomes)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -128,13 +271,13 @@ public class InfiniteHomes extends JavaPlugin {
|
||||
|
||||
homes.get(playerUuid).put(homeName, player.getLocation());
|
||||
saveHomesToConfig();
|
||||
player.sendMessage("§aHome '" + homeName + "' set!");
|
||||
player.sendMessage(getMessage(player, "home.set").replace("{home}", homeName));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cmd.getName().equalsIgnoreCase("delhome")) {
|
||||
if (args.length != 1) {
|
||||
player.sendMessage("Usage: /delhome <name>");
|
||||
player.sendMessage(getMessage(player, "usage.delhome"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -142,37 +285,84 @@ public class InfiniteHomes extends JavaPlugin {
|
||||
if (homes.containsKey(playerUuid) && homes.get(playerUuid).containsKey(homeName)) {
|
||||
homes.get(playerUuid).remove(homeName);
|
||||
saveHomesToConfig();
|
||||
player.sendMessage("§aHome '" + homeName + "' deleted!");
|
||||
player.sendMessage(getMessage(player, "home.deleted").replace("{home}", homeName));
|
||||
} else {
|
||||
player.sendMessage("§cHome '" + homeName + "' does not exist.");
|
||||
player.sendMessage(getMessage(player, "home.not_exist").replace("{home}", homeName));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cmd.getName().equalsIgnoreCase("home")) {
|
||||
if (args.length != 1) {
|
||||
player.sendMessage("Usage: /home <name>");
|
||||
player.sendMessage(getMessage(player, "usage.home"));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check cooldown
|
||||
int cooldown = getConfig().getInt("home-cooldown", -1);
|
||||
if (cooldown > 0) {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (cooldowns.containsKey(playerUuid)) {
|
||||
long lastUsed = cooldowns.get(playerUuid);
|
||||
long timeLeft = ((lastUsed / 1000) + cooldown) - (currentTime / 1000);
|
||||
|
||||
if (timeLeft > 0) {
|
||||
player.sendMessage(getMessage(player, "home.cooldown").replace("{time}", String.valueOf(timeLeft)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Set cooldown
|
||||
cooldowns.put(playerUuid, currentTime);
|
||||
}
|
||||
|
||||
String homeName = args[0].toLowerCase();
|
||||
if (homes.containsKey(playerUuid) && homes.get(playerUuid).containsKey(homeName)) {
|
||||
player.teleport(homes.get(playerUuid).get(homeName));
|
||||
player.sendMessage("§aTeleported to home '" + homeName + "'!");
|
||||
player.sendMessage(getMessage(player, "home.teleport").replace("{home}", homeName));
|
||||
} else {
|
||||
player.sendMessage("§cHome '" + homeName + "' does not exist.");
|
||||
player.sendMessage(getMessage(player, "home.not_exist").replace("{home}", homeName));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cmd.getName().equalsIgnoreCase("homes")) {
|
||||
// List all homes of the player
|
||||
if (!homes.containsKey(playerUuid) || homes.get(playerUuid).isEmpty()) {
|
||||
player.sendMessage(getMessage(player, "homes.none"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Set<String> homeNames = homes.get(playerUuid).keySet();
|
||||
int maxHomes = getConfig().getInt("max-homes", -1);
|
||||
int currentHomes = homeNames.size();
|
||||
|
||||
String limitText = (maxHomes == -1) ? getMessage(player, "homes.unlimited") : String.valueOf(maxHomes);
|
||||
player.sendMessage(getMessage(player, "homes.list.header")
|
||||
.replace("{current}", String.valueOf(currentHomes))
|
||||
.replace("{max}", limitText));
|
||||
|
||||
// List all home names
|
||||
StringBuilder homesList = new StringBuilder();
|
||||
for (String home : homeNames) {
|
||||
if (homesList.length() > 0) {
|
||||
homesList.append(", ");
|
||||
}
|
||||
homesList.append(home);
|
||||
}
|
||||
|
||||
player.sendMessage(getMessage(player, "homes.list.items").replace("{homes}", homesList.toString()));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cmd.getName().equalsIgnoreCase("homecount")) {
|
||||
if (!player.isOp()) {
|
||||
player.sendMessage("§cYou do not have permission to use this command.");
|
||||
player.sendMessage(getMessage(player, "no_permission"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length != 1) {
|
||||
player.sendMessage("Usage: /homecount <number>");
|
||||
player.sendMessage(getMessage(player, "usage.homecount"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -180,9 +370,41 @@ public class InfiniteHomes extends JavaPlugin {
|
||||
int newMax = Integer.parseInt(args[0]);
|
||||
getConfig().set("max-homes", newMax);
|
||||
saveConfig();
|
||||
player.sendMessage("§aGlobal home limit set to " + newMax + ".");
|
||||
player.sendMessage(getMessage(player, "homes.limit.set").replace("{max}", String.valueOf(newMax)));
|
||||
} catch (NumberFormatException e) {
|
||||
player.sendMessage("§cPlease provide a valid number.");
|
||||
player.sendMessage(getMessage(player, "invalid_number"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cmd.getName().equalsIgnoreCase("homecooldown")) {
|
||||
if (!player.isOp()) {
|
||||
player.sendMessage(getMessage(player, "no_permission"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length != 1) {
|
||||
player.sendMessage(getMessage(player, "usage.homecooldown"));
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
int cooldown = Integer.parseInt(args[0]);
|
||||
if (cooldown < -1 || cooldown > 60) {
|
||||
player.sendMessage(getMessage(player, "cooldown.range"));
|
||||
return true;
|
||||
}
|
||||
|
||||
getConfig().set("home-cooldown", cooldown);
|
||||
saveConfig();
|
||||
|
||||
if (cooldown == -1) {
|
||||
player.sendMessage(getMessage(player, "cooldown.disabled"));
|
||||
} else {
|
||||
player.sendMessage(getMessage(player, "cooldown.set").replace("{time}", String.valueOf(cooldown)));
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
player.sendMessage(getMessage(player, "invalid_number"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
# Default home limit (-1 = unlimited)
|
||||
max-homes: -1
|
||||
# Home-Limit Configuration
|
||||
max-homes: -1
|
||||
|
||||
# Home-Cooldown in seconds (-1 um to disable)
|
||||
home-cooldown: -1
|
||||
@@ -1,6 +1,7 @@
|
||||
name: InfiniteHomes
|
||||
version: 1.0
|
||||
version: 1.1
|
||||
main: com.user404_.infinitehomes.InfiniteHomes
|
||||
website: https://www.spigotmc.org/resources/infinitehomes-unlimited-or-configurable-homes-system.128492/
|
||||
api-version: 1.21
|
||||
commands:
|
||||
sethome:
|
||||
@@ -9,9 +10,18 @@ commands:
|
||||
delhome:
|
||||
description: Delete a home with the given name.
|
||||
usage: /delhome <name>
|
||||
aliases: [deletehome]
|
||||
home:
|
||||
description: Teleport to a home with the given name.
|
||||
usage: /home <name>
|
||||
aliases: [h]
|
||||
homes:
|
||||
description: List all your homes.
|
||||
usage: /homes
|
||||
aliases: [listhomes]
|
||||
homecount:
|
||||
description: Set the global home limit (OP only).
|
||||
usage: /homecount <number>
|
||||
usage: /homecount <number>
|
||||
homecooldown:
|
||||
description: Set the global home cooldown (OP only).
|
||||
usage: /homecooldown <seconds>
|
||||
|
||||
34
src/main/resources/texts.yml
Normal file
34
src/main/resources/texts.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
# InfiniteHomes - Translation File
|
||||
# You can create translations for different languages in the translations folder
|
||||
# Name the files texts_[lang].yml (e.g., texts_de.yml for German)
|
||||
|
||||
# General messages
|
||||
no_permission: "§cYou don't have permission to use this command."
|
||||
invalid_number: "§cPlease provide a valid number."
|
||||
cooldown.range: "§cCooldown must be between -1 and 60 seconds."
|
||||
|
||||
# Command usage
|
||||
usage.sethome: "§cUsage: /sethome <name>"
|
||||
usage.delhome: "§cUsage: /delhome <name>"
|
||||
usage.home: "§cUsage: /home <name>"
|
||||
usage.homecount: "§cUsage: /homecount <number>"
|
||||
usage.homecooldown: "§cUsage: /homecooldown <seconds>"
|
||||
|
||||
# Home messages
|
||||
home.set: "§aHome '{home}' set!"
|
||||
home.deleted: "§aHome '{home}' deleted!"
|
||||
home.not_exist: "§cHome '{home}' does not exist."
|
||||
home.teleport: "§aTeleported to home '{home}'!"
|
||||
home.cooldown: "§cYou must wait {time} seconds before using /home again."
|
||||
|
||||
# Homes list messages
|
||||
homes.none: "§cYou don't have any homes set."
|
||||
homes.unlimited: "unlimited"
|
||||
homes.list.header: "§aYour homes (§e{current}§a/§e{max}§a):"
|
||||
homes.list.items: "§e{homes}"
|
||||
homes.limit.reached: "§cYou have reached the maximum number of homes ({max})."
|
||||
homes.limit.set: "§aGlobal home limit set to {max}."
|
||||
|
||||
# Cooldown messages
|
||||
cooldown.set: "§aGlobal home cooldown set to {time} seconds."
|
||||
cooldown.disabled: "§aHome cooldown disabled."
|
||||
32
src/main/resources/translations/texts_de.yml
Normal file
32
src/main/resources/translations/texts_de.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
# InfiniteHomes - Deutsche Übersetzung
|
||||
|
||||
# Allgemeine Nachrichten
|
||||
no_permission: "§cDu hast keine Berechtigung, diesen Befehl zu verwenden."
|
||||
invalid_number: "§cBitte gib eine gültige Zahl ein."
|
||||
cooldown.range: "§cCooldown muss zwischen -1 und 60 Sekunden liegen."
|
||||
|
||||
# Befehlsverwendung
|
||||
usage.sethome: "§cVerwendung: /sethome <Name>"
|
||||
usage.delhome: "§cVerwendung: /delhome <Name>"
|
||||
usage.home: "§cVerwendung: /home <Name>"
|
||||
usage.homecount: "§cVerwendung: /homecount <Zahl>"
|
||||
usage.homecooldown: "§cVerwendung: /homecooldown <Sekunden>"
|
||||
|
||||
# Home-Nachrichten
|
||||
home.set: "§aHome '{home}' gesetzt!"
|
||||
home.deleted: "§aHome '{home}' gelöscht!"
|
||||
home.not_exist: "§cHome '{home}' existiert nicht."
|
||||
home.teleport: "§aZu Home '{home}' teleportiert!"
|
||||
home.cooldown: "§cDu musst {time} Sekunden warten, bevor du /home wieder verwenden kannst."
|
||||
|
||||
# Home-Liste Nachrichten
|
||||
homes.none: "§cDu hast keine Homes gesetzt."
|
||||
homes.unlimited: "unbegrenzt"
|
||||
homes.list.header: "§aDeine Homes (§e{current}§a/§e{max}§a):"
|
||||
homes.list.items: "§e{homes}"
|
||||
homes.limit.reached: "§cDu hast die maximale Anzahl an Homes ({max}) erreicht."
|
||||
homes.limit.set: "§aGlobales Home-Limit auf {max} gesetzt."
|
||||
|
||||
# Cooldown-Nachrichten
|
||||
cooldown.set: "§aGlobaler Home-Cooldown auf {time} Sekunden gesetzt."
|
||||
cooldown.disabled: "§aHome-Cooldown deaktiviert."
|
||||
32
src/main/resources/translations/texts_en.yml
Normal file
32
src/main/resources/translations/texts_en.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
# InfiniteHomes - English Translation
|
||||
|
||||
# General messages
|
||||
no_permission: "§cYou don't have permission to use this command."
|
||||
invalid_number: "§cPlease provide a valid number."
|
||||
cooldown.range: "§cCooldown must be between -1 and 60 seconds."
|
||||
|
||||
# Command usage
|
||||
usage.sethome: "§cUsage: /sethome <name>"
|
||||
usage.delhome: "§cUsage: /delhome <name>"
|
||||
usage.home: "§cUsage: /home <name>"
|
||||
usage.homecount: "§cUsage: /homecount <number>"
|
||||
usage.homecooldown: "§cUsage: /homecooldown <seconds>"
|
||||
|
||||
# Home messages
|
||||
home.set: "§aHome '{home}' set!"
|
||||
home.deleted: "§aHome '{home}' deleted!"
|
||||
home.not_exist: "§cHome '{home}' does not exist."
|
||||
home.teleport: "§aTeleported to home '{home}'!"
|
||||
home.cooldown: "§cYou must wait {time} seconds before using /home again."
|
||||
|
||||
# Homes list messages
|
||||
homes.none: "§cYou don't have any homes set."
|
||||
homes.unlimited: "unlimited"
|
||||
homes.list.header: "§aYour homes (§e{current}§a/§e{max}§a):"
|
||||
homes.list.items: "§e{homes}"
|
||||
homes.limit.reached: "§cYou have reached the maximum number of homes ({max})."
|
||||
homes.limit.set: "§aGlobal home limit set to {max}."
|
||||
|
||||
# Cooldown messages
|
||||
cooldown.set: "§aGlobal home cooldown set to {time} seconds."
|
||||
cooldown.disabled: "§aHome cooldown disabled."
|
||||
30
src/main/resources/translations/texts_es.yml
Normal file
30
src/main/resources/translations/texts_es.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
# Mensajes generales
|
||||
no_permission: "§cNo tienes permiso para usar este comando."
|
||||
invalid_number: "§cPor favor, proporciona un número válido."
|
||||
cooldown.range: "§cEl tiempo de espera debe estar entre -1 y 60 segundos."
|
||||
|
||||
# Uso de comandos
|
||||
usage.sethome: "§cUso: /sethome <nombre>"
|
||||
usage.delhome: "§cUso: /delhome <nombre>"
|
||||
usage.home: "§cUso: /home <nombre>"
|
||||
usage.homecount: "§cUso: /homecount <número>"
|
||||
usage.homecooldown: "§cUso: /homecooldown <segundos>"
|
||||
|
||||
# Mensajes de home
|
||||
home.set: "§aHome '{home}' establecido!"
|
||||
home.deleted: "§aHome '{home}' eliminado!"
|
||||
home.not_exist: "§cHome '{home}' no existe."
|
||||
home.teleport: "§aTeletransportado a home '{home}'!"
|
||||
home.cooldown: "§cDebes esperar {time} segundos antes de usar /home de nuevo."
|
||||
|
||||
# Lista de homes
|
||||
homes.none: "§cNo tienes ningún home establecido."
|
||||
homes.unlimited: "ilimitado"
|
||||
homes.list.header: "§aTus homes (§e{current}§a/§e{max}§a):"
|
||||
homes.list.items: "§e{homes}"
|
||||
homes.limit.reached: "§cHas alcanzado el número máximo de homes ({max})."
|
||||
homes.limit.set: "§aLímite global de homes establecido a {max}."
|
||||
|
||||
# Mensajes de cooldown
|
||||
cooldown.set: "§aCooldown global de homes establecido a {time} segundos."
|
||||
cooldown.disabled: "§aCooldown de homes desactivado."
|
||||
30
src/main/resources/translations/texts_fr.yml
Normal file
30
src/main/resources/translations/texts_fr.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
# Messages générales
|
||||
no_permission: "§cVous n'avez pas la permission d'utiliser cette commande."
|
||||
invalid_number: "§cVeuillez fournir un nombre valide."
|
||||
cooldown.range: "§cLe cooldown doit être compris entre -1 et 60 secondes."
|
||||
|
||||
# Utilisation des commandes
|
||||
usage.sethome: "§cUtilisation : /sethome <nom>"
|
||||
usage.delhome: "§cUtilisation : /delhome <nom>"
|
||||
usage.home: "§cUtilisation : /home <nom>"
|
||||
usage.homecount: "§cUtilisation : /homecount <nombre>"
|
||||
usage.homecooldown: "§cUtilisation : /homecooldown <secondes>"
|
||||
|
||||
# Messages de home
|
||||
home.set: "§aHome '{home}' défini !"
|
||||
home.deleted: "§aHome '{home}' supprimé !"
|
||||
home.not_exist: "§cHome '{home}' n'existe pas."
|
||||
home.teleport: "§aTéléporté vers le home '{home}' !"
|
||||
home.cooldown: "§cVous devez attendre {time} secondes avant d'utiliser /home à nouveau."
|
||||
|
||||
# Liste des homes
|
||||
homes.none: "§cVous n'avez aucun home défini."
|
||||
homes.unlimited: "illimité"
|
||||
homes.list.header: "§aVos homes (§e{current}§a/§e{max}§a) :"
|
||||
homes.list.items: "§e{homes}"
|
||||
homes.limit.reached: "§cVous avez atteint le nombre maximum de homes ({max})."
|
||||
homes.limit.set: "§aLimite globale de homes définie à {max}."
|
||||
|
||||
# Messages de cooldown
|
||||
cooldown.set: "§aCooldown global des homes défini à {time} secondes."
|
||||
cooldown.disabled: "§aCooldown des homes désactivé."
|
||||
30
src/main/resources/translations/texts_it.yml
Normal file
30
src/main/resources/translations/texts_it.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
# Messaggi generali
|
||||
no_permission: "§cNon hai il permesso di usare questo comando."
|
||||
invalid_number: "§cPer favore, inserisci un numero valido."
|
||||
cooldown.range: "§cIl cooldown deve essere tra -1 e 60 secondi."
|
||||
|
||||
# Uso dei comandi
|
||||
usage.sethome: "§cUso: /sethome <nome>"
|
||||
usage.delhome: "§cUso: /delhome <nome>"
|
||||
usage.home: "§cUso: /home <nome>"
|
||||
usage.homecount: "§cUso: /homecount <numero>"
|
||||
usage.homecooldown: "§cUso: /homecooldown <secondi>"
|
||||
|
||||
# Messaggi di home
|
||||
home.set: "§aHome '{home}' impostata!"
|
||||
home.deleted: "§aHome '{home}' eliminata!"
|
||||
home.not_exist: "§cHome '{home}' non esiste."
|
||||
home.teleport: "§aTeletrasportato a home '{home}'!"
|
||||
home.cooldown: "§cDevi aspettare {time} secondi prima di usare di nuovo /home."
|
||||
|
||||
# Lista delle home
|
||||
homes.none: "§cNon hai nessuna home impostata."
|
||||
homes.unlimited: "illimitato"
|
||||
homes.list.header: "§aLe tue home (§e{current}§a/§e{max}§a):"
|
||||
homes.list.items: "§e{homes}"
|
||||
homes.limit.reached: "§cHai raggiunto il numero massimo di home ({max})."
|
||||
homes.limit.set: "§aLimite globale di home impostato a {max}."
|
||||
|
||||
# Messaggi di cooldown
|
||||
cooldown.set: "§aCooldown globale delle home impostato a {time} secondi."
|
||||
cooldown.disabled: "§aCooldown delle home disattivato."
|
||||
30
src/main/resources/translations/texts_nl.yml
Normal file
30
src/main/resources/translations/texts_nl.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
# Algemene berichten
|
||||
no_permission: "§cJe hebt geen toestemming om dit commando te gebruiken."
|
||||
invalid_number: "§cVoer een geldig nummer in."
|
||||
cooldown.range: "§cCooldown moet tussen -1 en 60 seconden liggen."
|
||||
|
||||
# Gebruik van commando's
|
||||
usage.sethome: "§cGebruik: /sethome <naam>"
|
||||
usage.delhome: "§cGebruik: /delhome <naam>"
|
||||
usage.home: "§cGebruik: /home <naam>"
|
||||
usage.homecount: "§cGebruik: /homecount <nummer>"
|
||||
usage.homecooldown: "§cGebruik: /homecooldown <seconden>"
|
||||
|
||||
# Home berichten
|
||||
home.set: "§aHome '{home}' ingesteld!"
|
||||
home.deleted: "§aHome '{home}' verwijderd!"
|
||||
home.not_exist: "§cHome '{home}' bestaat niet."
|
||||
home.teleport: "§aGeteleporteerd naar home '{home}'!"
|
||||
home.cooldown: "§cJe moet {time} seconden wachten voordat je /home opnieuw kunt gebruiken."
|
||||
|
||||
# Home lijst
|
||||
homes.none: "§cJe hebt geen homes ingesteld."
|
||||
homes.unlimited: "onbeperkt"
|
||||
homes.list.header: "§aJe homes (§e{current}§a/§e{max}§a):"
|
||||
homes.list.items: "§e{homes}"
|
||||
homes.limit.reached: "§cJe hebt het maximale aantal homes ({max}) bereikt."
|
||||
homes.limit.set: "§aGlobale homelimit ingesteld op {max}."
|
||||
|
||||
# Cooldown berichten
|
||||
cooldown.set: "§aGlobale home cooldown ingesteld op {time} seconden."
|
||||
cooldown.disabled: "§aHome cooldown uitgeschakeld."
|
||||
30
src/main/resources/translations/texts_pt.yml
Normal file
30
src/main/resources/translations/texts_pt.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
# Mensagens gerais
|
||||
no_permission: "§cVocê não tem permissão para usar este comando."
|
||||
invalid_number: "§cPor favor, forneça um número válido."
|
||||
cooldown.range: "§cO cooldown deve estar entre -1 e 60 segundos."
|
||||
|
||||
# Uso de comandos
|
||||
usage.sethome: "§cUso: /sethome <nome>"
|
||||
usage.delhome: "§cUso: /delhome <nome>"
|
||||
usage.home: "§cUso: /home <nome>"
|
||||
usage.homecount: "§cUso: /homecount <número>"
|
||||
usage.homecooldown: "§cUso: /homecooldown <segundos>"
|
||||
|
||||
# Mensagens de home
|
||||
home.set: "§aHome '{home}' definida!"
|
||||
home.deleted: "§aHome '{home}' deletada!"
|
||||
home.not_exist: "§cHome '{home}' não existe."
|
||||
home.teleport: "§aTeleportado para a home '{home}'!"
|
||||
home.cooldown: "§cVocê deve esperar {time} segundos antes de usar /home novamente."
|
||||
|
||||
# Lista de homes
|
||||
homes.none: "§cVocê não tem nenhuma home definida."
|
||||
homes.unlimited: "ilimitado"
|
||||
homes.list.header: "§aSuas homes (§e{current}§a/§e{max}§a):"
|
||||
homes.list.items: "§e{homes}"
|
||||
homes.limit.reached: "§cVocê atingiu o número máximo de homes ({max})."
|
||||
homes.limit.set: "§aLimite global de homes definido para {max}."
|
||||
|
||||
# Mensagens de cooldown
|
||||
cooldown.set: "§aCooldown global de homes definido para {time} segundos."
|
||||
cooldown.disabled: "§aCooldown de homes desativado."
|
||||
30
src/main/resources/translations/texts_ru.yml
Normal file
30
src/main/resources/translations/texts_ru.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
# Общие сообщения
|
||||
no_permission: "§cУ вас нет разрешения на использование этой команды."
|
||||
invalid_number: "§cПожалуйста, укажите корректное число."
|
||||
cooldown.range: "§cВремя восстановления должно быть от -1 до 60 секунд."
|
||||
|
||||
# Использование команд
|
||||
usage.sethome: "§cИспользование: /sethome <имя>"
|
||||
usage.delhome: "§cИспользование: /delhome <имя>"
|
||||
usage.home: "§cИспользование: /home <имя>"
|
||||
usage.homecount: "§cИспользование: /homecount <число>"
|
||||
usage.homecooldown: "§cИспользование: /homecooldown <секунды>"
|
||||
|
||||
# Сообщения о доме
|
||||
home.set: "§aДом '{home}' установлен!"
|
||||
home.deleted: "§aДом '{home}' удалён!"
|
||||
home.not_exist: "§cДом '{home}' не существует."
|
||||
home.teleport: "§aТелепортировано к дому '{home}'!"
|
||||
home.cooldown: "§cВы должны подождать {time} секунд перед повторным использованием /home."
|
||||
|
||||
# Список домов
|
||||
homes.none: "§cУ вас нет установленных домов."
|
||||
homes.unlimited: "безлимитно"
|
||||
homes.list.header: "§aВаши дома (§e{current}§a/§e{max}§a):"
|
||||
homes.list.items: "§e{homes}"
|
||||
homes.limit.reached: "§cВы достигли максимального числа домов ({max})."
|
||||
homes.limit.set: "§aГлобальный лимит домов установлен на {max}."
|
||||
|
||||
# Сообщения о перезарядке
|
||||
cooldown.set: "§aГлобальный таймер восстановления домов установлен на {time} секунд."
|
||||
cooldown.disabled: "§aПерезарядка домов отключена."
|
||||
BIN
web/icon.ico
Normal file
BIN
web/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
518
web/index.html
Normal file
518
web/index.html
Normal file
@@ -0,0 +1,518 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" href=icon.ico>
|
||||
<title>InfiniteHomes - Minecraft Plugin</title>
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #4CAF50;
|
||||
--secondary-color: #2E7D32;
|
||||
--accent-color: #8BC34A;
|
||||
--dark-color: #1B5E20;
|
||||
--light-color: #F1F8E9;
|
||||
--text-dark: #212121;
|
||||
--text-light: #757575;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f5f5f5;
|
||||
color: var(--text-dark);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
header {
|
||||
background: linear-gradient(135deg, var(--primary-color), var(--dark-color));
|
||||
color: white;
|
||||
padding: 1rem 0;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
nav {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 1.8rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.nav-links li {
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.hero {
|
||||
background: url('https://via.placeholder.com/1500x500') no-repeat center center/cover;
|
||||
color: white;
|
||||
padding: 4rem 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.hero p {
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 2rem;
|
||||
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
background: var(--accent-color);
|
||||
color: white;
|
||||
padding: 0.8rem 1.5rem;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: var(--secondary-color);
|
||||
}
|
||||
|
||||
section {
|
||||
padding: 4rem 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
text-align: center;
|
||||
margin-bottom: 3rem;
|
||||
color: var(--dark-color);
|
||||
}
|
||||
|
||||
.features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 2rem;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.feature-card:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
.feature-card h3 {
|
||||
color: var(--primary-color);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.commands {
|
||||
background-color: var(--light-color);
|
||||
}
|
||||
|
||||
.command-list {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 2rem;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.command-item {
|
||||
margin-bottom: 1.5rem;
|
||||
padding-bottom: 1.5rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.command-item:last-child {
|
||||
border-bottom: none;
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.command-name {
|
||||
font-weight: bold;
|
||||
color: var(--secondary-color);
|
||||
}
|
||||
|
||||
.command-desc {
|
||||
margin-top: 0.5rem;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
.download-platforms {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 2rem;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.platform-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 1.5rem;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.platform-card:hover {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
|
||||
.platform-logo {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.screenshot-gallery {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.screenshot-item {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.screenshot-item img {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.screenshot-item:hover img {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.faq-item {
|
||||
margin-bottom: 1.5rem;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.faq-question {
|
||||
font-weight: bold;
|
||||
color: var(--primary-color);
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
footer {
|
||||
background: var(--dark-color);
|
||||
color: white;
|
||||
padding: 2rem 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 2rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.footer-links {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.footer-links li {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.footer-links a {
|
||||
color: var(--light-color);
|
||||
text-decoration: none;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
|
||||
.footer-links a:hover {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
|
||||
.copyright {
|
||||
margin-top: 2rem;
|
||||
padding-top: 1rem;
|
||||
border-top: 1px solid rgba(255,255,255,0.1);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-links {
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.nav-links li {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
.hero h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container">
|
||||
<nav>
|
||||
<div class="logo">InfiniteHomes</div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="#features">Features</a></li>
|
||||
<li><a href="#commands">Commands</a></li>
|
||||
<li><a href="#download">Download</a></li>
|
||||
<li><a href="#screenshots">Screenshots</a></li>
|
||||
<li><a href="#faq">FAQ</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="hero">
|
||||
<div class="container">
|
||||
<div class="hero-content">
|
||||
<h1>InfiniteHomes Minecraft Plugin</h1>
|
||||
<p>Unbegrenzte oder kontrollierbare Homes für deine Spieler! Leichtgewichtig, einfach zu bedienen und perfekt für jeden Survival- oder Freebuild-Server.</p>
|
||||
<a href="#download" class="btn">Jetzt herunterladen</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="features">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Plugin-Features</h2>
|
||||
<div class="features">
|
||||
<div class="feature-card">
|
||||
<h3>Unbegrenzte Homes</h3>
|
||||
<p>Spieler können standardmäßig so viele Homes setzen, wie sie möchten - oder du als Serverbetreiber legst fest, wie viele Homes erlaubt sind.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3>Einfache Konfiguration</h3>
|
||||
<p>Keine Datenbank erforderlich! Einfach installieren und loslegen. Perfekt für kleine und große Server.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3>Multilingual Support</h3>
|
||||
<p>Unterstützung für mehrere Sprachen durch benutzerdefinierte Textdateien. Einfache Anpassung aller Plugin-Nachrichten.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3>Cooldown-System</h3>
|
||||
<p>Konfigurierbare Cooldowns zwischen Teleportationen, um Missbrauch zu verhindern.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3>Leistungsoptimiert</h3>
|
||||
<p>Leichtgewichtiges Plugin, das keine Serverressourcen überlastet und selbst auf großen Servern reibungslos läuft.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3>Permissions</h3>
|
||||
<p>Vollständige Integration mit Permission-Systemen, um differentierte Zugriffsrechte zu verwalten.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="commands" class="commands">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Befehle</h2>
|
||||
<div class="command-list">
|
||||
<div class="command-item">
|
||||
<div class="command-name">/sethome <name></div>
|
||||
<div class="command-desc">Setzt ein Home mit einem benutzerdefinierten Namen</div>
|
||||
</div>
|
||||
<div class="command-item">
|
||||
<div class="command-name">/home <name></div>
|
||||
<div class="command-desc">Teleportiert dich zu deinem Home</div>
|
||||
</div>
|
||||
<div class="command-item">
|
||||
<div class="command-name">/delhome <name></div>
|
||||
<div class="command-desc">Löscht ein Home</div>
|
||||
</div>
|
||||
<div class="command-item">
|
||||
<div class="command-name">/homes</div>
|
||||
<div class="command-desc">Listet alle Homes des aktuellen Benutzers auf</div>
|
||||
</div>
|
||||
<div class="command-item">
|
||||
<div class="command-name">/homecooldown <number/-1></div>
|
||||
<div class="command-desc">Setzt den Cooldown zwischen Teleports (OP only, -1 = kein Cooldown)</div>
|
||||
</div>
|
||||
<div class="command-item">
|
||||
<div class="command-name">/homecount <number/-1></div>
|
||||
<div class="command-desc">Setzt die maximale Anzahl von Homes (OP only, -1 = unbegrenzt)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="download">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Download & Links</h2>
|
||||
<p style="text-align: center; margin-bottom: 2rem;">Lade das InfiniteHomes Plugin von diesen Plattformen herunter:</p>
|
||||
|
||||
<div class="download-platforms">
|
||||
<div class="platform-card">
|
||||
<div class="platform-logo">🔗</div>
|
||||
<h3>SpigotMC</h3>
|
||||
<p>Download für Spigot und Bukkit Server</p>
|
||||
<a href="https://www.spigotmc.org/resources/infinitehomes-unlimited-or-configurable-homes-system.128492/" class="btn">Zum Download</a>
|
||||
</div>
|
||||
<div class="platform-card">
|
||||
<div class="platform-logo">🔗</div>
|
||||
<h3>Modrinth</h3>
|
||||
<p>Download auf Modrinth</p>
|
||||
<a href="https://modrinth.com/plugin/infinitehomes" class="btn">Zum Download</a>
|
||||
</div>
|
||||
<div class="platform-card">
|
||||
<div class="platform-logo">🔗</div>
|
||||
<h3>GitHub</h3>
|
||||
<p>Quellcode auf GitHub</p>
|
||||
<a href="https://github.com/deutschich/InfiniteHomes" class="btn">Zum Repository</a>
|
||||
</div>
|
||||
<div class="platform-card">
|
||||
<div class="platform-logo">🔗</div>
|
||||
<h3>PaperMC Hangar</h3>
|
||||
<p>Download auf PaperMC Hangar</p>
|
||||
<a href="https://hangar.papermc.io/user404/InfiniteHomes" class="btn">Zum Download</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 3rem; background: white; padding: 2rem; border-radius: 8px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);">
|
||||
<h3 style="color: var(--primary-color); margin-bottom: 1rem;">Installationsanleitung</h3>
|
||||
<ol style="padding-left: 1.5rem;">
|
||||
<li style="margin-bottom: 0.5rem;">Lade die neueste Version des Plugins von einer der Plattformen herunter</li>
|
||||
<li style="margin-bottom: 0.5rem;">Füge die JAR-Datei in den Plugins-Ordner deines Minecraft-Servers ein</li>
|
||||
<li style="margin-bottom: 0.5rem;">Starte den Server neu, um das Plugin zu laden</li>
|
||||
<li style="margin-bottom: 0.5rem;">Passe die Konfiguration in der generierten Config-Datei nach Bedarf an</li>
|
||||
<li>Füge benutzerdefinierte Übersetzungen im /plugins/Infinitehomes/translations/ Ordner hinzu</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="screenshots">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Screenshots</h2>
|
||||
<p style="text-align: center; margin-bottom: 2rem;"></p>
|
||||
|
||||
<div class="screenshot-gallery">
|
||||
<div class="screenshot-item">
|
||||
<img src="https://cdn.modrinth.com/data/XMQtfIwI/images/27341dc3d536c51f337d813445954fce1c953119.png" alt="InfiniteHomes Screenshot 1">
|
||||
</div>
|
||||
<div class="screenshot-item">
|
||||
<img src="https://cdn.modrinth.com/data/XMQtfIwI/images/01d647600635f6ab25004a8e8d400634552945ef.png" alt="InfiniteHomes Screenshot 2">
|
||||
</div>
|
||||
<div class="screenshot-item">
|
||||
<img src="https://cdn.modrinth.com/data/XMQtfIwI/images/b04c4ac935befe93bf8d4f5cc15d903764976ddf.png" alt="InfiniteHomes Screenshot 3">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="faq" class="commands">
|
||||
<div class="container">
|
||||
<h2 class="section-title">Häufig gestellte Fragen</h2>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question">Wie installiere ich das InfiniteHomes Plugin?</div>
|
||||
<div class="faq-answer">Lade die JAR-Datei herunter, lege sie in den Plugins-Ordner deines Servers und starte den Server neu. Das Plugin generiert automatisch eine Config-Datei, die du nach deinen Wünschen anpassen kannst.</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question">Unterstützt das Plugin mehrere Sprachen?</div>
|
||||
<div class="faq-answer">Ja, das Plugin unterstützt mehrere Sprachen. Du kannst benutzerdefinierte Übersetzungen im /plugins/Infinitehomes/translations/ Ordner hinzufügen, z.B. texts_de.yml für Deutsch.</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question">Kann ich die maximale Anzahl von Homes pro Spieler begrenzen?</div>
|
||||
<div class="faq-answer">Ja, als Serveroperator kannst du mit /homecount <number> die maximale Anzahl von Homes festlegen. Verwende -1 für unbegrenzte Homes.</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question">Ist eine Datenbank für dieses Plugin erforderlich?</div>
|
||||
<div class="faq-answer">Nein, das Plugin ist leichtgewichtig und benötigt keine Datenbank. Alle Daten werden in lokalen Dateien gespeichert.</div>
|
||||
</div>
|
||||
|
||||
<div class="faq-item">
|
||||
<div class="faq-question">Kann ich Cooldowns für Teleports festlegen?</div>
|
||||
<div class="faq-answer">Ja, du kannst mit /homecooldown <seconds> einen Cooldown zwischen Teleportationen festlegen. Verwende -1, um Cooldowns zu deaktivieren.</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="footer-content">
|
||||
<div>
|
||||
<h3>InfiniteHomes</h3>
|
||||
<p>Ein leistungsstarkes Home-Plugin für Minecraft-Server.</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Links</h3>
|
||||
<ul class="footer-links">
|
||||
<li><a href="#features">Features</a></li>
|
||||
<li><a href="#commands">Commands</a></li>
|
||||
<li><a href="#download">Download</a></li>
|
||||
<li><a href="#screenshots">Screenshots</a></li>
|
||||
<li><a href="#faq">FAQ</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3>Externe Links</h3>
|
||||
<ul class="footer-links">
|
||||
<li><a href="https://www.spigotmc.org/resources/infinitehomes-unlimited-or-configurable-homes-system.128492/">SpigotMC</a></li>
|
||||
<li><a href="https://modrinth.com/plugin/infinitehomes">Modrinth</a></li>
|
||||
<li><a href="https://github.com/deutschich/InfiniteHomes">GitHub</a></li>
|
||||
<li><a href="https://hangar.papermc.io/user404/InfiniteHomes">PaperMC Hangar</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
<p>© 2025 InfiniteHomes Plugin. Alle Rechte vorbehalten.</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user