Skip to content

Commit

Permalink
Merge pull request #18 from PXAV/development
Browse files Browse the repository at this point in the history
Add features for first release
  • Loading branch information
PXAV committed Jun 30, 2020
2 parents fed1dd8 + 7c2a2cf commit bfe3300
Show file tree
Hide file tree
Showing 69 changed files with 6,411 additions and 278 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,18 @@
# Kelp Changelog

This file contains the changes made in the different releases of the KelpFramework.

The headlines with `MR <number>` stand for the major release. The following headlines mark the minor releases/versions.

## MR 0

#### v0.0.1 (30.06.2020)
* First release of Kelp
* Add entity system
* Add command system
* Add NPC system
* Add configuration system
* Add Netty-Wrapper
* Add sidebar system
* Add entity system
* Add 1.8 support
6 changes: 5 additions & 1 deletion README.md
Expand Up @@ -86,6 +86,10 @@ playerConnection.sendPacket(spawnPacket);
- **Sidebar system:** Create sidebars - no matter if animated or just simple & casual. Use up to 32 chars per line and enjoy flicker-free updating
- **Inventory system:** Create stunning GUIs with minimal effort, use an integrated listener system and meet helpful pre-defined or custom widgets. Never mess with changed material names anymore.
- **NPC system:** Create NPCs with ease and give them abilities like sneaking or give them effects and animations.
- **Entity system:** Create and modify entities without directly spawning them.
- **Command system:** Create commands and sub-commands with complex structures and easily maintain them.
- **Config system:** Create key-value-based configurations for your messages, etc.
- **KelpConnect:** A simple and easy to use netty wrapper for Kelp
- **Particle engine:** coming soon


Expand Down Expand Up @@ -138,7 +142,7 @@ Put the jar file of the core module into the normal `plugins` folder of your ser

#### For developers

