mpp-api

Apr 16, 2016
mpp-api
  • This page is intended for map-painting API users / developers.
    You will learn to obtain required codes and javadoc, make a simple plugin, and make it run.
    Hopefully you will get a plugin more amazing than Map Painting itself.

    1 Environment
    Before you could develop a plugin depending on map painting, you should retrieve the API and javadoc first. They could be obtained at https://github.com/aegistudio/MapPainting/releases.

    [​IMG]
    When you have downloaded those archives, firstly add the API jar (mappainting-xxxxx.jar) to build path.

    [​IMG]
    Then attach javadoc (mappainting-xxxxx-javadoc.jar) to the archive.

    [​IMG]
    You could now get coding support from javadoc!
    2 Customize canvas
    When you use MapPainting API, one major article is to customize your own canvas, and is always your main purpose.

    To customize your own canvas, you must have a implementation of PluginCanvas, which generalize the feature of a plugin customized canvas. The PluginCanvas is under package net.aegistudio.mpp.export. There're 7 methods waiting for you to implement, they're:
    • paint: invoke when player use paint tools to paint on your canvas.
    • interact: invoke when player use hands or non-paint tools to interact with your canvas.
    • tick: invoke when the server ticks.
    • add: invoke when this canvas was added or loaded into the server.
    • remove: invoke when this canvas was removed or unloaded from the server.
    • load: invoke when your canvas should load data.
    • save: invoke when your canvas should save data.
    More detailed information could be read from javadoc.

    You should feel doubted that where to display your canvas content? Now let's invite another pivot of customizing canvas: the PluginCanvasFactory, which is also under package net.aegistudio.mpp.export. This has a factory method create, which take into a Context parameter and create a PluginCanvas in return. If you feel this is hard to comprehend, just imagine the factory as the constructor of PluginCanvas, actually factory method has the alias of virtual constructor.

    If you would like to, you could write such class, which will display the position where player have clicked on the screen, and record the times that the player has clicked.

    Code (Java):
    package net.aegistudio.mpp.apitest;

    import java.awt.Color;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;

    import net.aegistudio.mpp.Interaction;
    import net.aegistudio.mpp.algo.StringGenerator;
    import net.aegistudio.mpp.export.Context;
    import net.aegistudio.mpp.export.PluginCanvas;

    public class APITestCanvas implements PluginCanvas {

        public final Context context;
        private int times = 0;
        private StringGenerator string;

        /** APITest is the owner plugin of this canvas, test.algo is a instance of Algorithm. **/
        public APITestCanvas(APITest test, Context context) {
            this.context = context;
            this.string = test.algo.get("string.left", StringGenerator.class);
        }

        @Override
        public boolean interact(Interaction i) {
            context.color(Color.RED);
            context.clear();

            context.color(Color.GREEN);
            for(int p = 0; p < 128; p ++) {
                context.set(i.x, p);
                context.set(p, i.y);
            }
            context.color(Color.WHITE);
            string.string(context, 1, 1, 1.0f, Integer.toString(times));
            string.string(context, 1, 120, 1.0f, String.format("(%d, %d)", i.x, i.y));

            context.repaint();

            times ++;
            return true;
        }

        @Override
        public void load(InputStream input) {
            try {
                DataInputStream din = new DataInputStream(input);
                times = din.readInt();
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void save(OutputStream output) {
            try {
                DataOutputStream dout = new DataOutputStream(output);
                dout.writeInt(times);
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void add() {    }

        @Override
        public void remove() {    }

        @Override
        public void tick() {    }

        @Override
        public void paint(Interaction i, Color c) {    }
    }
     
    You will need a canvas factory:
    Code (Java):
    package net.aegistudio.mpp.apitest;

    import net.aegistudio.mpp.export.Context;
    import net.aegistudio.mpp.export.PluginCanvasFactory;

    public class APITestCanvasFactory implements PluginCanvasFactory<APITestCanvas> {

       private final APITest plugin;
       public APITestCanvasFactory(APITest plugin) {
         this.plugin = plugin;
       }

       @Override
       public APITestCanvas create(Context context) {
         return new APITestCanvas(plugin, context);
       }
    }
     
    3 Create/Destroy canvas
    We are not talking about how to create a canvas in game so far. In this chapter, we will be talking about how to create. And we will talk about how to remove such canvas.

    We will introduce the class of our plugin.
    Code (Java):
    package net.aegistudio.mpp.apitest;

    import java.awt.Color;

    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.Material;

    import net.aegistudio.mpp.algo.StringGenerator;
    import net.aegistudio.mpp.export.AssetService;
    import net.aegistudio.mpp.export.CanvasCommandHandle;
    import net.aegistudio.mpp.export.CommandHandle;
    import net.aegistudio.mpp.export.NamingException;
    import net.aegistudio.mpp.export.PluginCanvasRegistry;
    import net.aegistudio.mpp.export.PluginCanvasService;
    import net.aegistudio.mpp.export.PluginCommandService;

    public class APITest extends JavaPlugin {
       PluginCanvasService svc;
       AssetService algo;
       public void onEnable() {
         algo = this.getServer().getServicesManager()
             .getRegistration(AssetService.class).getProvider();
         svc = this.getServer().getServicesManager()
             .getRegistration(net.aegistudio.mpp.export.PluginCanvasService.class).getProvider();
         try {
             svc.register(this, "apitest", new APITestCanvasFactory(this));
         } catch(NamingException e) {
             e.printStackTrace();
         }
       }

      public boolean onCommand(CommandSender sender, Command cmd, String lbl, String[] arguments) {
         if(sender instanceof Player) {
           Player ply = (Player) sender;
           if(ply.getItemInHand().getType() != Material.MAP) return false;
           short id = ply.getItemInHand().getDurability();

           if(cmd.getLabel().equals("testadd")) {
             try {
               /** /testadd to create canvas, canvas id is their holding canvas. **/
               PluginCanvasRegistry<APITestCanvas> canvas = svc.generate(this, "apitest", APITestCanvas.class);
               canvas.canvas().context.color(Color.RED);
               canvas.canvas().context.clear();
               canvas.canvas().context.color(Color.BLACK);
         
               algo.get("string.center", StringGenerator.class)
                 .string(canvas.canvas().context, 64, 64, 2.0f, "APITEST");
         
               canvas.canvas().context.repaint();
               svc.create(id, ply, arguments[0], canvas);
             } catch (NamingException e) {
               sender.sendMessage("Creation failed!");
             }
             return true;
           }
           else if(cmd.getLabel().equals("testrem")) {
             PluginCanvasRegistry<APITestCanvas> registry;
             if(arguments.length > 0) registry = svc.get(this, "apitest", arguments[0], APITestCanvas.class);
             else registry = svc.get(this, "apitest", id, APITestCanvas.class);
       
             if(svc.destroy(registry))
               sender.sendMessage("Successfully removed corresponding canvas!");
             else sender.sendMessage("Removal failed!");
             return true;
           }
         }
         return false;
       }
    }
     
    Let's analyze such tedious code. The first thing we should do is to register the canvas factory to the service provider of MapPainting. The service class is PluginCanvasService, which is under package net.aegistudio.mpp.export. By calling the register method, you will could register your factory.
    Code (Java):
       PluginCanvasService svc;
       AssetService algo;
       public void onEnable() {
         /** Get the provider that contains the algorithms. **/
         algo = this.getServer().getServicesManager()
             .getRegistration(AssetService.class).getProvider();
         /** Get the canvas service provider. **/
         svc = this.getServer().getServicesManager()
             .getRegistration(PluginCanvasService.class).getProvider();
         /** Register the factory. **/
         try {
             svc.register(this, "apitest", new APITestCanvasFactory(this));
         } catch(NamingException e) {
             e.printStackTrace();
         }
       }
     
    The creation steps are somehow complex. You should first call generate to create a instance of your own canvas, then call create to bind it to a canvas. Between the create and generate, you could do some additional operations to the created instance. (In this example, we display "APITEST" in the centre of the canvas after creation.)
    Code (Java):
           if(cmd.getLabel().equals("testadd")) {
             try {
               /** /testadd to create canvas, canvas id is their holding canvas. **/
               PluginCanvasRegistry<APITestCanvas> canvas = svc.generate(this, "apitest", APITestCanvas.class);
               canvas.canvas().context.color(Color.RED);
               canvas.canvas().context.clear();
               canvas.canvas().context.color(Color.BLACK);
         
               algo.get("string.center", StringGenerator.class)
                 .string(canvas.canvas().context, 64, 64, 2.0f, "APITEST");
         
               canvas.canvas().context.repaint();
               svc.create(id, ply, arguments[0], canvas);
             } catch (NamingException e) {
               sender.sendMessage("Creation failed!");
             }
             return true;
           }
     
    When you want to destroy a canvas you create, just call destroy method. (You may need get method to retrieve a registry instance.)
    Code (Java):
           else if(cmd.getLabel().equals("testrem")) {
             PluginCanvasRegistry<APITestCanvas> registry;
             if(arguments.length > 0) registry = svc.get(this, "apitest", arguments[0], APITestCanvas.class);
             else registry = svc.get(this, "apitest", id, APITestCanvas.class);
       
             if(svc.destroy(registry))
               sender.sendMessage("Successfully removed corresponding canvas!");
             else sender.sendMessage("Removal failed!");
             return true;
           }
     
  • Loading...
  • Loading...