// when a painting is placed...
  @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
  public void onPaintingPlace(PaintingPlaceEvent event) {
    // FEATURE: similar to above, placing a painting requires build permission in the claim

    // if the player doesn't have permission, don't allow the placement
    String noBuildReason =
        GriefPrevention.instance.allowBuild(event.getPlayer(), event.getPainting().getLocation());
    if (noBuildReason != null) {
      event.setCancelled(true);
      GriefPrevention.sendMessage(event.getPlayer(), TextMode.Err, noBuildReason);
      return;
    }

    // otherwise, apply entity-count limitations for creative worlds
    else if (GriefPrevention.instance.creativeRulesApply(event.getPainting().getLocation())) {
      PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getName());
      Claim claim =
          this.dataStore.getClaimAt(event.getBlock().getLocation(), false, playerData.lastClaim);
      if (claim == null) return;

      String noEntitiesReason = claim.allowMoreEntities();
      if (noEntitiesReason != null) {
        GriefPrevention.sendMessage(event.getPlayer(), TextMode.Err, noEntitiesReason);
        event.setCancelled(true);
        return;
      }
    }
  }
  // when a creature spawns...
  @EventHandler(priority = EventPriority.LOWEST)
  public void onEntitySpawn(CreatureSpawnEvent event) {
    LivingEntity entity = event.getEntity();

    // these rules apply only to creative worlds
    if (!GriefPrevention.instance.creativeRulesApply(entity.getLocation())) return;

    // chicken eggs and breeding could potentially make a mess in the wilderness, once griefers get
    // involved
    SpawnReason reason = event.getSpawnReason();
    if (reason != SpawnReason.SPAWNER_EGG
        && reason != SpawnReason.BUILD_IRONGOLEM
        && reason != SpawnReason.BUILD_SNOWMAN) {
      event.setCancelled(true);
      return;
    }

    // otherwise, just apply the limit on total entities per claim (and no spawning in the
    // wilderness!)
    Claim claim = this.dataStore.getClaimAt(event.getLocation(), false, null);
    if (claim == null || claim.allowMoreEntities() != null) {
      event.setCancelled(true);
      return;
    }
  }
Пример #3
0
  /** Computes the scores for all features on the board. */
  public List<FeatureScore> computeFinalScores() {
    // we use this set to track which claim groups we've already processed
    Set<Integer> processedClaims = Sets.newHashSet();

    // check all features on all tiles for potential scores
    List<FeatureScore> scores = Lists.newArrayList();
    for (Placement play : _plays.values()) {
      Claim claim = getClaim(play);
      for (Feature f : play.tile.terrain.features) {
        // ignore features that aren't completable (e.g. GRASS)
        if (!COMPLETABLES.contains(f.type)) continue;

        // determine whether or not we've already processed this claim
        int group = claim.getClaimGroup(f);
        if (processedClaims.contains(group)) continue;
        processedClaims.add(group);

        // determine who will earn points for this claim
        Set<Integer> scorers = getScorers(group);
        // if we have no scorers, the feature is unclaimed; skip it
        if (scorers.isEmpty()) continue;

        // if we made it this far, we may have something to report
        int score = computeFeatureScore(play, f);
        if (score != 0) {
          scores.add(new FeatureScore(f, scorers, score, getPiecens(group)));
        }
      }
    }

    return scores;
  }
Пример #4
0
 /** Remove the given claims in one go. */
 @Transactional
 @Secured(BF_CLAIM_DELETE)
 public void remove(Collection<Claim> claims) {
   for (Claim claim : claims) {
     claim.remove();
   }
 }
  // when a vehicle is damaged
  @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
  public void onVehicleDamage(VehicleDamageEvent event) {
    // all of this is anti theft code
    if (!GriefPrevention.instance.config_claims_preventTheft) return;

    // determine which player is attacking, if any
    Player attacker = null;
    Entity damageSource = event.getAttacker();
    if (damageSource instanceof Player) {
      attacker = (Player) damageSource;
    } else if (damageSource instanceof Arrow) {
      Arrow arrow = (Arrow) damageSource;
      if (arrow.getShooter() instanceof Player) {
        attacker = (Player) arrow.getShooter();
      }
    } else if (damageSource instanceof ThrownPotion) {
      ThrownPotion potion = (ThrownPotion) damageSource;
      if (potion.getShooter() instanceof Player) {
        attacker = (Player) potion.getShooter();
      }
    }

    // NOTE: vehicles can be pushed around.
    // so unless precautions are taken by the owner, a resourceful thief might find ways to steal
    // anyway
    Claim cachedClaim = null;
    PlayerData playerData = null;
    if (attacker != null) {
      playerData = this.dataStore.getPlayerData(attacker.getName());
      cachedClaim = playerData.lastClaim;
    }

    Claim claim = this.dataStore.getClaimAt(event.getVehicle().getLocation(), false, cachedClaim);

    // if it's claimed
    if (claim != null) {
      // if damaged by anything other than a player, cancel the event
      if (attacker == null) {
        event.setCancelled(true);
      }

      // otherwise the player damaging the entity must have permission
      else {
        String noContainersReason = claim.allowContainers(attacker);
        if (noContainersReason != null) {
          event.setCancelled(true);
          GriefPrevention.sendMessage(
              attacker, TextMode.Err, Messages.NoDamageClaimedEntity, claim.getOwnerName());
        }

        // cache claim for later
        if (playerData != null) {
          playerData.lastClaim = claim;
        }
      }
    }
  }