A detailed wiki and documentation is following soon.
Check out the [KelpWiki](https://github.com/PXAV/kelp/wiki), where you can find tutorials about the different features of Kelp. It is not 100% complete but constantly updated. Furthermore most of the classes and methods have JavaDocs, so check them out. A separate JavaDoc page is following soon.



Expand Down
10 changes: 10 additions & 0 deletions WISHLIST.md
@@ -0,0 +1,10 @@
# Kelp Wishlist

This file contains features which were requested by the community or other sources and are planned to be implemented into one of the next Kelp releases.

Before you create a new feature request, please make sure your idea has not already been posted in this wishlist to avoid duplicates.

## Features on the wishlist:

* Particle engine
* `KelpCommand#inheritSettingsFromParent()`: Settings like permissions, messages, etc. do not have to be set in every sub command but can be inherited by the main command.
79 changes: 44 additions & 35 deletions core/src/main/java/de/pxav/kelp/core/KelpPlugin.java
Expand Up @@ -24,13 +24,14 @@
import org.bukkit.plugin.java.annotation.plugin.author.Author;

import java.io.File;
import java.util.logging.Level;

/**
* A class description goes here.
*
* @author pxav
*/
@Plugin(name = "Kelp", version = "0.1-SNAPSHOT")
@Plugin(name = "Kelp", version = "0.0.1-SNAPSHOT")
@Author("pxav")
@Description("A cross version spigot framework.")
@Singleton
Expand All @@ -40,90 +41,94 @@ public class KelpPlugin extends JavaPlugin {

@Override
public void onLoad() {
getLogger().log(Level.INFO, "[BINDER] Using default bukkit logger until Kelp-Logger is available.");
getLogger().log(Level.INFO, "[BINDER] Loading Kelp-Binder...");

SimpleBinderModule simpleBinderModule = new SimpleBinderModule(this);
VersionBinderModule versionBinderModule = new VersionBinderModule(this, new File(Bukkit.getWorldContainer(),"kelp_versions"));
injector = Guice.createInjector(simpleBinderModule, versionBinderModule);
injector.injectMembers(this);

logger().log("[BINDER] Successfully injected all version implementations and members. ");
logger().log("[BINDER] Using normal Kelp-Logger now.");

injector.getInstance(ConfigurationRepository.class).loadAll(this.getClass().getPackage().getName());
injector.getInstance(KelpLogger.class).loadLoggerFiles();

injector.getInstance(KelpLogger.class).log(
"Loading Kelp Framework, begin logging...",
"[OK] Successfully loaded internal configurations!",
"[OK] Successfully loaded logger files!",
"Begin loading plugins from /kelp_plugins/..."
);
logger().log("[CONFIG] Successfully loaded logger files.");
logger().log("[APP] Detecting KelpApplications.");

injector.getInstance(KelpApplicationRepository.class)
.detectKelpApplications(new File(Bukkit.getWorldContainer(), "kelp_plugins"))
.load()
.enable();
.callOnLoad();

injector.getInstance(KelpLogger.class).log(
"[OK] Plugins loaded successfully!",
"Loading sequence completed"
);
logger().log("[APP] KelpApplications loaded successfully!");
}

@Override
public void onEnable() {
String[] developmentMode = injector.getInstance(KelpDefaultConfiguration.class)
.getBooleanValue(injector.getInstance(KelpDefaultConfiguration.class)
.developmentMode())
? new String[] {
"System is running in development mode.",
"=> Logging messages with DEBUG level as well."
}
: new String[] {
"System is running in production mode.",
"=> Messages with DEBUG level are not logged."
};

this.logKelpLogo("Enabling KelpFramework, running version " + this.getDescription().getVersion(),
"Developed & maintained by pxav and the open-source community with love <3");
injector.getInstance(KelpLogger.class).log(developmentMode);
"Developed & maintained by pxav and the open-source community with love <3", "");

injector.getInstance(KelpLogger.class).log("Checking environment...");
if (injector.getInstance(KelpDefaultConfiguration.class).getBooleanValue("development-mode")) {
logger().log("[GENERAL] Kelp is running in development mode. This allows you to access developer features.",
"[GENERAL] Messages with LogLevel.DEBUG are logged. If you do not want that, enable production mode in the config file.");
}

KelpVersion kelpVersion = KelpVersion.withBukkitVersion(Bukkit.getBukkitVersion());
logger().log("[VERSION] Checking server environment:");
if (kelpVersion == null) {
injector.getInstance(KelpLogger.class).log(LogLevel.WARNING, "=> The current server version is not supported by Kelp.");
logger().log(LogLevel.WARNING, "[VERSION] Server is running on " + Bukkit.getVersion() + " which is currently not supported by Kelp.");
logger().log("[VERSION] We are working on making Kelp compatible with as many versions as possible.");
logger().log("[VERSION] Check the GitHub Repo (https://github.com/PXAV/kelp) for more information about supported versions.");
Bukkit.getPluginManager().disablePlugin(this);
return;
} else {
logger().log("[VERSION] Server is running on " + Bukkit.getVersion() + " which is equal to Kelp-Version " + kelpVersion);
if (KelpVersion.versionImplementationExists(kelpVersion)) {
logger().log("[VERSION] This version is fully supported by Kelp.");
} else {
logger().log("[VERSION] This version is supported by Kelp, but there has not been written any version implementation",
"You will have to wait until you can finally use this version on your server.");
}
}

injector.getInstance(EventRegistration.class).initialize(this.getClass().getPackage().getName());

injector.getInstance(SidebarRepository.class).loadSidebars(this.getClass().getPackage().getName());
injector.getInstance(SidebarRepository.class).schedule();

injector.getInstance(KelpCommandRepository.class).loadCommands(this.getClass().getPackage().getName());

injector.getInstance(KelpNpcRepository.class).startScheduler();

injector.getInstance(KelpApplicationRepository.class).enableApplications();

logger().log("[VERSION] Initializing and enabling version implementation module.");
injector.getInstance(VersionBinderModule.getMainClass()).init(null, injector);
injector.getInstance(VersionBinderModule.getMainClass()).onEnable();
injector.getInstance(KelpLogger.class).log("Enabled Version implementation!");
logger().log("[VERSION] Enabled Version implementation!");

injector.getInstance(SoundVersionTemplate.class).defineDefaults();
injector.getInstance(KelpInventoryRepository.class).loadMaterials();
logger().log("[GENERAL] Successfully enabled KelpFramework. Have fun.");
}

@Override
public void onDisable() {
injector.getInstance(KelpLogger.class).log("Disabling plugins....");
injector.getInstance(KelpApplicationRepository.class).disableApplications();
injector.getInstance(KelpLogger.class).log("[OK] Disabled plugins!");

injector.getInstance(KelpNpcRepository.class).stopScheduler();
injector.getInstance(SidebarRepository.class).interruptAnimations();

logger().log("[VERSION] Disabling version implementation module");
injector.getInstance(VersionBinderModule.getMainClass()).onDisable();

this.logKelpLogo("Successfully shut down all Kelp services.",
"Thank you for using Kelp and goodbye!");


injector.getInstance(SidebarRepository.class).interruptAnimations();
injector.getInstance(KelpLogger.class).archiveLog();
injector.getInstance(KelpLogger.class).log("Saved log to archive. Disabling logger service.");
injector.getInstance(KelpLogger.class).log("[GENERAL] Saved log to archive. Disabling logger service.");
}

public static Injector getInjector() {
Expand All @@ -145,4 +150,8 @@ private void logKelpLogo(String... additionalLines) {
injector.getInstance(KelpLogger.class).log(additionalLines);
}

private KelpLogger logger() {
return injector.getInstance(KelpLogger.class);
}

}
Expand Up @@ -114,11 +114,11 @@ public KelpApplicationRepository load() {
KelpApplicationMeta module = entry.getValue();

if (!bindToClassPath(moduleStatuses2, new Stack<>(), module)) {
logger.log(LogLevel.ERROR, "Failed to enable " + entry.getKey());
logger.log(LogLevel.ERROR, "[APP] Failed to enable " + entry.getKey());
continue;
}

logger.log(LogLevel.INFO, "Successfully loaded " + entry.getKey());
logger.log(LogLevel.INFO, "[APP] Successfully loaded " + entry.getKey());
}
return this;
}
Expand Down Expand Up @@ -226,7 +226,7 @@ private boolean bindToClassPath(
}

