This commit is contained in:
55
.gitea/workflows/maven_build.yaml
Normal file
55
.gitea/workflows/maven_build.yaml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
name: Maven Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main, master, dev ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main, master ]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up JDK 21
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: '21'
|
||||||
|
cache: 'maven'
|
||||||
|
|
||||||
|
- name: Install Maven
|
||||||
|
run: |
|
||||||
|
if ! command -v mvn &> /dev/null; then
|
||||||
|
echo "Maven not found, installing..."
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y maven
|
||||||
|
fi
|
||||||
|
mvn --version
|
||||||
|
|
||||||
|
- name: Debug Info
|
||||||
|
run: |
|
||||||
|
echo "Current workspace directory: $GITHUB_WORKSPACE"
|
||||||
|
echo "Current directory: $(pwd)"
|
||||||
|
echo "Project structure:"
|
||||||
|
find . -type f -name "*.kt" | sort
|
||||||
|
find . -type f -name "pom.xml"
|
||||||
|
echo "Maven version: $(mvn --version)"
|
||||||
|
|
||||||
|
- name: Build easyadmin (easyadmin)
|
||||||
|
run: |
|
||||||
|
echo "Building easyadmin"
|
||||||
|
echo "Current directory: $(pwd)"
|
||||||
|
# Run Maven build directly using the POM file path
|
||||||
|
mvn -B clean package -f "$GITHUB_WORKSPACE/pom.xml" -Dmaven.compiler.failOnError=true
|
||||||
|
|
||||||
|
- name: Upload easyadmin artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: easyadmin
|
||||||
|
path: target/easyadmin-*.jar
|
||||||
|
if-no-files-found: error
|
||||||
113
.gitignore
vendored
Normal file
113
.gitignore
vendored
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
# User-specific stuff
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
target/
|
||||||
|
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
.mvn/wrapper/maven-wrapper.jar
|
||||||
|
.flattened-pom.xml
|
||||||
|
|
||||||
|
# Common working directory
|
||||||
|
run/
|
||||||
10
build.sh
Executable file
10
build.sh
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Direct build script for Maven project
|
||||||
|
|
||||||
|
echo "Current directory: $(pwd)"
|
||||||
|
echo "Building project with Maven..."
|
||||||
|
|
||||||
|
# Run Maven build using the exact pom.xml location
|
||||||
|
mvn clean package -f "$(pwd)/pom.xml"
|
||||||
|
|
||||||
|
echo "Build complete. JAR file should be in target/ directory."
|
||||||
87
pom.xml
Normal file
87
pom.xml
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>org.easyadmin</groupId>
|
||||||
|
<artifactId>easyadmin</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>easyadmin</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>21</java.version>
|
||||||
|
<kotlin.version>2.2.0-Beta2</kotlin.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<defaultGoal>clean package</defaultGoal>
|
||||||
|
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<jvmTarget>${java.version}</jvmTarget>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>3.5.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>papermc-repo</id>
|
||||||
|
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>sonatype</id>
|
||||||
|
<url>https://oss.sonatype.org/content/groups/public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.papermc.paper</groupId>
|
||||||
|
<artifactId>paper-api</artifactId>
|
||||||
|
<version>1.21.5-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
274
pommer.py
Normal file
274
pommer.py
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
import argparse
|
||||||
|
import glob
|
||||||
|
|
||||||
|
|
||||||
|
def parse_pom_xml(pom_path):
|
||||||
|
"""
|
||||||
|
Parse a pom.xml file and extract relevant information
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
print(f"Parsing POM file: {pom_path}")
|
||||||
|
|
||||||
|
# Register the default namespace
|
||||||
|
ET.register_namespace('', "http://maven.apache.org/POM/4.0.0")
|
||||||
|
|
||||||
|
# Parse the XML file
|
||||||
|
tree = ET.parse(pom_path)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
# Define namespace for easier XPath queries
|
||||||
|
ns = {'mvn': "http://maven.apache.org/POM/4.0.0"}
|
||||||
|
|
||||||
|
# Extract project info
|
||||||
|
artifact_id = root.find('./mvn:artifactId', ns).text
|
||||||
|
group_id = root.find('./mvn:groupId', ns).text if root.find('./mvn:groupId', ns) is not None else "unknown"
|
||||||
|
version = root.find('./mvn:version', ns).text if root.find('./mvn:version', ns) is not None else "unknown"
|
||||||
|
name = root.find('./mvn:name', ns).text if root.find('./mvn:name', ns) is not None else artifact_id
|
||||||
|
|
||||||
|
# Extract Java version
|
||||||
|
java_version_elem = root.find('./mvn:properties/mvn:java.version', ns)
|
||||||
|
java_version = java_version_elem.text if java_version_elem is not None else "17" # Default to Java 17 if not specified
|
||||||
|
|
||||||
|
# Extract packaging type (default to jar if not specified)
|
||||||
|
packaging = root.find('./mvn:packaging', ns)
|
||||||
|
packaging = packaging.text if packaging is not None else "jar"
|
||||||
|
|
||||||
|
# Check if Kotlin is used
|
||||||
|
kotlin_version_elem = root.find('./mvn:properties/mvn:kotlin.version', ns)
|
||||||
|
kotlin_version = kotlin_version_elem.text if kotlin_version_elem is not None else None
|
||||||
|
|
||||||
|
# Check for Kotlin plugin or dependency
|
||||||
|
kotlin_plugin = None
|
||||||
|
kotlin_dep = None
|
||||||
|
|
||||||
|
# Check for Kotlin plugin
|
||||||
|
plugins = root.findall('.//mvn:plugin', ns)
|
||||||
|
for plugin in plugins:
|
||||||
|
plugin_group = plugin.find('./mvn:groupId', ns)
|
||||||
|
if plugin_group is not None and plugin_group.text == 'org.jetbrains.kotlin':
|
||||||
|
kotlin_plugin = plugin
|
||||||
|
break
|
||||||
|
|
||||||
|
# Check for Kotlin dependency
|
||||||
|
deps = root.findall('.//mvn:dependency', ns)
|
||||||
|
for dep in deps:
|
||||||
|
dep_group = dep.find('./mvn:groupId', ns)
|
||||||
|
dep_artifact = dep.find('./mvn:artifactId', ns)
|
||||||
|
if (dep_group is not None and dep_group.text == 'org.jetbrains.kotlin' and
|
||||||
|
dep_artifact is not None and 'kotlin-stdlib' in dep_artifact.text):
|
||||||
|
kotlin_dep = dep
|
||||||
|
break
|
||||||
|
|
||||||
|
# Determine if this is a Kotlin project
|
||||||
|
is_kotlin = kotlin_version is not None or kotlin_plugin is not None or kotlin_dep is not None
|
||||||
|
|
||||||
|
# Check for source directories
|
||||||
|
source_dir = None
|
||||||
|
source_dirs = root.findall('.//mvn:sourceDirectory', ns)
|
||||||
|
if source_dirs:
|
||||||
|
source_dir = source_dirs[0].text
|
||||||
|
|
||||||
|
# Check for default goal (to use the same command as IntelliJ)
|
||||||
|
default_goal = None
|
||||||
|
default_goal_elem = root.find('./mvn:build/mvn:defaultGoal', ns)
|
||||||
|
if default_goal_elem is not None:
|
||||||
|
default_goal = default_goal_elem.text
|
||||||
|
|
||||||
|
return {
|
||||||
|
"artifact_id": artifact_id,
|
||||||
|
"group_id": group_id,
|
||||||
|
"version": version,
|
||||||
|
"name": name,
|
||||||
|
"java_version": java_version,
|
||||||
|
"packaging": packaging,
|
||||||
|
"is_kotlin": is_kotlin,
|
||||||
|
"kotlin_version": kotlin_version,
|
||||||
|
"source_dir": source_dir,
|
||||||
|
"default_goal": default_goal,
|
||||||
|
"pom_path": pom_path
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error parsing {pom_path}: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def generate_gitea_workflow(pom_infos):
|
||||||
|
"""
|
||||||
|
Generate a Gitea workflow YAML file based on multiple POM information
|
||||||
|
"""
|
||||||
|
if not pom_infos:
|
||||||
|
print("No valid POM files found")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Get the highest Java version required
|
||||||
|
java_version = max([info["java_version"] for info in pom_infos])
|
||||||
|
|
||||||
|
# Check if any project uses Kotlin
|
||||||
|
uses_kotlin = any(info["is_kotlin"] for info in pom_infos)
|
||||||
|
|
||||||
|
# Kotlin version (if any)
|
||||||
|
kotlin_version = None
|
||||||
|
for info in pom_infos:
|
||||||
|
if info["kotlin_version"]:
|
||||||
|
kotlin_version = info["kotlin_version"]
|
||||||
|
break
|
||||||
|
|
||||||
|
# Construct the workflow content
|
||||||
|
workflow_content = f"""name: Maven Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main, master, dev ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main, master ]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up JDK {java_version}
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: '{java_version}'
|
||||||
|
cache: 'maven'
|
||||||
|
|
||||||
|
- name: Install Maven
|
||||||
|
run: |
|
||||||
|
if ! command -v mvn &> /dev/null; then
|
||||||
|
echo "Maven not found, installing..."
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y maven
|
||||||
|
fi
|
||||||
|
mvn --version
|
||||||
|
|
||||||
|
- name: Debug Info
|
||||||
|
run: |
|
||||||
|
echo "Current workspace directory: $GITHUB_WORKSPACE"
|
||||||
|
echo "Current directory: $(pwd)"
|
||||||
|
echo "Project structure:"
|
||||||
|
find . -type f -name "*.kt" | sort
|
||||||
|
find . -type f -name "pom.xml"
|
||||||
|
echo "Maven version: $(mvn --version)"
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Add individual build steps for each POM
|
||||||
|
for i, info in enumerate(pom_infos):
|
||||||
|
# Determine the Maven command to use (same as the default goal if specified)
|
||||||
|
maven_command = "clean package"
|
||||||
|
if info["default_goal"]:
|
||||||
|
maven_command = info["default_goal"]
|
||||||
|
|
||||||
|
workflow_content += f"""
|
||||||
|
- name: Build {info["name"]} ({info["artifact_id"]})
|
||||||
|
run: |
|
||||||
|
echo "Building {info["artifact_id"]}"
|
||||||
|
echo "Current directory: $(pwd)"
|
||||||
|
# Run Maven build directly using the POM file path
|
||||||
|
mvn -B {maven_command} -f "$GITHUB_WORKSPACE/pom.xml" -Dmaven.compiler.failOnError=true
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Add artifact upload step
|
||||||
|
workflow_content += f"""
|
||||||
|
- name: Upload {info["artifact_id"]} artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: {info["artifact_id"]}
|
||||||
|
path: target/{info['artifact_id']}-*.jar
|
||||||
|
if-no-files-found: error
|
||||||
|
"""
|
||||||
|
|
||||||
|
return workflow_content
|
||||||
|
|
||||||
|
|
||||||
|
def find_pom_files(base_dir="."):
|
||||||
|
"""Find all pom.xml files in the given directory and subdirectories"""
|
||||||
|
return glob.glob(f"{base_dir}/**/pom.xml", recursive=True)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description='Generate Gitea workflow for Maven/Kotlin projects')
|
||||||
|
parser.add_argument('--dir', '-d', default='.', help='Base directory to search for pom.xml files')
|
||||||
|
parser.add_argument('--specific-pom', '-p', help='Path to a specific pom.xml file to process')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
pom_files = []
|
||||||
|
if args.specific_pom:
|
||||||
|
pom_files = [args.specific_pom]
|
||||||
|
else:
|
||||||
|
pom_files = find_pom_files(args.dir)
|
||||||
|
|
||||||
|
if not pom_files:
|
||||||
|
print(f"No pom.xml files found in {args.dir}")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"Found {len(pom_files)} pom.xml files")
|
||||||
|
|
||||||
|
# Parse all POM files
|
||||||
|
pom_infos = []
|
||||||
|
for pom_file in pom_files:
|
||||||
|
info = parse_pom_xml(pom_file)
|
||||||
|
if info:
|
||||||
|
pom_infos.append(info)
|
||||||
|
|
||||||
|
if not pom_infos:
|
||||||
|
print("No valid POM files could be parsed")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Generate the workflow content
|
||||||
|
workflow_content = generate_gitea_workflow(pom_infos)
|
||||||
|
|
||||||
|
if not workflow_content:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Create the .gitea/workflows directory if it doesn't exist
|
||||||
|
workflow_dir = Path(".gitea/workflows")
|
||||||
|
workflow_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
# Write the workflow file
|
||||||
|
workflow_file = workflow_dir / "maven_build.yaml"
|
||||||
|
with open(workflow_file, "w") as f:
|
||||||
|
f.write(workflow_content)
|
||||||
|
|
||||||
|
print(f"Gitea workflow generated at: {workflow_file}")
|
||||||
|
print(f"This workflow will build {len(pom_infos)} Maven projects")
|
||||||
|
|
||||||
|
# Print summary of detected projects
|
||||||
|
print("\nDetected projects:")
|
||||||
|
for info in pom_infos:
|
||||||
|
kotlin_info = "with Kotlin" if info["is_kotlin"] else "Java only"
|
||||||
|
build_command = info["default_goal"] if info["default_goal"] else "clean package"
|
||||||
|
print(
|
||||||
|
f"- {info['name']} ({info['artifact_id']}): {kotlin_info}, Java {info['java_version']}, build: {build_command}")
|
||||||
|
|
||||||
|
# Create a simple direct build script as fallback
|
||||||
|
with open("build.sh", "w") as f:
|
||||||
|
f.write("""#!/bin/bash
|
||||||
|
# Direct build script for Maven project
|
||||||
|
|
||||||
|
echo "Current directory: $(pwd)"
|
||||||
|
echo "Building project with Maven..."
|
||||||
|
|
||||||
|
# Run Maven build using the exact pom.xml location
|
||||||
|
mvn clean package -f "$(pwd)/pom.xml"
|
||||||
|
|
||||||
|
echo "Build complete. JAR file should be in target/ directory."
|
||||||
|
""")
|
||||||
|
|
||||||
|
# Make it executable
|
||||||
|
os.chmod("build.sh", 0o755)
|
||||||
|
print(f"Simple build script generated at: build.sh")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
286
src/main/kotlin/org/easyadmin/easyadmin/Easyadmin.kt
Normal file
286
src/main/kotlin/org/easyadmin/easyadmin/Easyadmin.kt
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
@file:Suppress("DEPRECATION")
|
||||||
|
|
||||||
|
package org.easyadmin.easyadmin
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.ChatColor
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.command.Command
|
||||||
|
import org.bukkit.command.CommandSender
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta // Is very much needed but here is a error!
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin
|
||||||
|
|
||||||
|
class Easyadmin : JavaPlugin(), Listener {
|
||||||
|
private val menuName = "${ChatColor.DARK_PURPLE}${ChatColor.BOLD}EasyAdmin"
|
||||||
|
|
||||||
|
override fun onEnable() {
|
||||||
|
// Register events and commands
|
||||||
|
server.pluginManager.registerEvents(this, this)
|
||||||
|
logger.info("${ChatColor.GREEN}EasyAdmin plugin enabled!")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDisable() {
|
||||||
|
logger.info("${ChatColor.RED}EasyAdmin plugin disabled!")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
|
||||||
|
if (sender !is Player) {
|
||||||
|
sender.sendMessage("${ChatColor.RED}This command can only be used by players!")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.name.equals("easyadmin", ignoreCase = true)) {
|
||||||
|
if (!sender.hasPermission("easyadmin.use")) {
|
||||||
|
sender.sendMessage("${ChatColor.RED}You don't have permission to use this command!")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
openAdminMenu(sender)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openAdminMenu(player: Player) {
|
||||||
|
val inventory = Bukkit.createInventory(null, 27, menuName)
|
||||||
|
|
||||||
|
// Time control
|
||||||
|
inventory.setItem(10, createGuiItem(Material.CLOCK, "${ChatColor.YELLOW}Time Control",
|
||||||
|
"${ChatColor.GRAY}Click to cycle time"))
|
||||||
|
|
||||||
|
// Weather control
|
||||||
|
inventory.setItem(11, createGuiItem(Material.WATER_BUCKET, "${ChatColor.BLUE}Weather Control",
|
||||||
|
"${ChatColor.GRAY}Click to cycle weather"))
|
||||||
|
|
||||||
|
// Kick all players
|
||||||
|
inventory.setItem(12, createGuiItem(Material.IRON_BOOTS, "${ChatColor.RED}Kick All",
|
||||||
|
"${ChatColor.GRAY}Kick all non-admin players"))
|
||||||
|
|
||||||
|
// Player management
|
||||||
|
inventory.setItem(13, createGuiItem(Material.PLAYER_HEAD, "${ChatColor.GREEN}Player Management",
|
||||||
|
"${ChatColor.GRAY}Manage online players"))
|
||||||
|
|
||||||
|
// World management
|
||||||
|
inventory.setItem(14, createGuiItem(Material.GRASS_BLOCK, "${ChatColor.GOLD}World Management",
|
||||||
|
"${ChatColor.GRAY}Manage worlds"))
|
||||||
|
|
||||||
|
// Server properties
|
||||||
|
inventory.setItem(15, createGuiItem(Material.COMMAND_BLOCK, "${ChatColor.LIGHT_PURPLE}Server Settings",
|
||||||
|
"${ChatColor.GRAY}View and modify server properties"))
|
||||||
|
|
||||||
|
// Plugin management
|
||||||
|
inventory.setItem(16, createGuiItem(Material.BOOK, "${ChatColor.AQUA}Plugin Management",
|
||||||
|
"${ChatColor.GRAY}Enable/disable plugins"))
|
||||||
|
|
||||||
|
player.openInventory(inventory)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createGuiItem(material: Material, name: String, vararg lore: String): ItemStack {
|
||||||
|
val item = ItemStack(material, 1)
|
||||||
|
val meta = item.itemMeta!!
|
||||||
|
|
||||||
|
meta.setDisplayName(name)
|
||||||
|
|
||||||
|
if (lore.isNotEmpty()) {
|
||||||
|
meta.lore = lore.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
item.itemMeta = meta
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun onInventoryClick(event: InventoryClickEvent) {
|
||||||
|
if (event.view.title != menuName) return
|
||||||
|
|
||||||
|
event.isCancelled = true
|
||||||
|
|
||||||
|
val player = event.whoClicked as Player
|
||||||
|
if (!player.hasPermission("easyadmin.use")) return
|
||||||
|
|
||||||
|
when (event.slot) {
|
||||||
|
10 -> handleTimeControl(player)
|
||||||
|
11 -> handleWeatherControl(player)
|
||||||
|
12 -> handleKickAll(player)
|
||||||
|
13 -> openPlayerManagement(player)
|
||||||
|
14 -> openWorldManagement(player)
|
||||||
|
15 -> openServerSettings(player)
|
||||||
|
16 -> openPluginManagement(player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleTimeControl(player: Player) {
|
||||||
|
val world = player.world
|
||||||
|
when (world.time) {
|
||||||
|
in 0..6000 -> world.time = 6000 // Set to noon
|
||||||
|
in 6001..12000 -> world.time = 12000 // Set to sunset
|
||||||
|
in 12001..18000 -> world.time = 18000 // Set to midnight
|
||||||
|
else -> world.time = 0 // Set to sunrise
|
||||||
|
}
|
||||||
|
player.sendMessage("${ChatColor.GREEN}Time changed in ${world.name}!")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleWeatherControl(player: Player) {
|
||||||
|
val world = player.world
|
||||||
|
when {
|
||||||
|
world.isThundering -> {
|
||||||
|
world.setStorm(false)
|
||||||
|
world.isThundering = false
|
||||||
|
player.sendMessage("${ChatColor.GREEN}Weather set to clear in ${world.name}!")
|
||||||
|
}
|
||||||
|
world.hasStorm() -> {
|
||||||
|
world.setStorm(true)
|
||||||
|
world.isThundering = true
|
||||||
|
player.sendMessage("${ChatColor.GREEN}Weather set to thunderstorm in ${world.name}!")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
world.setStorm(true)
|
||||||
|
player.sendMessage("${ChatColor.GREEN}Weather set to rain in ${world.name}!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleKickAll(player: Player) {
|
||||||
|
val kickMessage = "${ChatColor.RED}Server is being maintained by an administrator."
|
||||||
|
var kickCount = 0
|
||||||
|
|
||||||
|
for (onlinePlayer in Bukkit.getOnlinePlayers()) {
|
||||||
|
if (!onlinePlayer.hasPermission("easyadmin.exempt") && onlinePlayer != player) {
|
||||||
|
onlinePlayer.kickPlayer(kickMessage)
|
||||||
|
kickCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
player.sendMessage("${ChatColor.GREEN}Kicked $kickCount players from the server.")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openPlayerManagement(player: Player) {
|
||||||
|
val inventory = Bukkit.createInventory(null, 54, "${ChatColor.GREEN}${ChatColor.BOLD}Player Management")
|
||||||
|
|
||||||
|
var slot = 0
|
||||||
|
for (onlinePlayer in Bukkit.getOnlinePlayers()) {
|
||||||
|
if (slot >= 54) break
|
||||||
|
|
||||||
|
val playerHead = ItemStack(Material.PLAYER_HEAD, 1)
|
||||||
|
val meta = playerHead.itemMeta!!
|
||||||
|
meta.setDisplayName("${ChatColor.YELLOW}${onlinePlayer.name}")
|
||||||
|
|
||||||
|
val lore = mutableListOf<String>()
|
||||||
|
lore.add("${ChatColor.GRAY}Health: ${ChatColor.RED}${onlinePlayer.health}")
|
||||||
|
lore.add("${ChatColor.GRAY}Gamemode: ${ChatColor.GOLD}${onlinePlayer.gameMode}")
|
||||||
|
lore.add("${ChatColor.GRAY}World: ${ChatColor.GREEN}${onlinePlayer.world.name}")
|
||||||
|
lore.add("")
|
||||||
|
lore.add("${ChatColor.GREEN}Left-click: ${ChatColor.WHITE}Teleport to player")
|
||||||
|
lore.add("${ChatColor.RED}Right-click: ${ChatColor.WHITE}More options")
|
||||||
|
|
||||||
|
meta.lore = lore
|
||||||
|
playerHead.itemMeta = meta
|
||||||
|
|
||||||
|
inventory.setItem(slot, playerHead)
|
||||||
|
slot++
|
||||||
|
}
|
||||||
|
|
||||||
|
player.openInventory(inventory)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openWorldManagement(player: Player) {
|
||||||
|
val inventory = Bukkit.createInventory(null, 27, "${ChatColor.GOLD}${ChatColor.BOLD}World Management")
|
||||||
|
|
||||||
|
var slot = 0
|
||||||
|
for (world in Bukkit.getWorlds()) {
|
||||||
|
if (slot >= 27) break
|
||||||
|
|
||||||
|
val worldIcon = ItemStack(Material.GRASS_BLOCK, 1)
|
||||||
|
if (world.environment == org.bukkit.World.Environment.NETHER) {
|
||||||
|
worldIcon.type = Material.NETHERRACK
|
||||||
|
} else if (world.environment == org.bukkit.World.Environment.THE_END) {
|
||||||
|
worldIcon.type = Material.END_STONE
|
||||||
|
}
|
||||||
|
|
||||||
|
val meta = worldIcon.itemMeta!!
|
||||||
|
meta.setDisplayName("${ChatColor.YELLOW}${world.name}")
|
||||||
|
|
||||||
|
val lore = mutableListOf<String>()
|
||||||
|
lore.add("${ChatColor.GRAY}Players: ${ChatColor.WHITE}${world.players.size}")
|
||||||
|
lore.add("${ChatColor.GRAY}Time: ${ChatColor.WHITE}${world.time}")
|
||||||
|
lore.add("${ChatColor.GRAY}Weather: ${ChatColor.WHITE}${if (world.hasStorm()) "Raining" else "Clear"}")
|
||||||
|
lore.add("")
|
||||||
|
lore.add("${ChatColor.GREEN}Click: ${ChatColor.WHITE}Teleport to world spawn")
|
||||||
|
|
||||||
|
meta.lore = lore
|
||||||
|
worldIcon.itemMeta = meta
|
||||||
|
|
||||||
|
inventory.setItem(slot, worldIcon)
|
||||||
|
slot++
|
||||||
|
}
|
||||||
|
|
||||||
|
player.openInventory(inventory)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openServerSettings(player: Player) {
|
||||||
|
val inventory = Bukkit.createInventory(null, 27, "${ChatColor.LIGHT_PURPLE}${ChatColor.BOLD}Server Settings")
|
||||||
|
|
||||||
|
// Difficulty setting
|
||||||
|
inventory.setItem(10, createGuiItem(Material.ZOMBIE_HEAD, "${ChatColor.RED}Difficulty",
|
||||||
|
"${ChatColor.GRAY}Current: ${ChatColor.WHITE}${player.world.difficulty}",
|
||||||
|
"${ChatColor.GRAY}Click to cycle"))
|
||||||
|
|
||||||
|
// Gamemode setting
|
||||||
|
inventory.setItem(11, createGuiItem(Material.DIAMOND_SWORD, "${ChatColor.BLUE}Default Gamemode",
|
||||||
|
"${ChatColor.GRAY}Current: ${ChatColor.WHITE}${Bukkit.getDefaultGameMode()}",
|
||||||
|
"${ChatColor.GRAY}Click to cycle"))
|
||||||
|
|
||||||
|
// Toggle mob spawning
|
||||||
|
inventory.setItem(12, createGuiItem(Material.SPAWNER, "${ChatColor.GREEN}Mob Spawning",
|
||||||
|
"${ChatColor.GRAY}Click to toggle mob spawning"))
|
||||||
|
|
||||||
|
// PVP toggle
|
||||||
|
inventory.setItem(13, createGuiItem(Material.GOLDEN_SWORD, "${ChatColor.GOLD}PVP",
|
||||||
|
"${ChatColor.GRAY}Click to toggle PVP"))
|
||||||
|
|
||||||
|
// Whitelist
|
||||||
|
inventory.setItem(14, createGuiItem(Material.PAPER, "${ChatColor.WHITE}Whitelist",
|
||||||
|
"${ChatColor.GRAY}Click to toggle whitelist"))
|
||||||
|
|
||||||
|
// Save all worlds
|
||||||
|
inventory.setItem(15, createGuiItem(Material.FLOWER_POT, "${ChatColor.AQUA}Save All",
|
||||||
|
"${ChatColor.GRAY}Click to save all worlds"))
|
||||||
|
|
||||||
|
// Restart server (placeholder)
|
||||||
|
inventory.setItem(16, createGuiItem(Material.REDSTONE_BLOCK, "${ChatColor.DARK_RED}Restart Server",
|
||||||
|
"${ChatColor.GRAY}Click to restart server",
|
||||||
|
"${ChatColor.RED}This requires additional setup"))
|
||||||
|
|
||||||
|
player.openInventory(inventory)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openPluginManagement(player: Player) {
|
||||||
|
val inventory = Bukkit.createInventory(null, 54, "${ChatColor.AQUA}${ChatColor.BOLD}Plugin Management")
|
||||||
|
|
||||||
|
var slot = 0
|
||||||
|
for (plugin in Bukkit.getPluginManager().plugins) {
|
||||||
|
if (slot >= 54) break
|
||||||
|
|
||||||
|
val enabled = plugin.isEnabled
|
||||||
|
val material = if (enabled) Material.LIME_DYE else Material.GRAY_DYE
|
||||||
|
|
||||||
|
val pluginItem = createGuiItem(material,
|
||||||
|
"${if (enabled) ChatColor.GREEN else ChatColor.RED}${plugin.name}",
|
||||||
|
"${ChatColor.GRAY}Version: ${ChatColor.WHITE}${plugin.description.version}",
|
||||||
|
"${ChatColor.GRAY}Status: ${if (enabled) "${ChatColor.GREEN}Enabled" else "${ChatColor.RED}Disabled"}",
|
||||||
|
"",
|
||||||
|
"${ChatColor.YELLOW}Click to ${if (enabled) "disable" else "enable"}")
|
||||||
|
|
||||||
|
inventory.setItem(slot, pluginItem)
|
||||||
|
slot++
|
||||||
|
}
|
||||||
|
|
||||||
|
player.openInventory(inventory)
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/main/resources/plugin.yml
Normal file
22
src/main/resources/plugin.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: EasyAdmin
|
||||||
|
version: 1.0-SNAPSHOT
|
||||||
|
main: org.easyadmin.easyadmin.Easyadmin
|
||||||
|
api-version: '1.21'
|
||||||
|
author: rattatwinko
|
||||||
|
description: A minimal yet powerful admin GUI for Minecraft servers
|
||||||
|
|
||||||
|
commands:
|
||||||
|
easyadmin:
|
||||||
|
description: Opens the EasyAdmin GUI
|
||||||
|
usage: /easyadmin
|
||||||
|
aliases: [ea, admin, adminpanel]
|
||||||
|
permission: easyadmin.use
|
||||||
|
permission-message: You don't have permission to use this command!
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
easyadmin.use:
|
||||||
|
description: Allows access to the EasyAdmin GUI
|
||||||
|
default: op
|
||||||
|
easyadmin.exempt:
|
||||||
|
description: Exempts players from being kicked by the kick all function
|
||||||
|
default: op
|
||||||
Reference in New Issue
Block a user