Rrrrrrollback not working

Discussion in 'Plugin Development' started by xTrollxDudex, Oct 2, 2013.

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

    xTrollxDudex

    Yeah... So I have my rollback handling class here:
    PHP:
    package com.gmail.woodyc40.battledome.handlers;

    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.entity.LivingEntity;

    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;

    public class 
    RollbackHandler{
        private List<
    bdBlockblocks = new LinkedList<bdBlock>();
        private List<
    LivingEntityentities = new LinkedList<LivingEntity>();

        private class 
    bdBlock{
              final 
    Location l;
              final 
    byte data;
              final 
    Material type;
         
              public 
    bdBlock(Block b){
                    
    this.b.getLocation();
                    
    this.data b.getData();
                    
    this.type b.getType();
              }
              
              public 
    void parse(){
                    
    Block b l.getBlock();
                    
    b.setType(type);
                    
    b.setData(data);
              }
        }

        public 
    void add(LivingEntity ent){
            
    entities.add(ent);
        }

        public 
    void add(Block b){
             
    bdBlock bd = new bdBlock(b);
             
    blocks.add(bd);
        }
        
        public 
    void rollback(){
            
    Iterator<bdBlockit blocks.iterator();
            while(
    it.hasNext()){
                  
    it.next().parse();
            }

            
    Iterator<LivingEntityiterator entities.iterator();
            while(
    iterator.hasNext()){
                
    iterator.next().getWorld().spawn(iterator.next().getLocation(), iterator.next().getClass());
            }
        }
    }
    And the listener here:
    PHP:
    @EventHandler
        
    public void onLeave(PlayerQuitEvent e){
            
    Arena a BattleManager.getBM().getPlayerArena(e.getPlayer());
        
            if(
    == null){
                return;
            }else{
                
    BattleManager.getBM().removePlayer(e.getPlayer());
            }
        }

        @
    EventHandler
        
    public void onSignClick(PlayerInteractEvent e){
            if(
    e.getClickedBlock().getType().equals(Material.SIGN) || e.getClickedBlock().getType().equals(Material.SIGN_POST) || e.getClickedBlock().getType().equals(Material.WALL_SIGN)){
                
    Sign s = (Signe.getClickedBlock();
                
    int i 0;
                try{
                    
    Integer.parseInt(s.getLine(1));
                }catch (
    NumberFormatException ex){
                    
    e.setCancelled(true);
                }
                
    Arena a BattleManager.getBM().getArena(i);
                if(
    != null){
                    if(
    a.getState().equals(Arena.Game.LOBBY))    BattleManager.getBM().addPlayer(e.getPlayer(), i);
                    else {
                        if(
    a.getState().equals(Arena.Game.BUILD) || a.getState().equals(Arena.Game.DEATHMATCH) || a.getState().equals(Arena.Game.FIGHT))    a.setSpectator(e.getPlayer());
                        else if(
    a.getState().equals(Arena.Game.DISABLED) ||a.getState().equals(Arena.Game.NOT_JOINABLE) || a.getState().equals(Arena.Game.UNKNOWN) || a.getState().equals(Arena.Game.STARTING) || a.getState().equals(Arena.Game.ENDGAME))    e.setCancelled(true);
                    }
                }
            }
        }

            @
    EventHandler
            
    public void onPlayerDeath(PlayerDeathEvent e) {
                    
    // TODO Maybe customize death message?!
                    
    if(BattleManager.getBM().isInGame(e.getEntity())){
                            
    Arena a BattleManager.getBM().getPlayerArena(e.getEntity());
                            
    a.setSpectator(e.getEntity());
                    }
            }

            
    // If a spectator wants to block an arrow...
            
    @EventHandler
            
    public void onPlayerHurtPlayer(EntityDamageByEntityEvent event) {
                    
    Entity entityDamager event.getDamager();
                    
    Entity entityDamaged event.getEntity();
                    if (
    entityDamager instanceof Arrow) {
                            if (
    entityDamaged instanceof Player
                                            
    && ((ArrowentityDamager).getShooter() instanceof Player) {
                                    
    Arrow arrow = (ArrowentityDamager;
                                    
    Vector velocity arrow.getVelocity();
                                    
    Player shooter = (Playerarrow.getShooter();
                                    
    Player damaged = (PlayerentityDamaged;
                                    if (
    BattleManager.getBM().isSpectator(damaged)) {
                                            
    damaged.teleport(entityDamaged.getLocation().add(050));
                                            
    damaged.setFlying(true);
                                            
    Arrow newArrow shooter.launchProjectile(Arrow.class);
                                            
    newArrow.setShooter(shooter);
                                            
    newArrow.setVelocity(velocity);
                                            
    newArrow.setBounce(false);
                                            
    event.setCancelled(true);
                                            
    arrow.remove();

                        return;
                                    }
                            }
                    }

            if(
    entityDamager instanceof Player && entityDamaged instanceof Player){
                if(
    BattleManager.getBM().isOnTeam((PlayerentityDamaged, (PlayerentityDamager)){
                    ((
    PlayerentityDamager).sendMessage(BattleManager.getBM().bd "Don't kill your teammate!");
                    
    event.setCancelled(true);
                }
            }
            }
        
            @
    EventHandler
        
    public void onBreak(BlockBreakEvent e){
            
    Player p e.getPlayer();
            
    Arena a BattleManager.getBM().getPlayerArena(p);
            
            if(
    e.getBlock().getType().equals(Material.GLASS)){
                
    e.setCancelled(true);
                
    p.sendMessage(BattleManager.getBM().bd "HEY! Stay within the dome!");
                return;
            }
            
            if((!(
    BattleManager.getBM().isInGame(p))) || (ErrorHandler.getEh().validateArena(a.getId(), truep))){
                return;
            }else{
                
    a.getRollbackHandle().add(e.getBlock());
            }    
        }
        
        @
    EventHandler
        
    public void onPlace(BlockPlaceEvent e){
            
    Player p e.getPlayer();
            
    Arena a BattleManager.getBM().getPlayerArena(p);
            
            if(
    e.getBlock().getType().equals(Material.GLASS)){
                
    e.setCancelled(true);
                
    p.sendMessage(BattleManager.getBM().bd "HEY! This block is not allowed to be placed!");
                return;
            }
            
            if((!(
    BattleManager.getBM().isInGame(p))) || (ErrorHandler.getEh().validateArena(a.getId(), truep))){
                return;
            }else{
                
    a.getRollbackHandle().add(e.getBlockReplacedState().getBlock());
            }
        }
        
        @
    EventHandler
        
    public void onBurn(BlockBurnEvent e){
            
    Arena a BattleManager.getBM().getBlockArena(e.getBlock());
            
            if(
    == null){
                return;
            }else{
                
    a.getRollbackHandle().add(e.getBlock());
            }
        }   
        
        @
    EventHandler
        
    public void onFade(BlockFadeEvent e){
            
    Arena a BattleManager.getBM().getBlockArena(e.getBlock());
            
            if(
    == null){
                return;
            }else{
                
    a.getRollbackHandle().add(e.getBlock());
            }
        }
        
        @
    EventHandler
        
    public void onForm(BlockFormEvent e){
            
    Arena a BattleManager.getBM().getBlockArena(e.getBlock());
            
            if(
    == null){
                return;
            }else{
                
    a.getRollbackHandle().add(e.getBlock());
            }
        }

        @
    EventHandler
        
    public void onDecay(LeavesDecayEvent e){
            
    Arena a BattleManager.getBM().getBlockArena(e.getBlock());
            
            if(
    == null){
                return;
            }else{
                
    a.getRollbackHandle().add(e.getBlock());
            }
        }
        
        @
    EventHandler
        
    public void onEntityForm(EntityChangeBlockEvent e){
            
    Arena a BattleManager.getBM().getBlockArena(e.getBlock());
            
            if(
    == null){
                return;
            }else{
                
    a.getRollbackHandle().add(e.getBlock());
            }
        }
        
        @
    EventHandler
        
    public void onIgnite(BlockIgniteEvent e){
            
    //TODO Remove the fire instead of the block
            
    Arena a BattleManager.getBM().getBlockArena(e.getBlock());
            
            if(
    == null){
                return;
            }else{
                
    a.getRollbackHandle().add(e.getBlock());
            }
        }

        
    //TODO log water/lava, rollback, maybe by removing source block?

        
    @EventHandler
        
    public void onPhysics(BlockPhysicsEvent e){
            
    //TODO
        
    }
        
        
    //TODO Log pistons, log blocks moved by pistons, log piston movement/retract

        
    @EventHandler
        
    public void onSpread(BlockSpreadEvent e){
            
    //TODO
        
    }
    }
    Don't worry, the code is all correct, no errors on IntelliJ, and I have debugged it. What happened was it tarted rolling back all the blocks that were never placed by me, and kept looping infinitely until my client got an End of Stream. Then, it threw a NoSuchElementExceotion on the debug line :p

    This makes no sense at all....

    ALSO, anyone have suggestions for logging lava and water and pistons (and how to retract and extend them, maybe using setPowered(Boolean) or something)

    xTrollxDudex
    Bump. No replies?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 4, 2016
  2. are you rolling back entire maps? if so, there are other methods.
     
  3. Offline

    FozZeW

    @xTrollxDudex
    Use multiverse api to rollback multiverse worlds then you don't need to rollback block by block
     
  4. Offline

    Garris0n

    Trust me, logging everything and rolling it back is not the way you want to go about this. It's not reliable and you shouldn't do it without resetting the world afterwards anyway and only using it to constantly reconstruct a map while the game is going on. You also probably shouldn't be storing LivingEntities. And your spectator-block-arrow code should spawn the new arrow at the location of the old arrow. And post the code for the custom block you're using.
     
  5. Offline

    TomTheDeveloper

    Don't rollback by logging everything. Think about gravel, when it falls, your location of the block is wrong so it would cause a bad rollback.
     
  6. Offline

    Goblom

    Multiverse Beta has a clone world method.


    So clone the world, then when you want to roll back delete the cloned world and then clone the world again
     
  7. Also call you rollback plugin "Rick 'Rolledback". I'm sure it will work 100 % then.
     
    Hoolean and Rprrr like this.
  8. Offline

    Rprrr


    I can confirm this.
     
  9. Offline

    xTrollxDudex

    Not exactly the answers I was expecting...
    It's not a rollback plugin, it's a part of a plugin
    I'll find a way :p
     
  10. Offline

    Tirelessly

    Well bdBlock.parse() does nothing, that might be a part of it (I haven't read the whole thing)
     
  11. Offline

    xTrollxDudex

    Tirelessly
    Gets the block at the location and sets the type and data. I'll try a different method later.

    Glad to see someone that is willing to help with the issue I'm having instead of suggesting numerous workarounds.
     
  12. Offline

    Tirelessly

    That actually makes sense, nevermind then
     
  13. Offline

    Garris0n

    That's why I didn't actually help you. I have no idea what that parse method does exactly.
    Wait nevermind, I'm an idiot...reading it.

    Okay, have you tried actually figuring out where these magic blocks came from? We can't exactly debug it for you without the plugin, but I don't really see anything wrong with the code.
     
  14. Offline

    xTrollxDudex

    You don't need the plugin to debug it. a.getRollbackHandle() returns the instance of RollbackHandler running on the arena object a, so basically you can use the listener to place blocks to rollback into the RollbackHandler and test it with those two classes with a command to rollback-test it...
     
  15. Offline

    Garris0n

    Yeah I realize if I really wanted to I could rewrite the plugin, but what I meant was have you done any debugging to try to find the source of these blocks you say you didn't place. Perhaps one of the events is firing when you don't know about it, etc.
     
  16. Offline

    TomTheDeveloper

    xTrollxDudex

    The map you need to rollback, is it a small map? Because when it is a small map, I have an idea u can use!
     
  17. Offline

    xTrollxDudex

    TomTheDeveloper
    It between 200-500 blocks radius, is that "small" enough?
     
  18. Offline

    TomTheDeveloper

    xTrollxDudex Hmm, depends on how many blocks can break/placed.....

    My idea:
    First, when the server starts up, you need to put every block that can change in a hashmap with its type. (Don't put the air-type blocks in it.) Then you can check those with a repeating task, 1 by 1, or 100 by 100 ever second/tick. If a blocktype is changed, you just replace it by the type in the hashmap.

    For the AIR-blocks, you can just put them also in the same hashmap if you want, but you can also do this:
    Hmmm, weird, a few seconds ago I had a nice idea about the air blocks, but I forgot it completly. Hopefully I will remember it tomorrow!
     
Thread Status:
Not open for further replies.

Share This Page