dependencyGraph.append(module.getApplicationName()).append(" -> ").append(dependName);
logger.log(LogLevel.ERROR, "Circular dependency detected for "
logger.log(LogLevel.ERROR, "[APP] Circular dependency detected for "
+ module.getApplicationName()
+ ": " + dependencyGraph);
status = false;
Expand All @@ -238,7 +238,7 @@ private boolean bindToClassPath(
}

if (!Boolean.FALSE.equals(dependStatus) && !module.getSoftDependencies().contains(dependName)) {
logger.log(LogLevel.WARNING, "Dependency " + dependName + " (required by " + module.getApplicationName() + ") is unavailable");
logger.log(LogLevel.WARNING, "[APP] Dependency " + dependName + " (required by " + module.getApplicationName() + ") is unavailable");
status = false;
}

Expand All @@ -257,7 +257,7 @@ private boolean bindToClassPath(
(Class<? extends KelpApplication>) loader.loadClass(module.getMain());
this.classPathApps.put(module, main);
} catch (Throwable t) {
logger.log(LogLevel.ERROR,"Cannot load module " + module.getApplicationName() + ". Check stack trace for more information:");
logger.log(LogLevel.ERROR,"[APP] Cannot load module " + module.getApplicationName() + ". Check stack trace for more information:");
t.printStackTrace();
}
}
Expand All @@ -273,8 +273,7 @@ public void enableAfterClassPathLoad() {
moduleInstance.init(description, injector);

appsToEnable.put(description.getApplicationName(), moduleInstance);
logger.log(
"Loading application "
logger.log("[APP] Loading application "
+ description.getApplicationName()
+ " with version "
+ description.getVersion());
Expand All @@ -283,10 +282,11 @@ public void enableAfterClassPathLoad() {
}

public void enableApplications() {
logger.log("[APP] Enabling all registered KelpApplications...");
for (Map.Entry<String, KelpApplication> namePluginEntry : appsToEnable.entrySet()) {
try {
logger.log(
"Enabling application "
"[APP] Enabling application "
+ namePluginEntry.getValue().getInformation().getApplicationName()
+ " with version "
+ namePluginEntry.getValue().getInformation().getVersion());
Expand All @@ -298,7 +298,7 @@ public void enableApplications() {
enabledApps.put(namePluginEntry.getKey(), namePluginEntry.getValue());
} catch (Throwable t) {
logger.log(LogLevel.ERROR,
"Exception encountered while loading application "
"[APP] Exception encountered while loading application "
+ namePluginEntry.getValue().getInformation().getApplicationName()
+ ":");
t.printStackTrace();
Expand All @@ -309,7 +309,7 @@ public void enableApplications() {
appsToEnable.clear();
}

public void enable() {
public void callOnLoad() {
enableAfterClassPathLoad();
appsToLoad.clear();
}
Expand All @@ -332,20 +332,22 @@ private void disableApplication(KelpApplication application) {
&& kelpApplication.getInformation().getHardDependencies().contains(application.getInformation()
.getApplicationName())).forEach(this::disableApplication);

logger.log("Disabling application " + application.getInformation().getApplicationName());
logger.log("[APP] Disabling application " + application.getInformation().getApplicationName());

try {
application.onDisable();
} catch (Exception e) {
logger.log(LogLevel.ERROR, "Error while disabling " + application.getInformation().getApplicationName());
logger.log(LogLevel.ERROR, "[APP] Error while disabling " + application.getInformation().getApplicationName());
e.printStackTrace();
}

enabledApps.remove(application.getInformation().getApplicationName());
}

public void disableApplications() {
logger.log("[APP] Disabling all KelpApplications...");
getEnabledApps().forEach(this::disableApplication);
logger.log("[APP] All KelpApplications have been successfully disabled.");
}

public Collection<KelpApplication> getEnabledApps() {
Expand Down
45 changes: 44 additions & 1 deletion core/src/main/java/de/pxav/kelp/core/command/CreateCommand.java
Expand Up @@ -6,16 +6,59 @@
import java.lang.annotation.Target;

/**
* A class description goes here.
* Classes which should represent a new command
* have to be annotated with this annotation. It tells
* the Kelp system that this is a valid command class
* and you can provide essential information about
* your command.
*
* This annotation is only used for main commands, so
* commands that directly some after the '/'. If you want to
* add sub commands, take a look at {@code CreateSubCommand}.
*
* Furthermore your class has to inherit from the
* {@code KelpCommand} class and override at least
* one of the {@code #onCommand} methods.
*
* @see KelpCommand
* @see CreateSubCommand
* @author pxav
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CreateCommand {

/**
* Defines the name of the command, so the
* string the player has to enter in the chat
* to execute it. The '/' does not have to be
* included in this name.
*
* The name should be unique as only one command
* can be executed at a time by bukkit.
*
* This method is only meant for defining the
* main command name. If you want to add aliases,
* you can do that by using {@code #addAlias} in the
* {@code #onCommandRegister} method in your command class.
*
* @return The command name.
*/
String name();

/**
* Sets the executor type of the command, so it
* defines who is allowed to execute the command.
* Further information about that can be found in
* the {@code ExecutorType} class.
*
* Note that the executor type is only set for the
* very main command and not for the child/sub commands.
* You can adjust their executor types manually.
*
* @see ExecutorType
* @return The executor type for this specific command.
*/
ExecutorType executorType() default ExecutorType.PLAYER_AND_CONSOLE;

}

0 comments on commit bfe3300

Please sign in to comment.