Пример #6
0
  // the number of claim blocks a player has available for claiming land
  public int getRemainingClaimBlocks() {
    // accrued blocks + bonus blocks + permission bonus blocks
    int remainingBlocks =
        this.getAccruedClaimBlocks()
            + this.getBonusClaimBlocks()
            + GriefPreventionPlus.getInstance().getDataStore().getGroupBonusBlocks(this.playerID);
    for (final Claim claim : this.getClaims()) {
      remainingBlocks -= claim.getArea();
    }

    return remainingBlocks;
  }
Пример #7
0
 /** Merge the given claims into one and return the result. */
 @Transactional
 @Secured(BF_CLAIM_UPDATE)
 public Claim merge(Collection<Claim> claims) {
   BigDecimal amount = BigDecimal.ZERO;
   for (Claim claim : claims) {
     amount = amount.add(claim.getAmount());
   }
   Claim merged = Claim.of(Type.LEGITIMATE, "Merged claim", "Merged claim", amount);
   merged.persist();
   remove(claims);
   return merged;
 }
Пример #8
0
  public void renameCity(String oldName, String newName) {
    for (Claim claim : claimMap.values()) {
      if (oldName.equals(claim.getCityName())) claim.setCityName(newName);
    }

    City city = cityCache.get(oldName);
    cityCache.remove(oldName);
    city.rename(newName);
    cityCache.put(newName, city);

    for (PlayerCache pc : playerCache.values()) {
      if (oldName.equals(pc.getCity())) pc.setCity(newName);
    }
  }
Пример #9
0
  public Vector<Claim> getClaims() {
    if (this.claims == null) {
      int totalClaimsArea = 0;
      this.claims = new Vector<Claim>();

      // find all the claims belonging to this player and note them for
      // future reference
      for (final Claim claim : GriefPreventionPlus.getInstance().getDataStore().claims.values()) {
        if (this.playerID.equals(claim.getOwnerID())) {
          this.claims.add(claim);
          totalClaimsArea += claim.getArea();
        }
      }

      // ensure player has claim blocks for his claims, and at least the
      // minimum accrued
      this.loadDataFromSecondaryStorage();

      // if total claimed area is more than total blocks available
      int totalBlocks =
          this.accruedClaimBlocks
              + this.getBonusClaimBlocks()
              + GriefPreventionPlus.getInstance().getDataStore().getGroupBonusBlocks(this.playerID);
      if (totalBlocks < totalClaimsArea) {
        // try to fix it by adding to accrued blocks
        this.accruedClaimBlocks = totalClaimsArea;
        if (this.accruedClaimBlocks
            > GriefPreventionPlus.getInstance().config.claims_maxAccruedBlocks) {
          // remember to respect the maximum on accrued blocks
          this.accruedClaimBlocks =
              GriefPreventionPlus.getInstance().config.claims_maxAccruedBlocks;
        }

        // if that didn't fix it, then make up the difference with bonus
        // blocks
        totalBlocks =
            this.accruedClaimBlocks
                + this.getBonusClaimBlocks()
                + GriefPreventionPlus.getInstance()
                    .getDataStore()
                    .getGroupBonusBlocks(this.playerID);
        if (totalBlocks < totalClaimsArea) {
          this.bonusClaimBlocks += totalClaimsArea - totalBlocks;
        }
      }
    }

    return this.claims;
  }
  // restores nature in multiple chunks, as described by a claim instance
  // this restores all chunks which have ANY number of claim blocks from this claim in them
  // if the claim is still active (in the data store), then the claimed blocks will not be changed
  // (only the area bordering the claim)
  public void restoreClaim(Claim claim, long delayInTicks) {
    // admin claims aren't automatically cleaned up when deleted or abandoned
    if (claim.isAdminClaim()) return;

    // it's too expensive to do this for huge claims
    if (claim.getArea() > 10000) return;

    Chunk lesserChunk = claim.getLesserBoundaryCorner().getChunk();
    Chunk greaterChunk = claim.getGreaterBoundaryCorner().getChunk();

    for (int x = lesserChunk.getX(); x <= greaterChunk.getX(); x++)
      for (int z = lesserChunk.getZ(); z <= greaterChunk.getZ(); z++) {
        Chunk chunk = lesserChunk.getWorld().getChunkAt(x, z);
        this.restoreChunk(
            chunk, this.getSeaLevel(chunk.getWorld()) - 15, false, delayInTicks, null);
      }
  }
