Tracking player movement of a player with specific conditions

Discussion in 'Plugin Development' started by etusa, Jan 4, 2020.

  1. Offline


    The plugin ("peek") I'm making grants spectator gamemode when you call the command and teleports the player back to their original position when they reinitiate the command. This part works fine.

    At the moment the plugin works as follows:
    (if no player file found, create initial datafile)
    check wether the "peek" mode is activated from player file
    if no -> update file with necessary variables, activate specator
    if yes -> teleport player, disable spectator, update file

    My main class atm only checks for plugin folders and creates them if necessary and calls upon the another class (new PeekCommand(this)), which implements CommandExecutor.

    I would like to track the position of the players who have the plugin activated. I'm creating a range check from their original position and teleporting them back a bit if they cross a certain range. (Basically the plugin grants a limited range spectator mode mainly to be used to troubleshoot builds or have different angles for builds more reasonably.)

    Two reasonable ways to track, that I see.

    1. Track players who have a certain variable on in the yml file (the pluging creates player specific files to keep track of variables upon command). Tracking this would mean looping the plugin all the time in the back? How to achieve that? Or are the plugins always "on" anyways, checking for met conditions? Some from of eventhandling? Currently not in the know how to properly implement eventhandling


    2. Create a loop that activates when the plugin is called (and such gamemode changed) and ends when the plugin is called again. That would require changing the structure for the plugin to check joining players status too, to account for disconnecting while peek mode activated. I assume this could be a decent way to do this. Can I just put a loop that runs when the mode is activated, and that ends when it receives another /peek? Not sure how to do that -- can the player call the command again when it's still running on a loop?

    ( 3. A better way that some wise wizard might hint me towards to)

    I'm very new to Spigot API - actually started a couple hours ago - and rusty with programming, so I'm not sure how to implement either in a plugin. Basically I don't know how to implement continuous checks in a plugin. Being as efficient is obviously a goal, though many players won't be using this concurrently.

    The math for the ranges etc is easy, I only need some hints how to track the player movement properly and efficiently. I tried to google around but didn't feel confident enough in my understanding of anything I found, and I didn't find much. I can paste the code if asked, but didn't feel like it was necessary for this. Tracking every players movement seems silly, as we have conditions we can check before doing that.

    If anyone is interested, one feature I haven't yet decised on is how to handle possible abuse. Why I need to think and research about this more is because I don't want the command to be used to glitch out of situations (for example suffocation trap, lava, on the same block with loads of mobs etc). Maybe I try to add a check if they have taken damage recently, or maybe more simply a) there can't be entities within his activation coordinates and b) their activation coordinates must be air blocks c) they must be full hp. They are limiting but not plugin breaking (assuming there are air blocks in the nether and end) and remove a lot of the abusing, I think. Probably a good thing to add is also to check wether they are stationary, so it can't be abused in falling. Not sure how to implement that either, yet. I also might add some limit or cost to the usage (1 diamond from inventory every 5 uses etc), as I prefer vanilla experiences but feel like a bit of "cheating" could add some fun to the experience.
    Last edited: Jan 4, 2020
  2. Offline


    I would not advice using files for this because it makes things complicated and because reading from and writing to files is somewhat expensive.
    Using files is only necessary when you need your data to be stored after server restarts, which I don't think is the case for you.

    I would advice to use a Set of Player's to keep track of which players are spectating. When using the peek command, you can add players to and remove players from that set.
    You can use Bukkit.getScheduler().scheduleSyncRepeatingTask( .... ) to register a task that will be run repeatedly. In your case, I would run it every second and let the task loop over all spectating players and check if they didn't go to far.
    You should listen for the PlayerQuitEvent (or something similar) to check if players are disconnecting while spectating. If so, you should remove them from the set, set them back to survival mode and teleport them back to their start position. (This will require you to learn how to use event handlers, but you can't really avoid that.)
    Finally, you should use the onDisable() method of your plugin. That will be fired whenever your plug-in is disabled (so when the server stops). In there, you should teleport all players back and set their gamemode back to survival mode.

    I might have forgotten some annoying things you need to keep track of, but this should work reasonably well.

Share This Page