1.12.2 How to continuously run a piece of code and listen to commands

Discussion in 'Spigot Plugin Development' started by CabbageRoll_, Sep 27, 2020.

  1. I am still relatively new to plugin programming (and java overall) and im having this problem. I fully translated my C code into java but cannot replicate the main() function. It got this structure

    Wait for user
    Initialize game
    while(!gameover){
    listen to inputs
    do a common piece of code
    wait for x time
    }

    I turned listening to keyboard inputs to "/userinput input" command

    I tried multiple solutions but all of them either freeze the server, or throw a null pointer exception. I believe scheduler is what i need but there is a great lack of examples on how to use it. I dont know which part of code would be useful for solving the problem so i will attach the whole plugin source if you need it

    I believe spigot version doesnt matter, i chose 1.12.2 because of concrete

    I didnt post code right now because i am continuously trying to change and fix it.
     
    #1 CabbageRoll_, Sep 27, 2020
    Last edited: Sep 27, 2020
  2. P.S. Here's a general plugin tutorial, but the parts about setting up your environment and hooking into the Bukkit/Spigot API are out of date. The stuff about onEnable() and handling commands and permissions is still valid.

    https://bukkit.gamepedia.com/Plugin_Tutorial
     
  3. I am aware of how events work already (i am using playerjoin event to get the world)
    There is no mention of how to make a external function runnable (so outside of the plugin's onEnable completely or just partly, i need to delay it until player joins (later ideally, a /startgame command, but playerjoinevent can be a good start too) or its gonna continuously throw errors)
    I think you might want to see relevant code.

    I know it is a little bad but i am trying to work it out
    Pluginmain is the plugin's main
    Cmain is my old program's main
    Startgame and Playgame are my failed attempts at trying to fix it
    Other files are mostly irrelevant
    https://github.com/Cabbage-Roll/tetr.jar/tree/master/java
    This code is obviously non functional, i need some help on what should i look for.
    -------------------------------
    Update: i got the game to work by initializing game inside playerjoinevent, but i believe this is improper method and would cause issues, because the common code is still running inside onEnable. I still need to know how to activate it externally (and ideally, by command).
     
    #4 CabbageRoll_, Sep 27, 2020
    Last edited: Sep 27, 2020
  4. Take a look at the bukkit scheduler, there you can schedule tasks to run at specified times or on a constant interval. You could schedule a repeating task in onEnable.
     
  5. If you mean schedule a repeating task by start the task, i want to start it when the player requests it. Again, i find no tutorials on how to schedule a task outside of onEnable
    Sorry if i am not being specific on what i exactly want because i dont fully know the terminology, but you are not really giving me any helpful info either.
    In the current code, i have put the whole code i want to run inside onEnable and the only way to stop it is to restart the server.


    This is how my onEnable chunk looks right now. Sorry, i dont know how to embed code so i am going to put it in spoiler
    @Override
    public void onEnable() {
    System.out.println("Plugin started");
    getServer().getPluginManager().registerEvents(this, this);
    ///because of the underlying problems, the startgame command is useless
    this.getCommand("startgame").setExecutor(new Startgame());
    this.getCommand("sendinput").setExecutor(new Commandinput());

    Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
    @Override
    public void run() {
    ///repeating code
    }
    }, 0L, 1L);
    }
    What happens now:
    server starts
    player joins the server
    game initializes by the player join event
    repeating code repeats infinitely, and server must be closed to stop the game
    (player leaving and joining disrupts the game behaviour)

    What i want:
    command will initialize the game, after that it starts the repeating task
    repeating task kills itself when certain condition is met (gameover==true)
    code that goes after the repeating code
    (if player leaves, gameover=true automatically)

    If you know C language, read the main() function of this file to understand what i would actually like
    https://github.com/Cabbage-Roll/tetr.jar/blob/master/c/main.c
     
    #6 CabbageRoll_, Sep 27, 2020
    Last edited: Sep 27, 2020
  6. You can start and kill a BukkitRunnable from where ever you want.
    BukkitRunnable#cancel() will stop the runnable. This can also be called from within the runnable with this.cancel().

    And if you want to start your runnable on command call then just put the code piece to create it the command executor

    EDIT:
    Idk how much you know about object oriented programming but since you said you are new to java and you don’t know all of that terminology I’d guess not that much.
    It’s really essential for java so you should read a little bit about it. I don’t know any tutorials that well but this one didn’t look so bad:
    https://www.w3schools.com/java/java_oop.asp
     
    #7 MightyOne, Sep 27, 2020
    Last edited: Sep 27, 2020
  7. Well i know C and C++ (C++ is also object oriented). About the terminology, i mean plugin programming.
    Thank you all for the answers, i got it to work now. Here is the working code.
    Code (Text):

    public class Startgame implements CommandExecutor{
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            Cmain.initGame();
            Playgame.playgame();
            return true;
        }
    }
     
    Code (Text):

    public class Playgame {
        public static void playgame() {
            new BukkitRunnable(){
                 @Override
                 public void run() {
                    System.out.println("counter: "+Cmain.counter);
                    if(Cmain.counter >= 100){
                        if(!Position.isCollide(Position.x, Position.y + 1, Position.block_size)){
                            Moveblock.moveBlock(Position.x, Position.y + 1);
                            }else{
                                Cmain.placeBlock();
                                Cmain.checkPlaced();
                                Cmain.makenextblock();
                            }
                            Cmain.counter=0;
                    }
                    Cmain.counter+=10;
                   
                    if(Cmain.gameover) {
                        this.cancel();
                    }
                 }
            }.runTaskTimer(Pluginmain.plugin, 0, 5);
        }
    }

     
     
    #8 CabbageRoll_, Sep 27, 2020
    Last edited: Sep 27, 2020