Пример #11
0
  public void deleteCity(String city) {

    Collection<Claim> cc = claimMap.values();
    Iterator<Claim> iter = cc.iterator();
    while (iter.hasNext()) {
      Claim claim = iter.next();
      if (city.equals(claim.getCityName())) iter.remove();
    }

    cityCache.remove(city);

    for (PlayerCache pc : playerCache.values()) {
      if (city.equals(pc.getCity())) {
        pc.setCity(null);
        pc.setRank(null);
      }
    }
  }
Пример #12
0
  public void unclaimAll(String cityName, Claim claim) {
    City city = cityCache.get(cityName);

    Collection<Claim> cc = claimMap.values();
    Iterator<Claim> iter = cc.iterator();
    while (iter.hasNext()) {
      Claim c = iter.next();
      if (c.getCityName().equals(cityName)) {
        iter.remove();
        city.removeClaim(c);
      }
    }
    claimMap.put(claim.toString(), claim);
    city.addClaim(claim, null, null, null, null);

    city.setUsedClaims(1);
    city.removeAllPlots();
  }
  public String allowBuild(Player player, Location location) {
    PlayerData playerData = this.dataStore.getPlayerData(player.getName());
    Claim claim = this.dataStore.getClaimAt(location, false, playerData.lastClaim);
    WorldConfig wc = GriefPrevention.instance.getWorldCfg(player.getWorld());
    // exception: administrators in ignore claims mode and special player accounts created by server
    // mods
    if (playerData.ignoreClaims || wc.getModsIgnoreClaimsAccounts().contains(player.getName()))
      return null;

    // wilderness rules
    if (claim == null) {
      // no building in the wilderness in creative mode
      if (this.creativeRulesApply(location)) {
        String reason =
            this.dataStore.getMessage(Messages.NoBuildOutsideClaims)
                + "  "
                + this.dataStore.getMessage(Messages.CreativeBasicsDemoAdvertisement);
        if (player.hasPermission("griefprevention.ignoreclaims"))
          reason += "  " + this.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
        return reason;
      }

      // no building in survival wilderness when that is configured
      else if (wc.getApplyTrashBlockRules() && wc.getClaimsEnabled()) {
        if (wc.getTrashBlockPlacementBehaviour().Allowed(location, player).Denied())
          return this.dataStore.getMessage(Messages.NoBuildOutsideClaims)
              + "  "
              + this.dataStore.getMessage(Messages.SurvivalBasicsDemoAdvertisement);
        else return null;
      } else {
        // but it's fine in creative
        return null;
      }
    }

    // if not in the wilderness, then apply claim rules (permissions, etc)
    else {
      // cache the claim for later reference
      playerData.lastClaim = claim;
      return claim.allowBuild(player);
    }
  }
Пример #14
0
  public void removeClaim(Claim claim) {
    claimMap.remove(claim.toString());

    Chunk chunk = getServer().getWorld(claim.getWorld()).getChunkAt(claim.getX(), claim.getZ());
    Block minBlock = chunk.getBlock(0, 0, 0);
    Block maxBlock = chunk.getBlock(15, 0, 15);
    int xmin = minBlock.getX();
    int zmin = minBlock.getZ();
    int xmax = maxBlock.getX();
    int zmax = maxBlock.getZ();

    City city = getCity(claim.getCityName());
    ArrayList<Integer> idList = city.removeIntersectingPlots(xmin, zmin, xmax, zmax);
    for (int i : idList) {
      database.removePlot(i);
    }

    city.setUsedClaims(city.getUsedClaims() - 1);
    city.removeClaim(claim);
  }
