Memory unit help??

Discussion in 'Plugin Development' started by Cystalize, Aug 12, 2012.

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

    Cystalize

    So I asked this question yesterday and I did get answers, but none of them explained exactly how the whole code worked. I was hoping someone could explain to me how HashMaps, HashSets, ArrayLists, Strings, and Longs work/are. I sort of know that HashMaps are used to store user data or something right?

    I am making a plugin that will stop spam. I'm going to need some sort of memory unit to record each time a player sends a message, and then it will detect if it is spam or not. I have no clue on how to make this, and if you do, please leave an explanation so that I can understand what exactly the code is doing. Understanding is a little more important than just copy/pasting.

    Theres also another feature in my plugin that will limit the time a player can reconnect. For example, if the player disconnects and tries to reconnect within a configurable amount of time, it will kick the player leaving a message like "You cannot reconnect until %time% seconds have passed!"

    I already know how to do the @EventHandler part. What I need to know is how I could add a storage/memory unit that will record how many times a player sends a message, what message the player is sending, how many seconds a player has until the player can reconnect, how many times a player must be marked with spam until the player is kicked. Things like that. PLEASE leave explanations too! Thanks guys, I appreciate it.
     
  2. Offline

    Jogy34

    1.
    Hashmaps: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/HashMap.html
    HashSets: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/HashSet.html
    ArrayLists: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/ArrayList.html
    Strings: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html
    Longs: http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Long.html

    I have experiance with all of these except HashSets so if you are still having trouble with them after looking at the links I could probably answer any questions you have about them.

    2.
    You would want to us an AsyncPlayerChatEvent which is fired every time a player types a message in the chat. As for after that you would probably need to do something like, retrieve the message and check for what your definition of spam is then if it meets your criteria cancel the event.

    3.
    that would be handled in a PlayerJoinEvent and a PlayerLeaveEvent. In the leave event you would want to record the player's name in a list, probably an ArrayList, then schedule a delayed task to take them out. In the join event if the player is still in the list then cancel the event and I believe that you can change the reason of why they can't join.

    4.
    In my opinion you should learn more java before attempting writing plugins. This comes from you not having knowledge of Strings which - in almost an java class, book, tutorial - is one of the things it covers twords the start.
     
    lordaragos likes this.
  3. Offline

    Deleted user

    In your main class create an int.

    Code:
    //Time is in seconds
    public static int logout_timer = 15;
    
    Incase you don't know you're main class 'extends JavaPlugin' and has onEnable/Disable.

    Now in your Listener class, the class that 'implements Listener' add this:

    Code:
    private HashMap<String, Long> logout_cooldown = new HashMap<String, Long>();
     
    @EventHandler
    public void onPlayerLogout(PlayerQuitEvent event){
    Player p = event.getPlayer();
    logout_cooldown.put(p.getName(), System.currentTimeMillis());
    }
     
    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event){
    Player p = event.getPlayer();
     
    if (logout_cooldown.containsKey(p.getName())) {
    event.setJoinMessage(null);
    }
    }
     
    @EventHandler
    public void onPlayerLogin(PlayerLoginEvent event){
    Player p = event.getPlayer();
     
    if (logout_cooldown.containsKey(p.getName())) {
    long diff = (System.currentTimeMillis() - logout_cooldown.get(p.getName())) / 1000;
    if (diff < main.logout_timer) {
    event.disallow(Result.KICK_OTHER, ChatColor.RED + "You may not login for another " + (main.logout_timer - diff) + " second" + (main.logout_timer - diff != 1 ? "s" : "" + "!"));
    return;
    }
    logout_cooldown.put(p.getName(), System.currentTimeMillis());
    }
    }
    
    Tested it myself it works! I'm tired and need to shower and then bed for school tomorrow but if you'd like an explanation on what these things do so you may actually learn, just ask!
     
    Cystalize likes this.
  4. Offline

    Cystalize

    Thanks for writing this up :) Oddly enough, it's actually not working for me D: I didn't get any errors in eclipse or in the console after copying/pasting this and changing 'main' from 'main.logout_timer' to the name of my plugin. Here's the listener code:


    Code:
    public class SpamPlayerListener
        implements Listener
    {
        private HashMap<String, Long> logout_cooldown = new HashMap<String, Long>();
       
        @EventHandler
        public void onPlayerLogout(PlayerQuitEvent event){
        Player p = event.getPlayer();
        logout_cooldown.put(p.getName(), System.currentTimeMillis());
        }
       
        @EventHandler
        public void onPlayerJoin(PlayerJoinEvent event){
        Player p = event.getPlayer();
       
        if (logout_cooldown.containsKey(p.getName())) {
        event.setJoinMessage(null);
        }
        }
       
        @EventHandler
        public void onPlayerLogin(PlayerLoginEvent event){
        Player p = event.getPlayer();
       
        if (logout_cooldown.containsKey(p.getName())) {
        long diff = (System.currentTimeMillis() - logout_cooldown.get(p.getName())) / 1000;
        if (diff < Spamicide.logout_timer) {
        event.disallow(Result.KICK_OTHER, ChatColor.RED + "You may not login for another " + (Spamicide.logout_timer - diff) + " second" + (Spamicide.logout_timer - diff != 1 ? "s" : "" + "!"));
        return;
        }
        logout_cooldown.put(p.getName(), System.currentTimeMillis());
        }
        }
       
    }
    The only thing I changed was 'main' from 'main.logout_timer'. I figured it was a reference to me to change it into the main class name. I even tried making a variable in the listener class like this 'Spamicide main;' that didn't work. I also did 'Spamicide main;' 'public SpamPlayerListener(Spamicide instance) {main = instance;}. Sorry if that looked a bit messy.

    Yeah I probably should have a little more knowledge on Java before attempting to make plugins. From my understanding, a String is like a variable for words or something? I was asking because I wasn't too sure about it. Thanks for the links! I'm sure I can learn a lot from those.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 27, 2016
  5. Offline

    Deleted user

    Can I see your main class please?

    OT: Do you have saros?
     
  6. Offline

    Cystalize

    Nope I just have eclipse.

    Main class:
    Code:
    package me.Cystalize.spamicide;
     
    import java.io.File;
    import java.util.ArrayList;
    import java.util.Properties;
    import java.util.logging.Logger;
     
    import me.Cystalize.spamicide.listeners.ProfanityPlayerListener;
    import me.Cystalize.spamicide.listeners.CapsPlayerListener;
     
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.command.ConsoleCommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class Spamicide extends JavaPlugin
    {
        static String dir = "plugins/Spamicide";
        static File spamFile = new File(dir + File.separator + "ProfanityList");
        static Properties prop = new Properties();
        public ArrayList<String> Profanity = new ArrayList();
        final String defaultProfanity = "crap,shit";
        public static int logouttimer = 15;
        public static final Logger log = Logger.getLogger("Minecraft");
       
        public void onEnable() {
            PluginManager pm = getServer().getPluginManager();
            pm.registerEvents(new ProfanityPlayerListener(this), this);
            pm.registerEvents(new CapsPlayerListener(this), this);
            getConfig().options().copyDefaults(true);
            saveConfig();
            log.info("[Spamicide]  has successfully enabled!");
        }
       
       
       
       
        public void onDisable() {
            log.info("[Spamicide]  has been disabled!");
        }
       
       
       
       
        public ArrayList<String> parseArray(String in, char delimiter) {
            ArrayList parsed = new ArrayList();
            String build = "";
            int count = 0;
            int len = in.length();
            while (count < len) {
                while ((count < len) && (in.charAt(count) != delimiter)) {
                    build = build + in.charAt(count);
                    count++;
                }
                parsed.add(build);
                build = "";
                count++;
            }
            return parsed;
        }
       
       
       
       
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            boolean op = false;
            if ((sender instanceof Player)) {
                Player player = (Player)sender;
                op = player.isOp();
            }
            if ((label.equalsIgnoreCase("spam")) &&
                    ((op) || ((sender instanceof ConsoleCommandSender))) &&
                    (args.length == 1) && (args[0].equalsIgnoreCase("reload"))) {
                reloadConfig();
                log.info("[Spamicide]  Configuration successfully reloaded!");
                if (sender.hasPermission("spamicide.admin")) {
                    sender.sendMessage(ChatColor.RED + "[Spamicide] " + ChatColor.GREEN + " Configuration successfully reloaded!");
                }
                return true;
            }
            return false;
        }
    }
     
  7. Offline

    Deleted user

    You're not registering your class "SpamPlayerListener" as an Listener.
    Add this to your onEnable():
    Code:
    getServer().getPluginManager().registerEvents(new  SpamPlayerListener (), this);
    
    Tell me if that fixes it.. also Saros is a plugin for Eclipse not a program.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 27, 2016
  8. Offline

    Cystalize

    Omg it worked! :D AWESOME! Could you explain how it all worked? Were hashmaps needed for this operation? I have no clue how you got it to work.
     
  9. Offline

    Deleted user

    Alright here is the break down

    Hasmap that stores player data.
    Code:
        private HashMap<String, Long> logout_cooldown = new HashMap<String, Long>();
    
    When a player logs out put their name into the hashmap and start a timer for their name.
    Code:
        @EventHandler
        public void onPlayerLogout(PlayerQuitEvent event){
        Player p = event.getPlayer();
        logout_cooldown.put(p.getName(), System.currentTimeMillis());
        }
    
    When a player joins; if their name is in the hashmap still (meaning their timer is still running) then don't show a join message!
    Code:
        @EventHandler
        public void onPlayerJoin(PlayerJoinEvent event){
        Player p = event.getPlayer();
     
        if (logout_cooldown.containsKey(p.getName())) {
        event.setJoinMessage(null);
        }
        }
    
    When a player attempts to login; if their name is in the hashmap still (meaning their timer is still running) then kcik them and display how long before their timer is over.
    Code:
        @EventHandler
        public void onPlayerLogin(PlayerLoginEvent event){
        Player p = event.getPlayer();
     
        if (logout_cooldown.containsKey(p.getName())) {
        long diff = (System.currentTimeMillis() - logout_cooldown.get(p.getName())) / 1000;
        if (diff < Spamicide.logout_timer) {
        event.disallow(Result.KICK_OTHER, ChatColor.RED + "You may not login for another " + (Spamicide.logout_timer - diff) + " second" + (Spamicide.logout_timer - diff != 1 ? "s" : "" + "!"));
        return;
        }
        logout_cooldown.put(p.getName(), System.currentTimeMillis());
        }
        }
     
    }
    Confused on any of that?
     
    Cystalize likes this.
  10. Offline

    Cystalize

    Nope it all made total sense! Wow, you really helped me overcome a BIG obstacle that I was having with Java. Thank you SOOO much! I've seen other codes, but never a detailed explanation like this one. You rock man!
     
  11. Offline

    Deleted user

    Np, need anything else just pm me.
     
Thread Status:
Not open for further replies.

Share This Page