Skip to content

Updating Python-Plugin-Loader #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.masteroftime</groupId>
<artifactId>PyPluginLoader</artifactId>
<version>0.3.5</version>
<version>0.3.6</version>
<name>PyPluginLoader</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand All @@ -16,7 +16,7 @@
<repositories>
<repository>
<id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/groups/public</url>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
</repository>
</repositories>
<build>
Expand Down Expand Up @@ -99,12 +99,12 @@
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.5.3</version>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.3.2-R3.0</version>
<version>LATEST</version>
</dependency>
</dependencies>
</project>
61 changes: 57 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Running
0. Ensure you are using a bukkit build that uses
https://github.com/Bukkit/Bukkit/pull/335 - otherwise, only some of your
plugins will work.
1. Put PyPluginLoader-0.2.jar in your bukkit/plugins/ dir
1. Put PyPluginLoader-0.3.6.jar in your bukkit/plugins/ dir
2. Put jython.jar in your bukkit/lib/ dir
3. [Re-]Start bukkit

Expand Down Expand Up @@ -70,6 +70,9 @@ your plugin.py:
print "enabled!"
def onDisable():
print "disabled!"
def onLoaded():
print "load complete!"


Decorator API
-------------
Expand All @@ -94,7 +97,11 @@ your main.py:
@hook.disable
def ondisable():
print "main.py disabled"


@hook.load_complete
def onloadcomplete():
print "main.py loading complete"

@hook.event("player.PlayerJoinEvent", "normal")
def playerjoin(event):
event.getPlayer().sendMessage("Hello from python")
Expand Down Expand Up @@ -202,6 +209,30 @@ Summary of fields:
- "website" - mainly for people reading the code


Plugin resources
----------------

Some plugins may contain resource files. Unlike the code these files maybe text, images
or other binary files. When this is the case you need some way to access resources packed
within a plugin. Plugin object accessible from python interpreter globals has a special
method to obtain resource files data from within the plugin.

def init_plugin():
resource_data = pyplugin.getPyResource(resource_filename)
with resource_data:
for record in resource_data:
...

getPyResource() method of the pyplugin exposed object take a resource file path local to
plugin container (zip archive or folder) and returns python file object available for
reading. That file object needs to be closed after. Context manager may be used for this
purpose.
Resource files may only be accessed before plugin loaded will close the plugin file
(in case of zip for example); best place for this is a load_complete hook handler
which is called right after pyplugin object instantiated and before plugin file will be
closed by plugin loader.


Decorator api
-------------

Expand Down Expand Up @@ -346,6 +377,21 @@ examples:
def onDisable():
print "disabled!"

Initialization
**************

Function decorated with hook.load_complete is called when your
plugin is first loaded and immediately after plugin object is instantiated.
this functionality is intended to provide you a point when a once per server run
plugin initialization routine should be called.

examples:

@hook.load_complete
def onLoadComplete():
doInit(pyplugin)
print "initialization complete!"

Accessing the plugin object
***************************

Expand Down Expand Up @@ -386,13 +432,17 @@ main.py
@hook.disable
def onDisable():
print "sample plugin disabled"

@hook.load_complete
def onLoadComplete():
print "sample plugin loading complete"

@hook.event("player_join", "normal")
def onPlayerJoin(event):
msg = "welcome from the sample plugin, %s" % event.getPlayer().getName()
print msg
event.getPlayer().sendMessage(msg)

@hook.command("samplecommand", usage="/<command>",
desc="send a sample message")
def onSampleCommand(sender, command, label, args):
Expand Down Expand Up @@ -437,7 +487,10 @@ plugin.py

def onDisable(self):
print "sample plugin disabled"


def onLoaded(self):
print "sample plugin load complete"

def onCommand(self, sender, command, label, args):
msg = "sample plugin command"
print msg
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/net/lahwran/bukkit/jython/PluginImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.core.PyTuple;
import org.python.modules.imp;
import org.python.modules._imp;

/**
* Unfinished importer to separate plugins into their own namespaces, possibly also import
Expand Down Expand Up @@ -61,7 +61,7 @@ private PyObject retrieveModule(String name) {
PyString pypath = new PyString(pluginpath.getAbsolutePath());
PyObject[] elements = new PyObject[] {pypath};
PyList paths = new PyList(elements);
PyObject result = imp.find_module(subname, paths);
PyObject result = _imp.find_module(subname, paths);
if (result != null) {
PyTuple info = (PyTuple) result;

Expand Down
20 changes: 20 additions & 0 deletions src/main/java/net/lahwran/bukkit/jython/PythonHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public class PythonHooks {
*/
PyFunction onDisable;

/**
* Function to call when plugin is initialized
*/
PyFunction onLoaded;

/**
* List of handlers to register
*/
Expand Down Expand Up @@ -247,6 +252,21 @@ public PyFunction disable(PyFunction func) {
return func;
}

/**
* Python decorator. functions decorated with this are called on load complete
* <pre>
* @hook.load_complete
* def loaded():
* print "load complete!"
* </pre>
* @param func function to decorate
* @return decorated function
*/
public PyFunction load_complete(PyFunction func) {
onLoaded = func;
return func;
}

/**
* Python decorator. functions decorated with this are called as event handlers
* @param type event type
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/net/lahwran/bukkit/jython/PythonPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
import org.bukkit.plugin.PluginLogger;
import org.bukkit.plugin.java.JavaPlugin;
import org.python.util.PythonInterpreter;
import org.python.core.util.FileUtil;
import org.python.core.PyFile;
import org.python.core.PyString;

import com.avaje.ebean.EbeanServer;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
Expand Down Expand Up @@ -274,6 +277,11 @@ public PluginCommand getCommand(String name) {
*/
public void onLoad() {}

public void onLoaded() {
if (hooks.onLoaded != null)
hooks.onLoaded.__call__();
}

public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
getServer().getLogger().severe("Plugin " + getDescription().getFullName() + " does not contain any generators that may be used in the default world!");
return null;
Expand Down Expand Up @@ -335,6 +343,19 @@ public InputStream getResource(String filename) {
}
}

public PyFile getPyResource(PyString filename) {
if(filename == null) {
throw new IllegalArgumentException("Filename cannot be null");
}

try {
return FileUtil.wrap(dataFile.getStream(filename.asString()));
} catch (IOException e) {
//just return null and do not print stack trace as JavaPlugin's getResource does not print it either
return null;
}
}

@Override
public void saveResource(String resourcePath, boolean replace) {
if (resourcePath == null || resourcePath.equals("")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,7 @@ private Plugin loadPlugin(File file, boolean ignoreSoftDependencies, PluginDataF
ArrayList<String> depend;

try {
depend = (ArrayList<String>) description.getDepend();
if (depend == null) {
depend = new ArrayList<String>();
}
depend = new ArrayList<String>(description.getDepend());
} catch (ClassCastException ex) {
throw new InvalidPluginException(ex);
}
Expand Down Expand Up @@ -288,6 +285,8 @@ private Plugin loadPlugin(File file, boolean ignoreSoftDependencies, PluginDataF

result.initialize(this, server, description, dataFolder, file);
result.setDataFile(data);

result.onLoaded();

} catch (Throwable t) {
if (data.shouldAddPathEntry() && pythonpath.__contains__(filepath)) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name: PythonLoader
main: com.master.bukkit.python.PythonLoader
version: 0.3.4
version: 0.3.6