Пример #15
0
  @Override
  public void run() {
    // for each claim involved in this siege
    for (int i = 0; i < this.siegeData.claims.size(); i++) {
      // lock the doors
      Claim claim = this.siegeData.claims.get(i);
      claim.doorsOpen = false;

      // eject bad guys
      Player[] onlinePlayers = GriefPrevention.instance.getServer().getOnlinePlayers();
      for (int j = 0; j < onlinePlayers.length; j++) {
        Player player = onlinePlayers[j];
        if (claim.contains(player.getLocation(), false, false)
            && claim.allowAccess(player) != null) {
          GriefPrevention.sendMessage(
              player, TextMode.Err, "Looting time is up!  Ejected from the claim.");
          GriefPrevention.instance.ejectPlayer(player);
        }
      }
    }
  }
Пример #16
0
  /** Computes the scores for all features involved in the supplied placement. */
  public List<FeatureScore> computeScores(Placement play) {
    List<FeatureScore> scores = Lists.newArrayList();
    Claim claim = getClaim(play);

    // check all of the features on this tile for potential scores
    Set<Integer> groups = Sets.newHashSet();
    for (Feature f : play.tile.terrain.features) {
      // ignore features that aren't completed in this way (e.g. GRASS)
      if (!COMPLETABLES.contains(f.type)) continue;

      // make sure we haven't already scored this group; some tiles have disconnected
      // features that can be linked into the same group
      int group = claim.getClaimGroup(f);
      if (groups.contains(group)) continue;
      groups.add(group);

      // see who should score this feature
      Set<Integer> scorers = getScorers(group);
      // if we have no scorers, the feature is unclaimed; skip it
      if (scorers.isEmpty()) continue;

      // if we made it this far, we may have something to report
      int score = computeFeatureScore(play, f);
      if (score != 0) {
        scores.add(new FeatureScore(f, scorers, score, getPiecens(group)));
      }
    }

    // we may have also completed a cloister, so we check that as well
    for (Location nloc : play.loc.neighborhood()) {
      Placement nplay = _plays.get(nloc);
      if (nplay == null) continue;

      // check whether this tile has a piecen upon't
      Piecen p = _piecens.get(nloc);
      if (p == null) continue;

      // check whether this tile contains a cloister feature
      Feature cf = null;
      for (Feature f : nplay.tile.terrain.features) {
        if (f.type == Feature.Type.CLOISTER) {
          cf = f;
          break;
        }
      }
      if (cf == null) continue;

      // make sure the piecen is on the cloister
      if (_piecenGroups.get(p.loc) != getClaim(nplay).getClaimGroup(cf)) continue;

      // finally, score the cloister, which will always have only one scorer, one involved
      // piecen, and a non-zero score (simple!)
      scores.add(
          new FeatureScore(
              cf,
              Collections.singleton(p.ownerIdx),
              computeFeatureScore(nplay, cf),
              Collections.singletonList(p)));
    }

    return scores;
  }
  // when an entity is damaged
  @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
  public void onEntityDamage(EntityDamageEvent event) {
    // only actually interested in entities damaging entities (ignoring environmental damage)
    if (!(event instanceof EntityDamageByEntityEvent)) return;

    // monsters are never protected
    if (event.getEntity() instanceof Monster) return;

    EntityDamageByEntityEvent subEvent = (EntityDamageByEntityEvent) event;

    // determine which player is attacking, if any
    Player attacker = null;
    Entity damageSource = subEvent.getDamager();
    if (damageSource instanceof Player) {
      attacker = (Player) damageSource;
    } else if (damageSource instanceof Arrow) {
      Arrow arrow = (Arrow) damageSource;
      if (arrow.getShooter() instanceof Player) {
        attacker = (Player) arrow.getShooter();
      }
    } else if (damageSource instanceof ThrownPotion) {
      ThrownPotion potion = (ThrownPotion) damageSource;
      if (potion.getShooter() instanceof Player) {
        attacker = (Player) potion.getShooter();
      }
    }

    // if the attacker is a player and defender is a player (pvp combat)
    if (attacker != null && event.getEntity() instanceof Player) {
      // FEATURE: prevent pvp in the first minute after spawn, and prevent pvp when one or both
      // players have no inventory

      // doesn't apply when the attacker has the no pvp immunity permission
      // this rule is here to allow server owners to have a world with no spawn camp protection by
      // assigning permissions based on the player's world
      if (attacker.hasPermission("griefprevention.nopvpimmunity")) return;

      Player defender = (Player) (event.getEntity());

      PlayerData defenderData =
          this.dataStore.getPlayerData(((Player) event.getEntity()).getName());
      PlayerData attackerData = this.dataStore.getPlayerData(attacker.getName());

      // otherwise if protecting spawning players
      if (GriefPrevention.instance.config_pvp_protectFreshSpawns) {
        if (defenderData.pvpImmune) {
          event.setCancelled(true);
          GriefPrevention.sendMessage(attacker, TextMode.Err, Messages.ThatPlayerPvPImmune);
          return;
        }

        if (attackerData.pvpImmune) {
          event.setCancelled(true);
          GriefPrevention.sendMessage(attacker, TextMode.Err, Messages.CantFightWhileImmune);
          return;
        }
      }

      // FEATURE: prevent players who very recently participated in pvp combat from hiding inventory
      // to protect it from looting
      // FEATURE: prevent players who are in pvp combat from logging out to avoid being defeated

      long now = Calendar.getInstance().getTimeInMillis();
      defenderData.lastPvpTimestamp = now;
      defenderData.lastPvpPlayer = attacker.getName();
      attackerData.lastPvpTimestamp = now;
      attackerData.lastPvpPlayer = defender.getName();
    }

    // FEATURE: protect claimed animals, boats, minecarts
    // NOTE: animals can be lead with wheat, vehicles can be pushed around.
    // so unless precautions are taken by the owner, a resourceful thief might find ways to steal
    // anyway

    // if theft protection is enabled
    if (event instanceof EntityDamageByEntityEvent) {
      // if the entity is an non-monster creature (remember monsters disqualified above), or a
      // vehicle
      if ((subEvent.getEntity() instanceof Creature
          && GriefPrevention.instance.config_claims_protectCreatures)) {
        Claim cachedClaim = null;
        PlayerData playerData = null;
        if (attacker != null) {
          playerData = this.dataStore.getPlayerData(attacker.getName());
          cachedClaim = playerData.lastClaim;
        }

        Claim claim =
            this.dataStore.getClaimAt(event.getEntity().getLocation(), false, cachedClaim);

        // if it's claimed
        if (claim != null) {
          // if damaged by anything other than a player, cancel the event
          if (attacker == null) {
            event.setCancelled(true);
          }

          // otherwise the player damaging the entity must have permission
          else {
            String noContainersReason = claim.allowContainers(attacker);
            if (noContainersReason != null) {
              event.setCancelled(true);
              GriefPrevention.sendMessage(
                  attacker, TextMode.Err, Messages.NoDamageClaimedEntity, claim.getOwnerName());
            }

            // cache claim for later
            if (playerData != null) {
              playerData.lastClaim = claim;
            }
          }
        }
      }
    }
  }
