区域刷新,区域黑名单,世界黑名单完成

This commit is contained in:
yuyu 2024-08-03 13:25:21 +08:00
parent 1dc5223a8f
commit 667f88fe7e
13 changed files with 301 additions and 137 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,301 @@
package com.yuyu.srwildentity.listener;
import com.germ.germplugin.GermPlugin;
import com.yuyu.srwildentity.JDBC.JdbcSqlClass;
import com.yuyu.srwildentity.SrWildEntity;
import com.yuyu.srwildentity.conditionCheck.ConditionCheck;
import com.yuyu.srwildentity.config.ConfigManager;
import com.yuyu.srwildentity.config.condition.EntityCondition;
import com.yuyu.srwildentity.config.condition.SpawnEntityType;
import com.yuyu.srwildentity.pojo.AreaRefresh;
import io.lumine.xikage.mythicmobs.MythicMobs;
import io.lumine.xikage.mythicmobs.api.exceptions.InvalidMobTypeException;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author
* @version 1.0
* @project SrWildEntity
* @date 2024/7/8 13:48:50
* @description 区域刷新实体监听类
*/
public class AreaRefershListener implements Listener {
//实体死亡监听每当有记录的实体死亡后根据刷新时间新建一个定时任务刷新实体
private HashMap<UUID, String> uuidStringHashMap; //根据uuid定位到刷新区域之后再根据区域定位到需要刷新的目标
private HashMap<String, AreaRefresh> areaStringHashMap;//根据区域和UUID定位到需要定时刷新的实体
private ConfigManager configManager; //根据ConfigManager开始开始刷新怪物
private Random random;
public AreaRefershListener(ConfigManager configManager) {
this.uuidStringHashMap = new HashMap<>();
this.random = new Random();
this.configManager = configManager;
this.areaStringHashMap = configManager.getAreaRefreshHashMap();
//监听器初始化时查询数据库
this.loadData();
}
public synchronized void loadData() {
for (String area : areaStringHashMap.keySet()) {
AreaRefresh areaRefresh = areaStringHashMap.get(area);
HashMap<String, EntityCondition> entityConditionList = areaRefresh.getEntityConditionList();
for (String entity : entityConditionList.keySet()) {
//拼接字符
String area_entity = area + "/" + entity;
EntityCondition entityCondition = entityConditionList.get(entity);
//获取uuid
List<UUID> uuidByAreaAndEntity = JdbcSqlClass.getUUIDByAreaAndEntity(area, entity);
HashSet<UUID> hashSetUUID = new HashSet<>();
for (UUID uuid : uuidByAreaAndEntity) {
hashSetUUID.add(uuid);
this.uuidStringHashMap.put(uuid, area_entity);
}
areaRefresh.setEntityNums(entity, uuidByAreaAndEntity.size());
if (uuidByAreaAndEntity.size() < entityCondition.getNums()) {
int n = entityCondition.getNums() - uuidByAreaAndEntity.size();
for (int j = 0; j < n; j++) {
if (!this.refreshEntity(entityCondition, areaRefresh)) {
new BukkitRunnable() {
@Override
public void run() {
//默认最多尝试二十次
int rangeX = areaRefresh.getX2() - areaRefresh.getX1();
int rangeY = areaRefresh.getY2() - areaRefresh.getY1();
int rangeZ = areaRefresh.getZ2() - areaRefresh.getZ1();
World world = Bukkit.getServer().getWorld(areaRefresh.getWorldName());
int x = random.nextInt(rangeX) + areaRefresh.getX1();
int z = random.nextInt(rangeZ) + areaRefresh.getZ1();
if (!world.getChunkAt(x, z).isLoaded()) {
world.getChunkAt(x, z).load();
}
for (int i = 0; i < 20; i++) {
//范围
int y = random.nextInt(rangeY) + areaRefresh.getY1();
Location location = new Location(world, x, y, z);
//检查位置是否通过
if (ConditionCheck.checkEntityRefresh(world, location, entityCondition)) {
//刷新通过
if (entityCondition.getSpawnEntityType() == SpawnEntityType.MMENTITY) {
Entity entityNew;
try {
entityNew = MythicMobs.inst().getAPIHelper().spawnMythicMob(entityCondition.getEntityName(), location);
} catch (InvalidMobTypeException e) {
throw new RuntimeException(e);
}
UUID uniqueId1 = entityNew.getUniqueId();
uuidStringHashMap.put(uniqueId1, area_entity);
Integer nums = areaRefresh.getEntityNums().get(entity);
areaStringHashMap.get(areaRefresh.getArea()).setEntityNums(entity, nums + 1);
this.cancel();
return;
} else {
Entity entityNew = world.spawnEntity(location, EntityType.valueOf(entityCondition.getEntityName()));
UUID uniqueId1 = entityNew.getUniqueId();
uuidStringHashMap.put(uniqueId1, area_entity);
Integer nums = areaRefresh.getEntityNums().get(entity);
areaStringHashMap.get(areaRefresh.getArea()).setEntityNums(entity, nums + 1);
this.cancel();
return;
}
}
}
}
}.runTaskTimer(SrWildEntity.getInance(),1200,entityCondition.getRefreshTime() * 20);
}
}
}
}
}
}
//监控实体
@EventHandler
public synchronized void MonitorEntity(EntityDeathEvent event) {
if (!uuidStringHashMap.containsKey(event.getEntity().getUniqueId())) {
//死亡的实体不在Map集合内则返回
return;
}
UUID uniqueId = event.getEntity().getUniqueId();
//记录在map表中
String areaX_entity = uuidStringHashMap.get(uniqueId);
this.uuidStringHashMap.remove(uniqueId);//死亡后删除
//分割字符串
String[] split = areaX_entity.split("/");
String area = split[0];
String entity = split[1];
AreaRefresh areaRefresh = configManager.getAreaRefreshHashMap().get(area);
//获取实体的数量
Integer num = areaRefresh.getEntityNums().get(entity);
//更新实体数量
areaRefresh.setEntityNums(entity, num - 1);
//根据entityCondition设置只执行一次的定时任务并返回
EntityCondition entityCondition = areaRefresh.getEntityConditionList().get(entity);
//此处可以用定时器来执行任务刷新怪物
long refreshTime = entityCondition.getRefreshTime();//定时器注册的时间
new BukkitRunnable() {
@Override
public void run() {
//默认最多尝试二十次
int rangeX = areaRefresh.getX2() - areaRefresh.getX1();
int rangeY = areaRefresh.getY2() - areaRefresh.getY1();
int rangeZ = areaRefresh.getZ2() - areaRefresh.getZ1();
World world = Bukkit.getServer().getWorld(areaRefresh.getWorldName());
int x = random.nextInt(rangeX) + areaRefresh.getX1();
int z = random.nextInt(rangeZ) + areaRefresh.getZ1();
if (!world.getChunkAt(x, z).isLoaded()) {
world.getChunkAt(x, z).load();
}
for (int i = 0; i < 20; i++) {
//范围
int y = random.nextInt(rangeY) + areaRefresh.getY1();
Location location = new Location(world, x, y, z);
//检查位置是否通过
if (ConditionCheck.checkEntityRefresh(world, location, entityCondition)) {
//刷新通过
if (entityCondition.getSpawnEntityType() == SpawnEntityType.MMENTITY) {
Entity entityNew;
try {
entityNew = MythicMobs.inst().getAPIHelper().spawnMythicMob(entityCondition.getEntityName(), location);
} catch (InvalidMobTypeException e) {
throw new RuntimeException(e);
}
UUID uniqueId1 = entityNew.getUniqueId();
uuidStringHashMap.put(uniqueId1, areaX_entity);
Integer nums = areaRefresh.getEntityNums().get(entity);
areaStringHashMap.get(areaRefresh.getArea()).setEntityNums(entity, nums + 1);
this.cancel();
return;
} else {
Entity entityNew = world.spawnEntity(location, EntityType.valueOf(entityCondition.getEntityName()));
UUID uniqueId1 = entityNew.getUniqueId();
uuidStringHashMap.put(uniqueId1, areaX_entity);
Integer nums = areaRefresh.getEntityNums().get(entity);
areaStringHashMap.get(areaRefresh.getArea()).setEntityNums(entity, nums + 1);
this.cancel();
return;
}
}
}
}
}.runTaskTimer(SrWildEntity.getInance(),refreshTime * 20,refreshTime * 20);
return;
}
/**
* 此方法用于刷新实体
*/
public boolean refreshEntity(EntityCondition entityCondition, AreaRefresh areaRefresh) {
//默认最多尝试二十次
int rangeX = areaRefresh.getX2() - areaRefresh.getX1();
int rangeY = areaRefresh.getY2() - areaRefresh.getY1();
int rangeZ = areaRefresh.getZ2() - areaRefresh.getZ1();
String entity = entityCondition.getEntityName();
World world = Bukkit.getServer().getWorld(areaRefresh.getWorldName());
int x = random.nextInt(rangeX) + areaRefresh.getX1();
int z = random.nextInt(rangeZ) + areaRefresh.getZ1();
if (!world.getChunkAt(x, z).isLoaded()) {
world.getChunkAt(x, z).load();
}
for (int i = 0; i < 20; i++) {
//范围
int y = random.nextInt(rangeY) + areaRefresh.getY1();
Location location = new Location(world, x, y, z);
//检查位置是否通过
if (ConditionCheck.checkEntityRefresh(world, location, entityCondition)) {
//刷新通过
if (entityCondition.getSpawnEntityType() == SpawnEntityType.MMENTITY) {
Entity entityNew;
try {
entityNew = MythicMobs.inst().getAPIHelper().spawnMythicMob(entityCondition.getEntityName(), location);
} catch (InvalidMobTypeException e) {
throw new RuntimeException(e);
}
//拼接字符
String area_entity = areaRefresh.getArea() + "/" + entity;
UUID uniqueId1 = entityNew.getUniqueId();
uuidStringHashMap.put(uniqueId1, area_entity);
Integer nums = areaRefresh.getEntityNums().get(entity);
this.areaStringHashMap.get(areaRefresh.getArea()).setEntityNums(entity, nums + 1);
return true;
}else {
Entity entityNew = world.spawnEntity(location, EntityType.valueOf(entityCondition.getEntityName()));
String area_entity = areaRefresh.getArea() + "/" + entity;
UUID uniqueId1 = entityNew.getUniqueId();
uuidStringHashMap.put(uniqueId1, area_entity);
Integer nums = areaRefresh.getEntityNums().get(entity);
this.areaStringHashMap.get(areaRefresh.getArea()).setEntityNums(entity, nums + 1);
return true;
}
}
}
return false;
}
public void setConfigManager(ConfigManager configManager) {
this.configManager = configManager;
this.uuidStringHashMap = new HashMap<>();
this.random = new Random();
this.areaStringHashMap = configManager.getAreaRefreshHashMap();
//监听器初始化时查询数据库
this.loadData();
}
public HashMap<UUID, String> getUuidStringHashMap() {
return uuidStringHashMap;
}
public HashMap<String, AreaRefresh> getAreaStringHashMap() {
return areaStringHashMap;
}
}

