1.16.5 Time based command (ex: you have 10 seconds to /confirm or /deny)

Discussion in 'Spigot Plugin Development' started by LetsGoRidePandas, Jun 10, 2021.

  1. Hi everyone, this is my first time here, so hopefully I formatted everything properly. What I'm looking for is at least a push in the right direction or suggestions on how to do this. So here's what I'm trying to do.

    I'm making a simple town plugin and I'm almost finished. All I need is to make the commands to invite and accept/deny the invitation (so /mayor invite [player] and /towninvite accept|deny). I want to make it so /towninvite only works for the invited player and only works for a specified amount of time like 5 minutes.

    I'ved look into hashmaps and they seem like they might work (kind of like a reverse cooldown) but I'm not sure the best way to implement that for this situation

    I've also looked at persistantdatacontainers and that seems like it would work too but it seems like I can't set an expiration on that.

    Does anyone know how other town plugins do this or at least have any ideas on how to go about this?
     
  2. Strahan

    Benefactor

    You'd want to store a timestamp when the invite was issued, then when you accept it check if stored timestamp >= duration and if so, bounce it as expired. If not, process it.
     
  3. I kinda figured it would be like that. I'm just not sure how to attach that timestamp to the player and then delete it once it expires
     
  4. runTaskLater maybe can help you
     
  5. How have you implemented the invitation itself? If it is an object, I would implement this behavior by storing the system time when each invitation is created in a variable inside the invitation, create a <UUID, Invitation> hashmap, then when a player does /towninvite accept you first check if the hashMap containsKey(UUID) (check if the player has an active invitation), then check if the invitation has expired (compare the stored time to the current time). Then, if it's not expired add the player to the town. Regardless of if it's expired, then delete the UUID key from the hashmap. The only downside of this is that if a player is invited to two different towns, the most recent invitation will overwrite the older one (key can only have one value in the hashmap).
     
  6. try using java Cache object for instance
    Code (Java):
    private final Cache<Player, Invitation> invitation = CacheBuilder.newBuilder()
            .expireAfterWrite(5, TimeUnit.MINUTES)
            .build();
     
    • Informative Informative x 4
    • Useful Useful x 1
  7. Thanks for the suggestions everyone. I'll try some of them out and let you know how it goes
     
  8. I'm quite sure this is a guava class, if I'm not mistaken.
    It's not too hard to make your own class for it, I'd personally avoid using external libraries if you don't have to.

    If you don't want to make your own cache object, or if you don't want to use Guava's cache object, you could do something like:
    Code (Text):
    private final Map<UUID, Long> map = new HashMap<>();

    public void containsUUID(UUID uuid) {
        if(map.containsKey(uuid) && System.currentTimeMillis() - map.get(uuid) >= 0) {
            this.map.remove(uuid);
            return false;
        }

        return true;
    |

    public void registerUUID(UUID uuid, long cooldown) {
        this.map.put(uuid, System.currentTimeMillis() + cooldown);
    }
    (untested piece of code)

    edit: remove uuid from map
     
  9. Strahan

    Benefactor

    Depends how fancy you wanna get. I'd probably make a class called Invitation and use that to map out who is getting the invite, who it is from, what it's for, time tracking and such. Then just have a collection of Invitation objects in a centrally accessible class.
     
    • Agree Agree x 1