Generate a saved map on command ?

Discussion in 'Plugin Development' started by ThunderWaffeMC, Jun 19, 2013.

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

    ThunderWaffeMC

    How can I simply make it so when a user uses a command then it creates a new world called "world <playername>" from a map I have already made so each player can have their own version of my map that they can edit?

    I have seen this in plugins like skyblock and it's basically the same as what I want.

    Thanks in advance!


    Edit:

    I'm currently using:
    Bukkit.createWorld(new WorldCreator("Player-base"));
    to create the world. Instead of creating a new world, how can I generate a copy world of another world I have and where "player" is in "player-base" how can I change it to the players name?
     
  2. Offline

    chasechocolate

    Just use the copy(world) method in WorldCreator. For making players name, just use new WorldCreator(player.getName() + "-world").copy(otherWorld).
     
    ThunderWaffeMC likes this.
  3. Offline

    ThunderWaffeMC

    It says "otherWorld" cannot be resolved as a variable... How can I add the world template so it is a variable? Thanks, too for the other code!
     
  4. Offline

    chasechocolate

    ThunderWaffeMC .copy(Bukkit.getWorld("world-template")) or whatever your template world file is.
     
    ThunderWaffeMC likes this.
  5. Offline

    ThunderWaffeMC

    chasechocolate

    I'm getting an error even though I have a world called "CollideTemplate". It says in game after the command saying an internal error occurred.

    The error:

    Code:
    2013-06-22 14:54:33 [INFO] Thunder_Waffe issued server command: /collide start
    2013-06-22 14:54:33 [SEVERE] null
    org.bukkit.command.CommandException: Unhandled exception executing command 'collide' in plugin Collide vv1.0
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46)
    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:189)
    at org.bukkit.craftbukkit.v1_5_R3.CraftServer.dispatchCommand(CraftServer.java:523)
    at net.minecraft.server.v1_5_R3.PlayerConnection.handleCommand(PlayerConnection.java:965)
    at net.minecraft.server.v1_5_R3.PlayerConnection.chat(PlayerConnection.java:883)
    at net.minecraft.server.v1_5_R3.PlayerConnection.a(PlayerConnection.java:840)
    at net.minecraft.server.v1_5_R3.Packet3Chat.handle(Packet3Chat.java:44)
    at net.minecraft.server.v1_5_R3.NetworkManager.b(NetworkManager.java:292)
    at net.minecraft.server.v1_5_R3.PlayerConnection.d(PlayerConnection.java:109)
    at net.minecraft.server.v1_5_R3.ServerConnection.b(SourceFile:35)
    at net.minecraft.server.v1_5_R3.DedicatedServerConnection.b(SourceFile:30)
    at net.minecraft.server.v1_5_R3.MinecraftServer.r(MinecraftServer.java:581)
    at net.minecraft.server.v1_5_R3.DedicatedServer.r(DedicatedServer.java:226)
    at net.minecraft.server.v1_5_R3.MinecraftServer.q(MinecraftServer.java:477)
    at net.minecraft.server.v1_5_R3.MinecraftServer.run(MinecraftServer.java:410)
    at net.minecraft.server.v1_5_R3.ThreadServerApplication.run(SourceFile:573)
    Caused by: java.lang.IllegalArgumentException: World cannot be null
    at org.bukkit.WorldCreator.copy(WorldCreator.java:41)
    at com.gmail.thunderwaffemc.Collide.onCommand(Collide.java:127)
    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44)
    ... 15 more
    
    The code: (ps. line 127 is this code:)

    Code:java
    1.  
    2. Bukkit.createWorld(new WorldCreator(player.getName() + "-world").copy(Bukkit.getWorld("CollideTemplate")));
    3.  


    Thanks
     
  6. Offline

    Gamecube762

    You might would want to make a workaround if it cant find the template world. When it cant find a world, it returns null and the WorldCreator is unable to copy null. So lets just add a check if it is null or not:
    Code:java
    1. World template = bukkit.getWorld("CollideTemplate");
    2.  
    3. if (template==null) {player.sendmessage("Unable to create world!"); return false;}
    4. //Checks for null and ends the command with an error message if the world isn't found
    5. //any code below this if statement wont be ran because of return false;
    6.  
    7. Bukkit.createWorld(new WorldCreator(player.getName() + "-world").copy(template));

    This should help your problem =P

    Make sure that the world template name is correctly spelled and is capitalized correctly, getting worlds is case sensative.
     
    ThunderWaffeMC likes this.
  7. Offline

    ThunderWaffeMC

    Gamecube762

    I do get the error saying unable to find world even though there is clearly a world called "CollideTemplate"

    My code:

    Code:java
    1.  
    2. if (args.length == 1) {
    3. if (args[0].equalsIgnoreCase("start")) {
    4. if (!player.hasPermission("collide.start")) {
    5. getLogger().fine("Player " + player.getName() + " has no collide.start permission.");
    6. player.sendMessage(ChatColor.BLUE + "[Collide]" + ChatColor.RED + " You do not have permission to use this command!");
    7. return false;
    8. }
    9. World template = Bukkit.getWorld("CollideTemplate");
    10.  
    11. if (template==null) {player.sendMessage(ChatColor.BLUE + "[Collide] " + ChatColor.RED + "Unable to find world!"); return false;}
    12.  
    13. Bukkit.createWorld(new WorldCreator(player.getName() + "-world").copy(template));
    14. sender.sendMessage(ChatColor.BLUE + "[Collide] " + ChatColor.RED + "Generating new base!");
    15. }
    16. }
    17.  


    The world (proof):

    <img src="http://i43.tinypic.com/v4rpeb.png">
     
  8. Offline

    Gamecube762

    -----What I was going to post:
    Try to change the error message to this and test the command while you are in the TemplateWorld:
    Code:java
    1. player.sendMessage(ChatColor.BLUE + "[Collide] " + ChatColor.RED + "Unable to find world!" + "Current world: " + player.getWorld().getName());
    This is so you can see how Bukkit sees the name of the world and you could make sure its the same name.

    -----What I realized when I finished typing it: (Read this first, if you already have it, then read the other one).
    Make sure that you have the world loaded, you are going to need a multiworld plugin to do this(this plugin and so the players can join the worlds) if you don't already have one. Bukkit wont see the world with .getWorld("") if the world isn't loaded.
     
    ThunderWaffeMC likes this.
  9. Offline

    ThunderWaffeMC



    Thanks very much! All is working now with MultiWorld!
     
  10. Offline

    Gamecube762

    I would try this:
    Code:java
    1. if(Bukkit.getWorld(player.getName() + "-world") != null ) {//if the world isn't null, then it exists
    2. player.sendmessage("You world is already created, try /<command> instead.");//tell the player they already have one
    3. return true;//return true so its not showing command ussage(if set in plugin.yml)
    4. }

    So it checks for if the world isn't null, then it tells the player that it is allready created and to try a different command to go to their world.
    return true; ends the command (error message can be done by player.sendMessage() )
    return false; ends the command and tells the player the command usage(if its defined in the plugin.yml)
     
  11. Offline

    ThunderWaffeMC

    Gamecube762 chasechocolate It's actually quite strange that whenever it copies the world, it copies the default world before I had edited the world and built onto it and isn't showing anything I changed. Not sure why? Is there a way to save the template world before copying? I have tried restarting the server since then.
     
  12. Offline

    Gamecube762

    Using the command /save-all should force bukkit to save all of the worlds it has loaded and make sure when you are restarting the server use /stop. If you hit the 'x' to close the window it wont save everything.
     
  13. Offline

    ThunderWaffeMC


    Everytime I shut down the server I use "save-all" and then "stop". Doesn't seem to save the world data?

    Gamecube762 as you can see in this video I have made it loads the world before it was edited. So it copies the terrain and seed but not what I have edited to the world?

    (may still be uploading)

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 2, 2016
  14. Offline

    Gamecube762

    Could be that the WorldCreator is just copying the world data(seed,spawn,...) and not the contents of it. I havnt played around with creating worlds and I'm kind of busy to look into it right now, I can look into it when I get back.
     
  15. Offline

    ThunderWaffeMC


    Thanks. Just don't forget about me. I'll be waiting :)
     
  16. Offline

    Gamecube762

    Ok, so the WorldCreator only copies the world 'options'(seed,worldspawn,generator,gamerules). What you would need to do is copy the world's file and rename it to the new world. You may haft to take a step outside of the Bukkit API and use the Java IO. I found a thread that was trying to do a similar thing and copy a world, take a look at it and see how much it can help you. I'm still here if you need help. =P
     
    ThunderWaffeMC likes this.
  17. Offline

    ThunderWaffeMC

    Gamecube762 What do I write in the <collide template> and <play> area? Is it the world? (also is the directory right? "Collide Server" is the folder in where the world is. I tried adding the whole directory and I got errors (like C:\...\...\...)

    Code:java
    1.  
    2. File source = new File(System.getProperty("Collide Server.dir") + File.separator + "CollideTemplate");
    3. File destination = new File(System.getProperty("Collide Server.dir") + File.separator + "play");
    4.  
     
  18. Offline

    Gamecube762

    I haven't really played around with Java IO. I started learning Java by learning the Bukkit API XD I think I have an idea on how that works and how to do it, but ill get back to you on it tomorrow (currently 12:00am where I am).
     
    ThunderWaffeMC likes this.
  19. Offline

    Gamecube762

    ThunderWaffeMC
    Dont worry, I havnt forgotten about you.
    Code:java
    1. String templateName = "";//enter template world's name
    2. String newWorldName = player.getName() + "-world";//name of the world thats going to be made
    3.  
    4. File serverFolder = new File(System.getProperty("user.dir"));//server directory
    5. File templateFolder = new File(serverFolder + File.separator + templateName);//template world directory
    6. File newWorldFolder = new File(serverFolder + File.separator + newWorldName);//new player world directory
    This should help you with getting the folders of the worlds. Ive been trying to test this and been getting an error saying "access is denied" every time I use Files.copy(from,to). Anyone knows what the problem is on that? (code works, just files.copy returns with the error)
    Code:java
    1.  
    2. String templateName = "hub";
    3.  
    4. World template = Bukkit.getWorld(templateName);//if (template==null) {player.sendMessage(ChatColor.BLUE + "[Collide] " + ChatColor.RED + "Unable to find Template!"); return false;}
    5. if (template!=null) {Bukkit.unloadWorld(template, true);}//unload world to prevent issues while copying
    6.  
    7.  
    8. String newWorldName = player.getName() + "-world";
    9.  
    10. File serverFolder = new File(System.getProperty("user.dir"));
    11. File templateFolder = new File(serverFolder + File.separator + templateName);
    12. File newWorldFolder = new File(serverFolder + File.separator + newWorldName);
    13.  
    14. //create world section
    15. player.sendMessage("creating");//create folders
    16.  
    17. if (!newWorldFolder.exists()){
    18. newWorldFolder.mkdir();
    19. new File(newWorldFolder.getPath() + File.separator + "data").mkdirs();
    20. new File(newWorldFolder.getPath() + File.separator + "players").mkdirs();
    21. new File(newWorldFolder.getPath() + File.separator + "region").mkdirs();
    22. }
    23.  
    24. player.sendMessage("copying");//copy files into the folders
    25. try {
    26. Files.copy(new File(templateFolder.getPath() + File.separator + "data"), new File(newWorldFolder.getPath() + File.separator + "data"));
    27. Files.copy(new File(templateFolder.getPath() + File.separator + "region"), new File(newWorldFolder.getPath() + File.separator + "region"));
    28. Files.copy(templateFolder, newWorldFolder);
    29. } catch (IOException e) {
    30. e.printStackTrace();
    31. player.sendMessage("error in copying world");
    32. getLogger().info("serv:"+serverFolder.getPath());
    33. getLogger().info("From:"+templateFolder.getPath());
    34. getLogger().info("To:"+newWorldFolder.getPath());
    35. return true;//ends command on error
    36. }
    37.  
    38. player.sendMessage("preventing problems");//remove the copied id so it can load properly
    39. File CopiedWorldUID = new File(newWorldFolder + File.separator + "uid.dat");
    40. if (CopiedWorldUID.exists()) {CopiedWorldUID.delete();}
    41.  
    42. player.sendMessage("loading world");//tells Bukkit to create the world with the same data as the template
    43. Bukkit.createWorld(new WorldCreator(templateName).copy(template));//this will let Bukkit load it and have the same seed for generation
    44.  
    45.  
    46. player.sendMessage("done");
    Error occurs on lines 26-28.
     
  20. Offline

    ThunderWaffeMC

    Gamecube762 Thanks very much! I will be sure to add you to some type of credits. I'll try find out what the errors are and I can tell you the fix if you want (if I do fix it).
     
  21. Offline

    ThunderWaffeMC

    Gamecube762 Sorry but what do I use for user.dir? I tried:

    File serverFolder = new File(System.getProperty("C:/Users/Toshiba/My Documents/zServers/Collide Server/"));//server directory

    but I get a nullpointerexception. What did I do wrong?
     
  22. Offline

    Gamecube762


    Code:java
    1. File serverFolder = new File(System.getProperty("user.dir"));
     
    ThunderWaffeMC likes this.
  23. Offline

    ThunderWaffeMC

    Oh so I don't write in the directory of the folder and it automatically finds it with user.dir?
     
  24. Offline

    Gamecube762

    It grabs the folder that the bukkit.jar was ran from. Its help full so you don't haft to write the file path for where ever you move it to.
     
    ThunderWaffeMC likes this.
  25. Offline

    ThunderWaffeMC

    Gamecube762 Thanks so much! Also, did you find out the error from files.copy?
     
  26. Offline

    Gamecube762

    ThunderWaffeMC Sorry, havn't gotten time to look into that, been very busy lately...
     
  27. Offline

    ThunderWaffeMC

    Gamecube762 Okay that's fine. Thanks anyway.

    Gamecube762 Also did you import "import com.google.common.io.Files;" or the Java NIO import?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 2, 2016
  28. Offline

    Gamecube762


    Code:java
    1. import java.io.File;
    2. import java.io.IOException;
    3. import java.io.OutputStream;

    Those are the imports that I used.
     
  29. Offline

    ThunderWaffeMC

    Gamecube762 So then what did you use for files.copy?
     
  30. Offline

    Gamecube762

    That part came from the com.google.---------, I dint see it because it was hiding underneath the bukkit imports...
     
    ThunderWaffeMC likes this.
Thread Status:
Not open for further replies.

Share This Page