Skip to content

Commit 15df852

Browse files
authored
Merge pull request #11 from CSC207-2022F-UofT/feat-plugin-loader
2 parents a609e24 + 63e31fe commit 15df852

17 files changed

+554
-43
lines changed

build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import org.apache.tools.ant.filters.ReplaceTokens
33
plugins {
44
id 'java'
55
id 'maven-publish'
6+
id "com.github.johnrengelman.shadow" version "7.1.2"
67
}
78

89
group 'org.hydev.csc207'
@@ -32,6 +33,9 @@ dependencies {
3233
// The Spigot API with no shadowing. Requires the OSS repo.
3334
compileOnly 'org.spigotmc:spigot-api:1.19-R0.1-SNAPSHOT'
3435

36+
// https://mvnrepository.com/artifact/net.sourceforge.argparse4j/argparse4j
37+
implementation 'net.sourceforge.argparse4j:argparse4j:0.9.0'
38+
3539
// Apache HTTP Client
3640
// https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5-fluent
3741
implementation 'org.apache.httpcomponents.client5:httpclient5-fluent:5.2-beta1'
@@ -46,6 +50,9 @@ dependencies {
4650
// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
4751
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.0-rc1'
4852

53+
// https://mvnrepository.com/artifact/com.google.guava/guava
54+
implementation 'com.google.guava:guava:31.1-jre'
55+
4956
// YAML parser
5057
// https://mvnrepository.com/artifact/org.yaml/snakeyaml
5158
implementation group: 'org.yaml', name: 'snakeyaml', version: '1.33'
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.hydev.mcpm;
2+
3+
import net.sourceforge.argparse4j.ArgumentParsers;
4+
import net.sourceforge.argparse4j.inf.ArgumentParser;
5+
import net.sourceforge.argparse4j.inf.ArgumentParserException;
6+
7+
/**
8+
* Static collection of argument parsers for the command line
9+
*
10+
* @author Azalea (https://github.com/hykilpikonna)
11+
* @since 2022-10-30
12+
*/
13+
public class ArgsParser
14+
{
15+
public static final ArgumentParser LOADER;
16+
17+
static
18+
{
19+
LOADER = ArgumentParsers.newFor("loader").build().defaultHelp(true);
20+
LOADER.addArgument("name");
21+
}
22+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package org.hydev.mcpm;
2+
3+
import net.sourceforge.argparse4j.inf.ArgumentParserException;
4+
import org.hydev.mcpm.client.injector.*;
5+
6+
import java.util.function.Consumer;
7+
8+
import static java.lang.String.format;
9+
import static org.hydev.mcpm.utils.Sugar.sub;
10+
import static org.hydev.mcpm.utils.Sugar.subFrom;
11+
12+
13+
/**
14+
* Controller of the program
15+
*
16+
* @author Azalea (https://github.com/hykilpikonna)
17+
* @since 2022-10-30
18+
*/
19+
public class Controller
20+
{
21+
private final LoadBoundary loader;
22+
private final UnloadBoundary unloader;
23+
private final ReloadBoundary reloader;
24+
25+
public Controller()
26+
{
27+
var pl = new PluginLoader();
28+
loader = pl;
29+
unloader = pl;
30+
reloader = pl;
31+
}
32+
33+
/**
34+
* Run a command
35+
*
36+
* @param args Command-line arguments (not including the command name/path)
37+
* @param log Callback logger
38+
*/
39+
public void runCommand(String[] args, Consumer<String> log)
40+
{
41+
if (args.length == 0) return;
42+
43+
var cmd = args[0].toLowerCase();
44+
switch (cmd)
45+
{
46+
case "load", "unload", "reload" ->
47+
{
48+
try
49+
{
50+
var a = ArgsParser.LOADER.parseArgs(subFrom(args, 1));
51+
var name = a.getString("name");
52+
53+
try
54+
{
55+
switch (cmd)
56+
{
57+
case "load" -> loader.loadPlugin(name);
58+
case "unload" -> unloader.unloadPlugin(name);
59+
case "reload" -> reloader.reloadPlugin(name);
60+
}
61+
log.accept(format("Plugin %s %sed", name, cmd));
62+
}
63+
catch (PluginNotFoundException e)
64+
{
65+
log.accept(format("Plugin %s not found", name));
66+
}
67+
}
68+
catch (ArgumentParserException e)
69+
{
70+
log.accept("Error: " + e.getMessage());
71+
log.accept(ArgsParser.LOADER.formatHelp());
72+
}
73+
}
74+
default ->
75+
{
76+
log.accept("Usage: /mcpm <install/uninstall/update/search/load/unload/reload/help>");
77+
}
78+
}
79+
}
80+
}

src/main/java/org/hydev/mcpm/SpigotEntry.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import org.bukkit.plugin.java.JavaPlugin;
77
import org.jetbrains.annotations.NotNull;
88

9+
import java.util.Arrays;
910
import java.util.Objects;
1011
import java.util.logging.Logger;
1112

@@ -17,6 +18,7 @@
1718
public class SpigotEntry extends JavaPlugin implements CommandExecutor
1819
{
1920
private Logger log;
21+
private Controller controller;
2022

2123
/**
2224
* onEnable() is called when our plugin is loaded on a Spigot server.
@@ -26,7 +28,10 @@ public void onEnable()
2628
{
2729
// Initialize logger
2830
log = getLogger();
29-
log.info("[MCPM] Enabled!");
31+
log.info("Enabled!");
32+
33+
// Initialize controller
34+
controller = new Controller();
3035

3136
// Register mcpm command
3237
requireNonNull(this.getCommand("mcpm")).setExecutor(this);
@@ -38,13 +43,13 @@ public void onEnable()
3843
@Override
3944
public void onDisable()
4045
{
41-
log.info("[MCPM] Disabled!");
46+
log.info("Disabled!");
4247
}
4348

4449
@Override
4550
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args)
4651
{
47-
sender.sendMessage("This command is not yet implemented, meow~");
48-
return false;
52+
controller.runCommand(args, sender::sendMessage);
53+
return true;
4954
}
5055
}

src/main/java/org/hydev/mcpm/client/database/DatabaseLoader.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
package org.hydev.mcpm.client.database;
22

3-
import org.hydev.mcpm.client.models.Plugin;
3+
import org.hydev.mcpm.client.models.PluginModel;
44

5-
import javax.xml.crypto.Data;
6-
import java.io.File;
75
import java.util.HashMap;
86
import java.util.List;
97
import java.util.Map;
@@ -17,13 +15,13 @@
1715
public class DatabaseLoader
1816
{
1917
/** Name index: map[lower-cased name] = Plugin of that name */
20-
private final Map<String, Plugin> nameIndex;
18+
private final Map<String, PluginModel> nameIndex;
2119

2220
/** Keyword index: map[lower keyword] = List[plugins that contain the keyword either in name or description] */
23-
private final Map<String, List<Plugin>> keywordIndex;
21+
private final Map<String, List<PluginModel>> keywordIndex;
2422

2523
/** Command index: map[lower command name/alias] = List[plugins that provide the command or alias] */
26-
private final Map<String, List<Plugin>> commandIndex;
24+
private final Map<String, List<PluginModel>> commandIndex;
2725

2826
/**
2927
* Load database, create index for faster searching through the database
@@ -46,7 +44,7 @@ public DatabaseLoader(String path)
4644
* @param name Name of the plugin
4745
* @return Plugin of that name, or null if not found
4846
*/
49-
public Plugin findByName(String name)
47+
public PluginModel findByName(String name)
5048
{
5149
// TODO: Implement this
5250
throw new UnsupportedOperationException("TODO");
@@ -65,7 +63,7 @@ public Plugin findByName(String name)
6563
* @param keyword Keyword
6664
* @return List of packages matching the keyword, or empty list
6765
*/
68-
public List<Plugin> searchByKeyword(String keyword)
66+
public List<PluginModel> searchByKeyword(String keyword)
6967
{
7068
// TODO: Implement this
7169
throw new UnsupportedOperationException("TODO");
@@ -77,7 +75,7 @@ public List<Plugin> searchByKeyword(String keyword)
7775
* @param command Command name
7876
* @return Plugins that provides the command, or empty list
7977
*/
80-
public List<Plugin> searchByCommand(String command)
78+
public List<PluginModel> searchByCommand(String command)
8179
{
8280
// TODO: Implement this
8381
throw new UnsupportedOperationException("TODO");

src/main/java/org/hydev/mcpm/client/database/LocalPluginTracker.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.hydev.mcpm.client.database;
22

3-
import org.hydev.mcpm.client.models.Plugin;
43
import org.hydev.mcpm.client.models.PluginVersion;
54

65
import java.io.File;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.hydev.mcpm.client.injector;
2+
3+
import java.io.File;
4+
5+
/**
6+
* Interface for loading a locally installed plugin.
7+
*
8+
* @author Azalea (https://github.com/hykilpikonna)
9+
* @since 2022-10-29
10+
*/
11+
public interface LoadBoundary
12+
{
13+
/**
14+
* Dynamically load a local plugin through JVM reflections and classloader hacks
15+
*
16+
* @param name Loaded plugin name
17+
* @return True if success, false if failed
18+
* @throws PluginNotFoundException Plugin of the name is not found in the plugins directory
19+
*/
20+
public boolean loadPlugin(String name) throws PluginNotFoundException;
21+
22+
/**
23+
* Dynamically load a local plugin through JVM reflections and classloader hacks
24+
*
25+
* @param jar Local jar file path
26+
* @return True if success, false if failed
27+
*/
28+
public boolean loadPlugin(File jar);
29+
}

0 commit comments

Comments
 (0)