Пример #18
0
 public City getCityAt(int x, int z, String world) {
   Claim claim = claimMap.get(new Claim(world, x, z).toString());
   if (claim == null) return null;
   return cityCache.get(claim.getCityName());
 }
Пример #19
0
 public Claimed(
     final Claim source, final SimTime time, final AgentID senderID, final AgentID receiverID) {
   super(source.getID(), senderID.getModelID(), senderID, receiverID);
   replyToId = source.getID();
 }
Пример #20
0
  public void addClaim(Claim claim) {
    claimMap.put(claim.toString(), claim);
    com.sethcran.cityscape.Claim north =
        getClaimAt(claim.getX(), claim.getZ() + 1, claim.getWorld());
    com.sethcran.cityscape.Claim east =
        getClaimAt(claim.getX() + 1, claim.getZ(), claim.getWorld());
    com.sethcran.cityscape.Claim south =
        getClaimAt(claim.getX(), claim.getZ() - 1, claim.getWorld());
    com.sethcran.cityscape.Claim west =
        getClaimAt(claim.getX() - 1, claim.getZ(), claim.getWorld());

    if (north != null) {
      if (!north.getCityName().equals(claim.getCityName())) north = null;
    }
    if (east != null) {
      if (!east.getCityName().equals(claim.getCityName())) east = null;
    }
    if (south != null) {
      if (!south.getCityName().equals(claim.getCityName())) south = null;
    }
    if (west != null) {
      if (!west.getCityName().equals(claim.getCityName())) west = null;
    }
    getCity(claim.getCityName()).addClaim(claim, north, east, south, west);
  }