View File

@ -1,10 +0,0 @@
Area_Number: 1
area_1:
x1: 100
z1: 100
x2: 200
z2: 200
yMax: 10
yMin: 20 #此处给出一个大概y轴刷新范围增大刷新的概率
worldName: TravelersDreamCompact
refreshList: [ZOMBIE]

View File

@ -1,12 +0,0 @@
area_1:
ZOMBIE: #指出entity在该群系的刷新条件
type: 0 #0表示生成mc原生实体1表示生成MM怪物,不能为空!
site: 1 #刷新位置,数字代表不同的刷新位置
light: 15 #刷新亮度
refreshTime: 20 #单位为秒
nums: 2 #entity的刷新数量注意这里的数量会和通群系中其他entity相关总数不会超过config.yml中的定义
yMax: 150 #极限刷新高度
yMin: 60 #最小刷新高度
riskMax: 10 #刷新危险度的范围
riskMin: 0 #条件是小于等于riskMin大于riskMax即riskMin<= risklevel < riskMax 才会刷新
weight: 1.0 #权重越高刷新的概率越高最高为1.0

View File

@ -1,63 +0,0 @@
biome:
- OCEAN
- PLAINS
- DESERT
- EXTREME_HILLS
- FOREST
- TAIGA
- SWAMPLAND
- RIVER
- HELL
- SKY
- FROZEN_OCEAN
- FROZEN_RIVER
- ICE_FLATS
- ICE_MOUNTAINS
- MUSHROOM_ISLAND
- MUSHROOM_ISLAND_SHORE
- BEACHES
- DESERT_HILLS
- FOREST_HILLS
- TAIGA_HILLS
- SMALLER_EXTREME_HILLS
- JUNGLE
- JUNGLE_HILLS
- JUNGLE_EDGE
- DEEP_OCEAN
- STONE_BEACH
- COLD_BEACH
- BIRCH_FOREST
- BIRCH_FOREST_HILLS
- ROOFED_FOREST
- TAIGA_COLD
- TAIGA_COLD_HILLS
- REDWOOD_TAIGA
- REDWOOD_TAIGA_HILLS
- EXTREME_HILLS_WITH_TREES
- SAVANNA
- SAVANNA_ROCK
- MESA
- MESA_ROCK
- MESA_CLEAR_ROCK
- VOID
- MUTATED_PLAINS
- MUTATED_DESERT
- MUTATED_EXTREME_HILLS
- MUTATED_FOREST
- MUTATED_TAIGA
- MUTATED_SWAMPLAND
- MUTATED_ICE_FLATS
- MUTATED_JUNGLE
- MUTATED_JUNGLE_EDGE
- MUTATED_BIRCH_FOREST
- MUTATED_BIRCH_FOREST_HILLS
- MUTATED_ROOFED_FOREST
- MUTATED_TAIGA_COLD
- MUTATED_REDWOOD_TAIGA
- MUTATED_REDWOOD_TAIGA_HILLS
- MUTATED_EXTREME_HILLS_WITH_TREES
- MUTATED_SAVANNA
- MUTATED_SAVANNA_ROCK
- MUTATED_MESA
- MUTATED_MESA_ROCK
- MUTATED_MESA_CLEAR_ROCK

