Simple Temp Book API

Discussion in 'Resources' started by Tux2, Aug 15, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    desht

    OK, tracked this one down - it's a Spout problem. If SpoutPlugin is present, written book contents are lost when written books are dropped on the ground. Works fine without SpoutPlugin installed. Filed http://issues.spout.org/browse/SPOUTPLUGIN-142.
     
  2. Offline

    cadika_orade

    This is very handy (I think) but I'm having some difficulty getting a simple test of it to work.

    For now I'm just trying to add a book to the inventory of a player who uses the command "/bookmake". Eventually I'll do more things, but I want to make sure I can actually make a book first.

    Here's what I'm doing:

    Code:
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args)
        {
           
            if (label.equalsIgnoreCase("bookmake"))
            {   
               
                Server server = Bukkit.getServer();
                Player p = server.getPlayer(args[0]);
               
                sender.sendMessage("Declaring pages[]");
                String[] pages;
                sender.sendMessage("Allocating pages[]");
                pages = new String[10];
                String author = "Herp McDerp";
                String title = "Most Awesome Title Ever.";
                sender.sendMessage("Initializing pages[0]");
                pages[0] = "Awesome text here! Zero!";
                sender.sendMessage("Initializing pages[1]");
                pages[1] = "Awesome text here! One!";
                sender.sendMessage("Initializing pages[2]");
                pages[2] = "Awesome text here! Two!";
                sender.sendMessage("Initializing pages[3]");
                pages[3] = "Awesome text here! Three!";
                sender.sendMessage("Initializing pages[4]");
                pages[4] = "Awesome text here! Four!";
                sender.sendMessage("Initializing pages[5]");
                pages[5] = "Awesome text here! Five!";
                sender.sendMessage("Initializing pages[6]");
                pages[6] = "Awesome text here! Six!";
                sender.sendMessage("Initializing pages[7]");
                pages[7] = "Awesome text here! Seven!";
                sender.sendMessage("Initializing pages[8]");
                pages[8] = "Awesome text here! Eight!";
                sender.sendMessage("Initializing pages[9]");
                pages[9] = "Awesome text here! Nine!";
     
                sender.sendMessage("Creating BookItem");
                BookItem bi = new BookItem(new ItemStack(387,1));
                sender.sendMessage("Setting Pages");
                bi.setPages(pages);
                sender.sendMessage("Setting Author");
                bi.setAuthor(author);
                sender.sendMessage("Setting Title");
                bi.setTitle(title);
                //When making an ItemStack it isn't automatically the correct
                //format, so we need to make sure to get the one from
                //book item.
                sender.sendMessage("Creating ItemStack");
                ItemStack writtenbook = bi.getItemStack();
               
                sender.sendMessage("Giving finished book");
     
                p.getInventory().addItem(writtenbook);
               
                sender.sendMessage("Command Executed!");
                return true;
            }
           
            return false;
        }
    When I run it I don't get any errors and all the debug messages display without hesitation, but no book shows up. Am I doing something wrong?

    Also, I've looked long and hard for a way to simply add the item to the invenory of the person who ran the command, instead of having to add a name as an argument but found nothing. Suggestions?

    (I'm new to both Java and Bukkit, but I know C++ and C# and I'm learning fast!)
     
  3. Offline

    desht

    cadika_orade You're mostly there.

    To get the book to show up in the player's inventory, you need to call player.updateInventory() after the .addItem() call. (Yes, this method is marked as deprecated, but it's the only way currently to sync a server inventory to the client).

    To give the book to the caller, you check the argument count (args.length) and if there are no arguments, you give it to the sender. To do this, you can check if sender is an instance of Player (Player extends the CommandSender interface, among others), and if so, cast sender to an object of type Player. (The sender is castable to Player if it was a player running the command, but not if the command was run from the console).

    I do exactly this here: https://github.com/desht/portableho.../desht/portablehole/commands/GiveCommand.java (note that I'm using a custom command framework class instead of using onCommand() directly, but the principle of creating & giving an item still applies).

    Note that you should also check the return value of Bukkit.getPlayer() and give the sender a sensible error message if it's null - otherwise you'll get a NullPointerException if the target player isn't online.

    Finally, a slightly more concise Java-ish way of initialising a String array:
    PHP:
    String [] pages = new String[] {
      
    "page one",
      
    "page two",
      
    "page three",
      
    // etc.
    };
     
  4. Offline

    cadika_orade

    Much obliged! I have a plugin installed that exports books as txt files, but the creator said that he/she was waiting for an official book API. I'm not so patient. xD

    I'll give that a shot this evening and see if it works!

    Update: I had some time between classes (pun?) so I made the changes you suggested and had a friend test it on his server. It worked perfectly! Thank you! :D
     
  5. Offline

    devilquak

    desht Since you seem to be very good and knowledgeable about this kind of stuff, do you happen to know how to search a player's inventory for a written book with a certain title/author using this API? I'm having a lot of trouble figuring it out on my own...
     
  6. Offline

    desht

    This is offhand, so no testing, but should be about right:
    PHP:
    for (ItemStack stack player.getInventory()) {
      if (
    stack.getType() == Material.WRITTEN_BOOK) {
        
    BookItem bi = new BookItem(stack);
        
    // checking for title OR author here - adjust to suit
        
    if (bi.getTitle().equals(wantedTitle) || bi.getAuthor().equals(wantedAuthor)) {
          
    // ...do something...
        
    }
      }
    }
     
    devilquak likes this.
  7. Offline

    devilquak

    Ah, great, looks very different from what I was trying. I'll test this when I get time, thanks for your help.
     
  8. Offline

    Neodork

    Would people with a Spout JIRA account be so kind to bump this to up the priority ?

    +

    Are there any changes to be made for the latest RB?
     
  9. Offline

    Joshua Burt

    Also confirmed that this works as advertised. Thank you! :) I'm now giving our starting guide to new users on join. Swweeeettt.
     
  10. Offline

    Tux2

    I'm happy to know that people are using the API and that it works well for you guys. The code used should be quite stable unless bukkit decides to totally change up their entire code base so feel free to use it in long term projects.
     
  11. Offline

    Tux2

    Lol, and of course bukkit changes it up... I'm now offering this file packaged in a library that you can link against to make sure that it will continue to work regardless of Minecraft updates.
     
  12. Offline

    Neodork

    Are we allowed to add the source of the TuxTwoLib to our plugins? This I we wouldn't have to add another dependency to my plugin. Since it's all rights reserved now I would like to be sure..
     
  13. Offline

    Tux2

    The reason I made the TuxTwoLib is so that plugin devs wouldn't have to recompile their jar every Minecraft version (see this commit: https://github.com/Bukkit/CraftBukkit/commit/8f12382e8efc8c39a919af9180dd884caf3720ff )
    You are more than welcome to keep using the pastebin above, just inserting the v1_4_5 in the includes and recompiling your plugin every Minecraft version if you are so inclined. I don't like using dependencies in my plugins either, but it was either ugly reflection or doing this.
     
  14. Offline

    Neodork

    I don't mind having to recompile it every Minecraft update. I'll have to change and test the NPClib most of the time anyways. Guess it wouldn't hurt to test the books interface either. Thanks for your permission.
     
Thread Status:
Not open for further replies.

Share This Page