View File

@ -1,7 +0,0 @@
DESERT: #群系名称,下方标出该群系需要刷新的entity
ENTITY_LEVEL_1: [ZOMBIE,PIG_ZOMBIE] #该群系刷新的entity,具体的怪物刷新配置需要去entityConfig.yml中配置,!!注意此处的实体配置一定要在实体配置文件中存在,否则会不会刷新!
ROOFED_FOREST: #群系名称,下方标出该群系需要刷新的entity
ENTITY_LEVEL_1: [ZOMBIE,PIG_ZOMBIE] #该群系刷新的entity,具体的怪物刷新配置需要去entityConfig.yml中配置,!!注意此处的实体配置一定要在实体配置文件中存在,否则会不会刷新!
ENTITY_LEVEL_2: [ZOMBIE,PIG_ZOMBIE] #该群系刷新的entity,具体的怪物刷新配置需要去entityConfig.yml中配置,!!注意此处的实体配置一定要在实体配置文件中存在,否则会不会刷新!

View File

@ -1,13 +0,0 @@
blacklistNums: 2 #黑名单区域的数量
blacklist_1: #黑名单区域
world_name: TravelersDreamCompact
x1: 100
z1: 100
x2: 200
z2: 200
blacklist_2: #黑名单区域
world_name: TravelersDreamCompact
x1: 1000
z1: 100
x2: 2000
z2: 200

View File

@ -1,3 +0,0 @@
#世界黑名单
blacklistWorld:
- TravelersDreamCompact

View File

@ -1,12 +0,0 @@
RefreshTime: 10 #刷新时间单位为s
total: 12 #每个玩家最多刷新的实体数量
num: 4 #单次刷新的最大数量每RefreshTime秒刷新的数量
LEVEL_MAX: 2 #能够刷新的最高等级,便于读取文件
attempts: 6 #权重通过时,随机位置的最大次数
blacklistNums: 1 #黑名单区域的数量的数量
location_1: #黑名单区域
world_name: TravelersDreamCompact
x1: 100
z1: 100
x2: 200
z2: 200

View File

@ -1,17 +0,0 @@
name: SrWildEntity
version: '1.0-SNAPSHOT'
main: com.yuyu.srwildentity.SrWildEntity
description: 实体刷新插件
authors: [Yuyu]
commands:
despawn:
usage: /<command>
aliases: [dsp]
description: 只有op能使用的插件
permission: op
permission-message: 你没有使用权限!
srwildentity:
usage: /<command>
description: 只有op能使用的插件
permission: op
permission-message: 你没有使用权限!