Compare commits

...

12 Commits

54 changed files with 1923 additions and 546 deletions

9
.idea/compiler.xml generated
View File

@@ -2,6 +2,7 @@
<project version="4"> <project version="4">
<component name="CompilerConfiguration"> <component name="CompilerConfiguration">
<annotationProcessing> <annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true"> <profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" /> <sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
@@ -9,8 +10,10 @@
<module name="SrWildEntity" /> <module name="SrWildEntity" />
</profile> </profile>
</annotationProcessing> </annotationProcessing>
<bytecodeTargetLevel> </component>
<module name="SrWildEntity" target="1.8" /> <component name="JavacSettings">
</bytecodeTargetLevel> <option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="SrWildEntity" options="-extdirs lib" />
</option>
</component> </component>
</project> </project>

17
.idea/dataSources.xml generated Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="@localhost" uuid="b3e4f6d4-9bc1-40e4-ac36-fb03b40c315e">
<driver-ref>mysql.8</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver>
<jdbc-url>jdbc:mysql://localhost:3306</jdbc-url>
<jdbc-additional-properties>
<property name="com.intellij.clouds.kubernetes.db.host.port" />
<property name="com.intellij.clouds.kubernetes.db.enabled" value="false" />
<property name="com.intellij.clouds.kubernetes.db.container.port" />
</jdbc-additional-properties>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: com.google.code.gson:gson:2.8.0">
<CLASSES>
<root url="jar://$USER_HOME$/.m2/repository/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.m2/repository/com/google/code/gson/gson/2.8.0/gson-2.8.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.m2/repository/com/google/code/gson/gson/2.8.0/gson-2.8.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: com.google.guava:guava:21.0">
<CLASSES>
<root url="jar://$USER_HOME$/.m2/repository/com/google/guava/guava/21.0/guava-21.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.m2/repository/com/google/guava/guava/21.0/guava-21.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.m2/repository/com/google/guava/guava/21.0/guava-21.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: com.googlecode.json-simple:json-simple:1.1.1">
<CLASSES>
<root url="jar://$USER_HOME$/.m2/repository/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.m2/repository/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.m2/repository/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: commons-lang:commons-lang:2.6">
<CLASSES>
<root url="jar://$USER_HOME$/.m2/repository/commons-lang/commons-lang/2.6/commons-lang-2.6.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.m2/repository/commons-lang/commons-lang/2.6/commons-lang-2.6-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.m2/repository/commons-lang/commons-lang/2.6/commons-lang-2.6-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: junit:junit:4.10">
<CLASSES>
<root url="jar://$USER_HOME$/.m2/repository/junit/junit/4.10/junit-4.10.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.m2/repository/junit/junit/4.10/junit-4.10-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.m2/repository/junit/junit/4.10/junit-4.10-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: net.md-5:bungeecord-chat:1.12-SNAPSHOT">
<CLASSES>
<root url="jar://$USER_HOME$/.m2/repository/net/md-5/bungeecord-chat/1.12-SNAPSHOT/bungeecord-chat-1.12-20180712.114550-97.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.m2/repository/net/md-5/bungeecord-chat/1.12-SNAPSHOT/bungeecord-chat-1.12-20180712.114550-97-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.m2/repository/net/md-5/bungeecord-chat/1.12-SNAPSHOT/bungeecord-chat-1.12-20180712.114550-97-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.hamcrest:hamcrest-core:1.1">
<CLASSES>
<root url="jar://$USER_HOME$/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT">
<CLASSES>
<root url="jar://$USER_HOME$/.m2/repository/org/spigotmc/spigot-api/1.12.2-R0.1-SNAPSHOT/spigot-api-1.12.2-R0.1-20180712.012057-156.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.m2/repository/org/spigotmc/spigot-api/1.12.2-R0.1-SNAPSHOT/spigot-api-1.12.2-R0.1-20180712.012057-156-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.m2/repository/org/spigotmc/spigot-api/1.12.2-R0.1-SNAPSHOT/spigot-api-1.12.2-R0.1-20180712.012057-156-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.yaml:snakeyaml:1.19">
<CLASSES>
<root url="jar://$USER_HOME$/.m2/repository/org/yaml/snakeyaml/1.19/snakeyaml-1.19.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$USER_HOME$/.m2/repository/org/yaml/snakeyaml/1.19/snakeyaml-1.19-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$USER_HOME$/.m2/repository/org/yaml/snakeyaml/1.19/snakeyaml-1.19-sources.jar!/" />
</SOURCES>
</library>
</component>

10
.idea/libraries/lib__2_.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="lib (2)">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib" />
</CLASSES>
<JAVADOC />
<SOURCES />
<jarDirectory url="file://$PROJECT_DIR$/lib" recursive="false" />
</library>
</component>

10
.idea/libraries/lib__3_.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="lib (3)">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib" />
</CLASSES>
<JAVADOC />
<SOURCES />
<jarDirectory url="file://$PROJECT_DIR$/lib" recursive="false" />
</library>
</component>

10
.idea/libraries/lib__4_.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="lib (4)">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib" />
</CLASSES>
<JAVADOC />
<SOURCES />
<jarDirectory url="file://$PROJECT_DIR$/lib" recursive="false" />
</library>
</component>

1
.idea/misc.xml generated
View File

@@ -5,6 +5,7 @@
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" /> <item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
</list> </list>
</component> </component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager"> <component name="MavenProjectsManager">
<option name="originalFiles"> <option name="originalFiles">
<list> <list>

2
README.md Normal file
View File

@@ -0,0 +1,2 @@
刷新实体插件除了当玩家跑出一定距离后despawn刷新的实体个人认为有争议外其他基本都完成了可以通过despawn控制是否刷新实体
缩写为dsp并且dsp on/off 玩家姓名 可以控制是否在玩家附近刷新实体,如果单输入despawn或者dsp的话会关闭所有玩家的实体刷新

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> <module version="4">
<component name="FacetManager"> <component name="FacetManager">
<facet type="minecraft" name="Minecraft"> <facet type="minecraft" name="Minecraft">
<configuration> <configuration>
@@ -9,25 +9,4 @@
</configuration> </configuration>
</facet> </facet>
</component> </component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="lib" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.spigotmc:spigot-api:1.12.2-R0.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: junit:junit:4.10" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:21.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.code.gson:gson:2.8.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.19" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.md-5:bungeecord-chat:1.12-SNAPSHOT" level="project" />
</component>
</module> </module>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/PlayerRisk-1.2.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

19
pom.xml
View File

@@ -6,7 +6,7 @@
<groupId>com.yuyu</groupId> <groupId>com.yuyu</groupId>
<artifactId>SrWildEntity</artifactId> <artifactId>SrWildEntity</artifactId>
<version>1.0-SNAPSHOT</version> <version>2.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>SrWildEntity</name> <name>SrWildEntity</name>
@@ -17,7 +17,19 @@
</properties> </properties>
<build> <build>
<plugins> <plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<compilerArguments>
<extdirs>lib</extdirs><!--指定外部lib-->
</compilerArguments>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
@@ -70,5 +82,10 @@
<version>1.12.2-R0.1-SNAPSHOT</version> <version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -0,0 +1,224 @@
package com.yuyu.srwildentity.JDBC;
import org.bukkit.ChatColor;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
/**
* @author 峰。
* @version 1.0
* @project SrDisassemble
* @date 2024/6/19 16:05:42
* @description JDBC
*/
public class JdbcSqlClass {
private static String driver;
private static String url;
private static String user;
private static String password;
public static List<UUID> getUUIDByAreaAndEntity(String area, String entity){
List<UUID> uuids = new ArrayList<>();
Connection connection = openConnection();
String sql = "select * from areaentity where area = '"+area+"' and entityname = '"+entity+"'";
try {
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
uuids.add(UUID.fromString(resultSet.getString("uuid")));
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return uuids;
}
public static Connection openConnection() {
//注册驱动
try {
Class.forName(JdbcSqlClass.driver);
//获取连接
Connection conn = DriverManager.getConnection(JdbcSqlClass.url, JdbcSqlClass.user, JdbcSqlClass.password);
return conn;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String getDriver() {
return driver;
}
public static String getUrl() {
return url;
}
public static String getUser() {
return user;
}
public static String getPassword() {
return password;
}
public static void setDriver(String driver) {
JdbcSqlClass.driver = driver;
}
public static void setUrl(String url) {
JdbcSqlClass.url = url;
}
public static void setUser(String user) {
JdbcSqlClass.user = user;
}
public static void setPassword(String password) {
JdbcSqlClass.password = password;
}
public static void initTable() {
try {
Connection connection = openConnection();
Statement stmt = connection.createStatement();
//执行Sql语句
String createTable = " create table if not exists areaentity\t( " +
"area varchar(255) null comment '区域名称',\n" +
" entityname varchar(255) null,\n" +
" uuid varchar(255) null comment '实体uuid')";
boolean rs = stmt.execute(createTable);
String sql = "select column_name\n" +
"from INFORMATION_SCHEMA.COLUMNS\n" +
"where TABLE_NAME = 'areaentity'";
//手动注入所有列
List<String> columns = new ArrayList<>();
columns.add("area");
columns.add("entityname");
columns.add("uuid");
try {
ResultSet resultSet = stmt.executeQuery(sql);
List<String> lists = new ArrayList<>();
int index = 0;
while (resultSet.next()) {
String columnName = resultSet.getString("column_name");
lists.add(columnName);
index++;
}
List<String> missColumn = new ArrayList<>();
for (String columnName : columns) {
if (!lists.contains(columnName)) {
missColumn.add(columnName);
}
}
//新增列
for (String columnName : missColumn) {
addColumn(columnName);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
connection.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static int addColumn(String columns) {
String sql = null;
if (columns.equals("area")) {
sql = "ALTER TABLE areaentity\n" +
"ADD area varchar(255) null comment '区域名'";
} else if (columns.equals("entityname")) {
sql = "ALTER TABLE areaentity\n" +
"ADD entityname varchar(255) null comment '打开gui的名称'";
} else if (columns.equals("uuid")) {
sql = "ALTER TABLE areaentity\n" +
"ADD uuid varchar(255) null comment '实体uuid'";
}
if (sql != null) {
try {
Statement stmt = openConnection().createStatement();
int i = stmt.executeUpdate(sql);
return i;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
return 0;
}
public static void setChartseUtf8() {
try {
Statement connection = openConnection().createStatement();
//执行Sql语句
String sql = "ALTER TABLE areaentity CONVERT TO CHARACTER SET utf8mb4;";
boolean rs = connection.execute(sql);
connection.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void deleteData(){
//先清空数据库,再插入
String sqlDelete = "DELETE FROM areaentity";
Connection connection = openConnection();
try {
Statement statement = connection.createStatement();
boolean execute = statement.execute(sqlDelete);
if (execute){
System.out.println(ChatColor.RED+"区域实体数据清空");
}
statement.close();
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void saveData(HashMap<UUID, String> hashMap){
Connection connection = openConnection();
try {
Statement statement = connection.createStatement();
for (UUID uuid : hashMap.keySet()) {
String s = hashMap.get(uuid);
String[] split = s.split("/");
String area = split[0];
String entity = split[1];
String uuidString = uuid.toString();
String sql = "INSERT INTO areaentity(area,entityname,uuid) VALUES('"+area+"','"+entity+"','"+uuidString+"')";
statement.executeUpdate(sql);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -1,12 +1,16 @@
package com.yuyu.srwildentity; package com.yuyu.srwildentity;
import com.yuyu.srwildentity.JDBC.JdbcSqlClass;
import com.yuyu.srwildentity.config.ConfigManager; import com.yuyu.srwildentity.config.ConfigManager;
import com.yuyu.srwildentity.listener.AreaRefershListener;
import com.yuyu.srwildentity.listener.EntityRefreshListener; import com.yuyu.srwildentity.listener.EntityRefreshListener;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
/** /**
@@ -21,18 +25,33 @@ import org.bukkit.plugin.java.JavaPlugin;
public final class SrWildEntity extends JavaPlugin implements CommandExecutor { public final class SrWildEntity extends JavaPlugin implements CommandExecutor {
private EntityRefreshListener entityRefreshListener; private EntityRefreshListener entityRefreshListener;
private AreaRefershListener areaRefershListener;
public static Plugin getInance(){
return Bukkit.getPluginManager().getPlugin("SrWildEntity");
}
@Override @Override
public void onEnable() { public void onEnable() {
getLogger().info(ChatColor.AQUA+"SrWildEntity开始运行"); getLogger().info(ChatColor.AQUA+"SrWildEntity开始运行");
onload(); ConfigManager onload = onload();
//TODO(注册监听类,测试) //TODO(注册监听类,测试)
this.entityRefreshListener = new EntityRefreshListener(this.getLogger(),onload(),this); this.entityRefreshListener = new EntityRefreshListener(this.getLogger(),onload,this);
this.areaRefershListener = new AreaRefershListener(onload);
Bukkit.getPluginManager().registerEvents(entityRefreshListener,this); Bukkit.getPluginManager().registerEvents(entityRefreshListener,this);
Bukkit.getPluginManager().registerEvents(areaRefershListener,this);
//注册定时任务
// this.getServer().getScheduler().scheduleSyncRepeatingTask
// (this,this.entityRefreshListener::timedRdfreshEneity,
// 0,this.entityRefreshListener.getConfigManager().getRefreshTime()*20);
getLogger().info(ChatColor.DARK_GREEN+"SrWildEntity定时任务触发");
this.getCommand("despawn").setExecutor(entityRefreshListener); this.getCommand("despawn").setExecutor(entityRefreshListener);
this.getCommand("SrWildEntity").setExecutor(this::onCommand); this.getCommand("SrWildEntity").setExecutor(this::onCommand);
@@ -50,6 +69,9 @@ public final class SrWildEntity extends JavaPlugin implements CommandExecutor {
@Override @Override
public void onDisable() { public void onDisable() {
//关闭时,保存数据
JdbcSqlClass.deleteData();
JdbcSqlClass.saveData(areaRefershListener.getUuidStringHashMap());
} }
/** /**
@@ -72,9 +94,18 @@ public final class SrWildEntity extends JavaPlugin implements CommandExecutor {
commandSender.sendMessage(ChatColor.RED+"请加上reload操作"); commandSender.sendMessage(ChatColor.RED+"请加上reload操作");
}else { }else {
if (strings[0].equalsIgnoreCase("reload")){ if (strings[0].equalsIgnoreCase("reload")){
getLogger().info(ChatColor.GOLD+"SrWildEntity定时任务关闭");
// Bukkit.getScheduler().cancelTasks(this);
getLogger().info(ChatColor.AQUA+"SrWildEntity重新读取配置文件"); getLogger().info(ChatColor.AQUA+"SrWildEntity重新读取配置文件");
commandSender.sendMessage(ChatColor.YELLOW+"SrWildEntity重新读取配置文件"); commandSender.sendMessage(ChatColor.YELLOW+"SrWildEntity重新读取配置文件");
entityRefreshListener.setConfigManager(this.onload()); ConfigManager onload = this.onload();
entityRefreshListener.setConfigManager(onload);
areaRefershListener.setConfigManager(onload);
//todo(此处要重新注册定时任务)
getLogger().info(ChatColor.DARK_GREEN+"SrWildEntity定时任务触发");
} }
} }

View File

@@ -1,5 +1,6 @@
package com.yuyu.srwildentity.conditionCheck; package com.yuyu.srwildentity.conditionCheck;
import com.palmergames.compress.compressors.lz77support.LZ77Compressor;
import com.yuyu.srwildentity.config.condition.EntityCondition; import com.yuyu.srwildentity.config.condition.EntityCondition;
import com.yuyu.srwildentity.config.condition.EntitySite; import com.yuyu.srwildentity.config.condition.EntitySite;
import org.bukkit.Location; import org.bukkit.Location;
@@ -7,6 +8,8 @@ import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import java.util.HashSet;
/** /**
* @BelongsProject: SrWildEntity * @BelongsProject: SrWildEntity
* @BelongsPackage: com.yuyu.srwildentity.conditionCheck * @BelongsPackage: com.yuyu.srwildentity.conditionCheck
@@ -17,6 +20,11 @@ import org.bukkit.block.Block;
* @Description: 用于检查是否通过 * @Description: 用于检查是否通过
*/ */
public class ConditionCheck { public class ConditionCheck {
//实体碰撞
public static final HashSet<Material> noEntityCollision = new HashSet<>();
/** /**
* 检查entity生成位置是否符合 * 检查entity生成位置是否符合
* 1.位置 * 1.位置
@@ -30,10 +38,10 @@ public class ConditionCheck {
*/ */
public static boolean checkEntityRefresh(World world, Location location, EntityCondition entityCondition){ public static boolean checkEntityRefresh(World world, Location location, EntityCondition entityCondition){
return checkLocation(world,location,entityCondition.getEntitySite()) return (checkLocation(world,location,entityCondition.getEntitySite())
&& checkLight(world,location,entityCondition.getLight()) && checkLight(world,location,entityCondition.getLight())
&& checkTimed(world,entityCondition.getStartTiming(), entityCondition.getEndTimeing()) && checkTimed(world,entityCondition.getStartTiming(), entityCondition.getEndTimeing())
&& checkY(location,entityCondition.getyMax(), entityCondition.getyMin()); && checkY(location,entityCondition.getyMax(), entityCondition.getyMin()));
} }
/** /**
@@ -50,8 +58,16 @@ public class ConditionCheck {
} }
if (entitySite == EntitySite.ON_GROUND){ if (entitySite == EntitySite.ON_GROUND){
Block blockAt = world.getBlockAt(location); //实体的刷新位置
return blockAt.getType().name().equals(Material.AIR.name()); Block block = world.getBlockAt(location);
//实体的落脚点\
Block blockAt = world.getBlockAt(new Location(world,location.getBlockX(),location.getBlockY() + 1,location.getBlockZ()));
Block blockAt0 = world.getBlockAt(new Location(world,location.getBlockX(),location.getBlockY() - 2,location.getBlockZ()));
Block b = world.getBlockAt(new Location(world,location.getBlockX(),location.getBlockY() - 1,location.getBlockZ()));
return (noEntityCollision.contains(block.getType()) &&
noEntityCollision.contains(blockAt.getType()) &&
!noEntityCollision.contains(b.getType()) &&
!noEntityCollision.contains(blockAt0.getType()));
} }
if (entitySite == EntitySite.NULL){ if (entitySite == EntitySite.NULL){

View File

@@ -1,11 +1,24 @@
package com.yuyu.srwildentity.config; package com.yuyu.srwildentity.config;
import com.yuyu.srwildentity.JDBC.JdbcSqlClass;
import com.yuyu.srwildentity.conditionCheck.ConditionCheck;
import com.yuyu.srwildentity.config.condition.BiomeEntityRefreshSettings; import com.yuyu.srwildentity.config.condition.BiomeEntityRefreshSettings;
import com.yuyu.srwildentity.config.condition.EntityCondition;
import com.yuyu.srwildentity.config.condition.EntitySite;
import com.yuyu.srwildentity.config.condition.SpawnEntityType;
import com.yuyu.srwildentity.pojo.AreaRefresh;
import com.yuyu.srwildentity.pojo.BlackListArea;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
/** /**
* @BelongsProject: SrWildEntity * @BelongsProject: SrWildEntity
@@ -21,19 +34,175 @@ public class ConfigManager {
private final int refreshTime; private final int refreshTime;
private final int total; private final int total;
private final int num; private final int num;
private final int attempts;
private final int LEVEL;
private final HashMap<String, List<BlackListArea>> blackListAreaMap;
private final HashSet<String> blacklistWorldSet;
private final HashMap<String, AreaRefresh> areaRefreshHashMap;
public ConfigManager(Plugin plugin) { public ConfigManager(Plugin plugin) {
//加载配置文件
this.biomeEntityRefreshSettings = new BiomeEntityRefreshSettings(plugin);
//保存配置文件 //保存配置文件
plugin.saveResource("config.yml",false); plugin.saveResource("config.yml",false);
FileConfiguration config; FileConfiguration config;
File file = new File(plugin.getDataFolder(), "config.yml"); File file = new File(plugin.getDataFolder(), "config.yml");
config = YamlConfiguration.loadConfiguration(file); config = YamlConfiguration.loadConfiguration(file);
this.refreshTime = config.getInt("RefreshTime"); this.refreshTime = config.getInt("RefreshTime");
this.total = config.getInt("total"); this.total = config.getInt("total");
this.num = config.getInt("num"); this.num = config.getInt("num");
this.LEVEL = config.getInt("LEVEL_MAX");
this.attempts = config.getInt("attempts");
this.blackListAreaMap = new HashMap<>();
this.blacklistWorldSet = new HashSet<>();
this.areaRefreshHashMap = new HashMap<>();
//加载配置文件
this.biomeEntityRefreshSettings = new BiomeEntityRefreshSettings(plugin,LEVEL);
this.loadEntityCheck();
this.loadBlacklistWorld(plugin);
this.loadBlacklistArea(plugin);
this.loadAreaRefresh(plugin);
this.loadDataBase(plugin);
JdbcSqlClass.initTable();
JdbcSqlClass.setChartseUtf8();
}
private void loadEntityCheck() {
ConditionCheck.noEntityCollision.add(Material.AIR);
// ConditionCheck.noEntityCollision.add(Material.GRASS);
ConditionCheck.noEntityCollision.add(Material.SAPLING);
ConditionCheck.noEntityCollision.add(Material.WATER);
ConditionCheck.noEntityCollision.add(Material.STATIONARY_WATER);
ConditionCheck.noEntityCollision.add(Material.LAVA);
ConditionCheck.noEntityCollision.add(Material.STATIONARY_LAVA);
ConditionCheck.noEntityCollision.add(Material.POWERED_RAIL);
ConditionCheck.noEntityCollision.add(Material.DETECTOR_RAIL);
ConditionCheck.noEntityCollision.add(Material.WEB);
ConditionCheck.noEntityCollision.add(Material.LONG_GRASS);
ConditionCheck.noEntityCollision.add(Material.DEAD_BUSH);
ConditionCheck.noEntityCollision.add(Material.RED_ROSE);
ConditionCheck.noEntityCollision.add(Material.BROWN_MUSHROOM);
ConditionCheck.noEntityCollision.add(Material.RED_MUSHROOM);
ConditionCheck.noEntityCollision.add(Material.TORCH);
ConditionCheck.noEntityCollision.add(Material.FIRE);
ConditionCheck.noEntityCollision.add(Material.REDSTONE_WIRE);
ConditionCheck.noEntityCollision.add(Material.CROPS);
ConditionCheck.noEntityCollision.add(Material.SIGN_POST);
ConditionCheck.noEntityCollision.add(Material.LADDER);
ConditionCheck.noEntityCollision.add(Material.RAILS);
ConditionCheck.noEntityCollision.add(Material.WALL_SIGN);
ConditionCheck.noEntityCollision.add(Material.REDSTONE_TORCH_OFF);
ConditionCheck.noEntityCollision.add(Material.REDSTONE_TORCH_ON);
ConditionCheck.noEntityCollision.add(Material.STONE_BUTTON);
ConditionCheck.noEntityCollision.add(Material.SNOW);
ConditionCheck.noEntityCollision.add(Material.SUGAR_CANE_BLOCK);
ConditionCheck.noEntityCollision.add(Material.PUMPKIN_STEM);
ConditionCheck.noEntityCollision.add(Material.MELON_STEM);
ConditionCheck.noEntityCollision.add(Material.VINE);
ConditionCheck.noEntityCollision.add(Material.WATER_LILY);
ConditionCheck.noEntityCollision.add(Material.NETHER_WARTS);
ConditionCheck.noEntityCollision.add(Material.CARROT);
ConditionCheck.noEntityCollision.add(Material.POTATO);
ConditionCheck.noEntityCollision.add(Material.BEETROOT);
}
public void loadBlacklistArea(Plugin plugin){
plugin.saveResource("blacklistArea.yml",false);
FileConfiguration config;
File file = new File(plugin.getDataFolder(), "blacklistArea.yml");
config = YamlConfiguration.loadConfiguration(file);
int blacklistNums = config.getInt("blacklistNums");
for (int i = 1; i <= blacklistNums; i++) {
String locationX = "blacklist_"+i;
BlackListArea blackListArea = new BlackListArea(config.getString(
locationX + "." + "world_name"),
config.getInt(locationX +"." +"x1"),
config.getInt(locationX +"." +"z1"),
config.getInt(locationX +"." +"x2"),
config.getInt(locationX +"." +"z2"));
if (blackListAreaMap.containsKey(blackListArea.getWorldName())) {
blackListAreaMap.get(blackListArea.getWorldName()).add(blackListArea);
}else {
List<BlackListArea> blackListAreas = new ArrayList<>();
blackListAreas.add(blackListArea);
blackListAreaMap.put(blackListArea.getWorldName(), blackListAreas);
}
}
}
public void loadAreaRefresh(Plugin plugin) {
FileConfiguration config;
File file = new File(plugin.getDataFolder(), "areaRefresh.yml");
config = YamlConfiguration.loadConfiguration(file);
FileConfiguration configuration;
File file2 = new File(plugin.getDataFolder(), "area_Entity.yml");
configuration = YamlConfiguration.loadConfiguration(file2);
int areaNumber = config.getInt("Area_Number");
for (int i = 1; i <= areaNumber; i++) {
String areaName = "area_"+i;
List<String> entityList = config.getStringList(areaName + ".refreshList");
String worldName = config.getString(areaName + ".worldName");
int x1 = config.getInt(areaName + ".x1");
int z1 = config.getInt(areaName + ".z1");
int x2 = config.getInt(areaName + ".x2");
int z2 = config.getInt(areaName + ".z2");
int y1 = config.getInt(areaName + ".yMax");
int y2 = config.getInt(areaName + ".yMin");
HashMap<String,EntityCondition> entityConditions = new HashMap<>();
//获取刷新列表
for (String entity : entityList) {
SpawnEntityType spawnEntityType = SpawnEntityType.fromId(configuration.getInt(areaName + "." + entity + ".type"));
EntitySite entitySite = EntitySite.fromId(configuration.getInt(areaName + "." + entity + ".site"));
int light = configuration.getInt(areaName + "." + entity + ".light");
long refreshTime = configuration.getLong(areaName + "." + entity + ".refreshTime");
int nums = configuration.getInt(areaName + "." + entity + ".nums");
int yMax = configuration.getInt(areaName + "." + entity + ".yMax");
int yMin = configuration.getInt(areaName + "." + entity + ".yMin");
double weight = configuration.getDouble(areaName + "." + entity + ".weight");
EntityCondition entityCondition = new EntityCondition(entity, null,
spawnEntityType, entitySite, light, 0, 24000, nums, yMax, yMin, 50, 0, weight,refreshTime);
entityConditions.put(entity, entityCondition);
}
this.areaRefreshHashMap.put(areaName,new AreaRefresh(x1, z1, x2, z2, worldName, entityConditions,y1 , y2,areaName));
}
}
public void loadBlacklistWorld(Plugin plugin){
plugin.saveResource("blacklistWorld.yml",false);
FileConfiguration config;
File file = new File(plugin.getDataFolder(), "blacklistWorld.yml");
config = YamlConfiguration.loadConfiguration(file);
List<String> stringList = config.getStringList("blacklistWorld");
for (String string : stringList) {
this.blacklistWorldSet.add(string);
}
}
public HashSet<String> getBlacklistWorldSet() {
return blacklistWorldSet;
}
public int getAttempts() {
return attempts;
}
public int getLEVEL() {
return LEVEL;
} }
public BiomeEntityRefreshSettings getBiomeEntityRefreshSettings() { public BiomeEntityRefreshSettings getBiomeEntityRefreshSettings() {
@@ -51,4 +220,32 @@ public class ConfigManager {
public int getTotal() { public int getTotal() {
return total; return total;
} }
public HashMap<String, AreaRefresh> getAreaRefreshHashMap() {
return areaRefreshHashMap;
}
public void loadDataBase(Plugin plugin){
plugin.saveResource("datasource.yml",false);
File datasource = new File(plugin.getDataFolder(), "datasource.yml");
FileConfiguration datasourceConfig = YamlConfiguration.loadConfiguration(datasource);
JdbcSqlClass.setUser(datasourceConfig.getString("database.sql.username"));
JdbcSqlClass.setPassword(datasourceConfig.getString("database.sql.password"));
JdbcSqlClass.setDriver(datasourceConfig.getString("database.sql.driver"));
JdbcSqlClass.setUrl(datasourceConfig.getString("database.sql.url"));
plugin.getLogger().info(ChatColor.GREEN+"username:"+JdbcSqlClass.getUser()+"\npassword:"+JdbcSqlClass.getPassword()
+"\ndriver:"+JdbcSqlClass.getDriver()+"\nurl:"+JdbcSqlClass.getUrl());
JdbcSqlClass.initTable();
JdbcSqlClass.setChartseUtf8();
}
public HashMap<String, List<BlackListArea>> getBlackListAreaMap() {
return blackListAreaMap;
}
} }

View File

@@ -6,6 +6,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -19,57 +20,26 @@ import java.util.List;
* @Description: 读取实体刷新的配置相关文件 * @Description: 读取实体刷新的配置相关文件
*/ */
public class BiomeEntityRefreshSettings { public class BiomeEntityRefreshSettings {
private final HashMap<String,List<String>> biomeEntityMap;//此集合储存了群系内需要刷新的怪物 // private final HashMap<String,List<String>> biomeEntityMap;//此集合储存了群系内需要刷新的怪物
//
private final HashMap<String,HashMap<String,EntityCondition>> biomeEntityConditionMap;//此集合储存需要刷新的怪物的相关配置 // private final HashMap<String,HashMap<String,EntityCondition>> biomeEntityConditionMap;//此集合储存需要刷新的怪物的相关配置
private final List<LevelRefresh> levelRefreshesList;
public BiomeEntityRefreshSettings(Plugin plugin) { public BiomeEntityRefreshSettings(Plugin plugin,int levelMax) {
this.biomeEntityMap = new HashMap<>(); // this.biomeEntityMap = new HashMap<>();
this.biomeEntityConditionMap = new HashMap<>(); // this.biomeEntityConditionMap = new HashMap<>();
this.levelRefreshesList = new ArrayList<>();
this.loadBiomeEntitiesConfig(plugin); // this.loadBiomeEntitiesConfig(plugin,levelMax);
//
// this.loadEntityConditionConfig(plugin,levelMax);
this.loadEntityConditionConfig(plugin); this.loadRefreshEntity(plugin,levelMax);
} }
private void loadEntityConditionConfig(Plugin plugin) { private void loadRefreshEntity(Plugin plugin,int level){
//保存文件
plugin.saveResource("entityCondition.yml",false);
FileConfiguration config;
File file = new File(plugin.getDataFolder(), "entityCondition.yml");
config = YamlConfiguration.loadConfiguration(file);
for (String biomeName : this.biomeEntityMap.keySet()){
plugin.getLogger().info(ChatColor.GOLD+biomeName);
HashMap<String,EntityCondition> entityConditionHashMap = new HashMap<>();
List<String> entities = this.biomeEntityMap.get(biomeName);
for (String entityName : entities){
SpawnEntityType spawnEntityType = SpawnEntityType.fromId(config.getInt(biomeName + "." + entityName + ".type"));
EntitySite entitySite = EntitySite.fromId(config.getInt(biomeName + "." + entityName + ".site"));
int light = config.getInt(biomeName+"."+entityName+".light");
long stime = config.getLong(biomeName+"."+entityName+".startTiming");
long etime = config.getLong(biomeName+"."+entityName+".endTiming");
int nums = config.getInt(biomeName+"."+entityName+".nums");
int yMax = config.getInt(biomeName+"."+entityName+".yMax");
int yMin = config.getInt(biomeName+"."+entityName+".yMin");
EntityCondition entityCondition = new EntityCondition(entityName, biomeName, spawnEntityType,entitySite, light, stime,etime, nums, yMax, yMin);
plugin.getLogger().info(ChatColor.AQUA+entityCondition.toString());
//存入单个群系刷新map
entityConditionHashMap.put(entityName, entityCondition);
}
//存入记录总群系的map
biomeEntityConditionMap.put(biomeName,entityConditionHashMap);
}
plugin.getLogger().info("群系刷新相关文件读取完毕");
}
public void loadBiomeEntitiesConfig(Plugin plugin){
//保存文件 //保存文件
plugin.saveResource("biomeEntity.yml",false); plugin.saveResource("biomeEntity.yml",false);
@@ -90,26 +60,168 @@ public class BiomeEntityRefreshSettings {
plugin.getLogger().info("biomeEntity.yml或者 biome.yml文件读取失败!"); plugin.getLogger().info("biomeEntity.yml或者 biome.yml文件读取失败!");
return; return;
} }
// 等级 群系 实体列表
HashMap<String,HashMap<String,List<String>>> levelBiomeMap = new HashMap<>();
//遍历所有可能的生物群系 //按level循环
for (String section : biomeList){ for (int i = 1;i <= level;i++){
//判断是否存在 HashMap<String,List<String>> biomeMap = new HashMap<>();
if (config.contains(section)){ //按群系循环
List<String> entityList = config.getStringList(section+".ENTITY"); for (String biome : biomeList){
this.biomeEntityMap.put(section,entityList); //判断该群系是否存在该等级的配置
plugin.getLogger().info(ChatColor.MAGIC+section+ entityList.toString()); if (config.contains(biome)){
//获取到后保存
List<String> stringList = config.getStringList(biome + ".ENTITY_LEVEL_" + i);
if (stringList.size() > 0) {
biomeMap.put(biome, stringList);
}
}
} }
levelBiomeMap.put("level_"+i,biomeMap);
} }
plugin.getLogger().info("biomeEntity.读取完成"); for (int i = 1;i <= level;i++){
//读取对应的等级文件
// plugin.saveResource("LEVEL_"+i+".yml",false);
FileConfiguration levelConfig = null;
File levelFile = new File(plugin.getDataFolder(), "LEVEL_"+i+".yml");
levelConfig = YamlConfiguration.loadConfiguration(levelFile);
HashMap<String, List<String>> stringListHashMap = levelBiomeMap.get("level_" + i);
//获取最大,最小危险度
int riskMax = levelConfig.getInt("RISK_MAX");
int riskMin = levelConfig.getInt("RISK_MIN");
HashMap<String,List<EntityCondition>> listHashMap = new HashMap<>();
for (String biome : stringListHashMap.keySet()){
List<EntityCondition> entityConditions = new ArrayList<>();
List<String> strings = stringListHashMap.get(biome);
for (String entityName : strings){
SpawnEntityType spawnEntityType = SpawnEntityType.fromId(levelConfig.getInt(biome + "." + entityName + ".type"));
EntitySite entitySite = EntitySite.fromId(levelConfig.getInt(biome + "." + entityName + ".site"));
int light = levelConfig.getInt(biome + "." + entityName + ".light");
long stime = levelConfig.getLong(biome + "." + entityName + ".startTiming");
long etime = levelConfig.getLong(biome + "." + entityName + ".endTiming");
int nums = levelConfig.getInt(biome + "." + entityName + ".nums");
int yMax = levelConfig.getInt(biome + "." + entityName + ".yMax");
int yMin = levelConfig.getInt(biome + "." + entityName + ".yMin");
// int riskMax = levelConfig.getInt(biome + "." + entityName + ".riskMax");
// int riskMin = levelConfig.getInt(biome + "." + entityName + ".riskMin");
double weight = levelConfig.getDouble(biome + "." + entityName + ".weight");
EntityCondition entityCondition = new EntityCondition(entityName, biome,
spawnEntityType, entitySite, light, stime, etime, nums, yMax, yMin, 50, 0, weight);
entityConditions.add(entityCondition);
plugin.getLogger().info(ChatColor.AQUA +"Level:"+i +"\t"+ entityCondition.toString());
}
//此处按群系储存list
listHashMap.put(biome,entityConditions);
}
//此处按等级储存对应等级的LevelRefresh对象
this.levelRefreshesList.add(new LevelRefresh(riskMax,riskMin,listHashMap));
}
} }
public HashMap<String, List<String>> getBiomeEntityMap() { // private void loadEntityConditionConfig(Plugin plugin,int levelMax) {
return biomeEntityMap; //
} // //保存文件
// plugin.saveResource("entityCondition.yml",false);
//
// FileConfiguration config;
// File file = new File(plugin.getDataFolder(), "entityCondition.yml");
// config = YamlConfiguration.loadConfiguration(file);
//
//
// for (int i = 1;i<levelMax;i++) {
// for (String biomeName : this.biomeEntityMap.keySet()) {
// plugin.getLogger().info(ChatColor.GOLD + biomeName);
// HashMap<String, EntityCondition> entityConditionHashMap = new HashMap<>();
//
// List<String> entities = this.biomeEntityMap.get(biomeName);
// for (String entityName : entities) {
// SpawnEntityType spawnEntityType = SpawnEntityType.fromId(config.getInt(biomeName + "." + entityName + ".type"));
// EntitySite entitySite = EntitySite.fromId(config.getInt(biomeName + "." + entityName + ".site"));
// int light = config.getInt(biomeName + "." + entityName + ".light");
// long stime = config.getLong(biomeName + "." + entityName + ".startTiming");
// long etime = config.getLong(biomeName + "." + entityName + ".endTiming");
// int nums = config.getInt(biomeName + "." + entityName + ".nums");
// int yMax = config.getInt(biomeName + "." + entityName + ".yMax");
// int yMin = config.getInt(biomeName + "." + entityName + ".yMin");
// int riskMax = config.getInt(biomeName + "." + entityName + ".riskMax");
// int riskMin = config.getInt(biomeName + "." + entityName + ".riskMin");
// double weight = config.getDouble(biomeName + "." + entityName + ".weight");
// EntityCondition entityCondition = new EntityCondition(entityName, biomeName,
// spawnEntityType, entitySite, light, stime, etime, nums, yMax, yMin, riskMax, riskMin, weight);
//
// plugin.getLogger().info(ChatColor.AQUA + entityCondition.toString());
//
// //存入单个群系刷新map
// entityConditionHashMap.put(entityName, entityCondition);
// }
// //存入记录总群系的map
// biomeEntityConditionMap.put(biomeName, entityConditionHashMap);
// }
// }
//
// plugin.getLogger().info("群系刷新相关文件读取完毕");
// }
//
// public void loadBiomeEntitiesConfig(Plugin plugin,int levelMax){
// //保存文件
// plugin.saveResource("biomeEntity.yml",false);
//
// FileConfiguration config;
// File file = new File(plugin.getDataFolder(), "biomeEntity.yml");
// config = YamlConfiguration.loadConfiguration(file);
//
// //获取所有生物群系
// plugin.saveResource("biome.yml",false);
// FileConfiguration biomeconfig = null;
// File biomeName = new File(plugin.getDataFolder(),"biome.yml");
// biomeconfig = YamlConfiguration.loadConfiguration(biomeName);
// List<String> biomeList = biomeconfig.getStringList("biome");
//
//
//
// if (config == null || biomeconfig == null){
// plugin.getLogger().info("biomeEntity.yml或者 biome.yml文件读取失败!");
// return;
// }
//
// //遍历所有可能的生物群系
// for (String section : biomeList){
// //判断是否存在
// if (config.contains(section)){
// List<String> entityList = config.getStringList(section+".ENTITY");
// this.biomeEntityMap.put(section,entityList);
// plugin.getLogger().info(ChatColor.MAGIC+section+ entityList.toString());
// }
// }
//
// plugin.getLogger().info("biomeEntity.读取完成");
// }
public HashMap<String, HashMap<String, EntityCondition>> getBiomeEntityConditionMap() { // public HashMap<String, List<String>> getBiomeEntityMap() {
return biomeEntityConditionMap; // return biomeEntityMap;
} // }
//
// public HashMap<String, HashMap<String, EntityCondition>> getBiomeEntityConditionMap() {
// return biomeEntityConditionMap;
// }
public List<LevelRefresh> getLevelRefreshesList() {
return levelRefreshesList;
}
} }

View File

@@ -20,8 +20,14 @@ public class EntityCondition {
private final int nums;//刷新的数量 private final int nums;//刷新的数量
private final int yMax; private final int yMax;
private final int yMin; private final int yMin;
private final int riskMax;
private final int riskMin;
private final double weight;
private long refreshTime;
public EntityCondition(String entityName, String biome, SpawnEntityType spawnEntityType, EntitySite entitySite, int light, long startTiming, long endTiming, int nums, int yMax, int yMin) { public EntityCondition(String entityName, String biome, SpawnEntityType spawnEntityType, EntitySite entitySite,
int light, long startTiming, long endTiming, int nums,
int yMax, int yMin,int riskMax,int riskMin, double weight, long refreshTime) {
this.entityName = entityName; this.entityName = entityName;
this.biome = biome; this.biome = biome;
this.spawnEntityType = spawnEntityType; this.spawnEntityType = spawnEntityType;
@@ -32,6 +38,39 @@ public class EntityCondition {
this.nums = nums; this.nums = nums;
this.yMax = yMax; this.yMax = yMax;
this.yMin = yMin; this.yMin = yMin;
this.riskMax = riskMax;
this.riskMin = riskMin;
this.weight = weight;
this.refreshTime = refreshTime;
}
public EntityCondition(String entityName, String biome, SpawnEntityType spawnEntityType, EntitySite entitySite,
int light, long startTiming, long endTiming, int nums,
int yMax, int yMin,int riskMax,int riskMin, double weight) {
this.entityName = entityName;
this.biome = biome;
this.spawnEntityType = spawnEntityType;
this.entitySite = entitySite;
this.light = light;
this.startTiming = startTiming;
this.endTimeing = endTiming;
this.nums = nums;
this.yMax = yMax;
this.yMin = yMin;
this.riskMax = riskMax;
this.riskMin = riskMin;
this.weight = weight;
}
public SpawnEntityType getSpawnEntityType() {
return spawnEntityType;
}
public int getRiskMax() {
return riskMax;
}
public int getRiskMin() {
return riskMin;
} }
public SpawnEntityType getEntityType() { public SpawnEntityType getEntityType() {
@@ -74,6 +113,14 @@ public class EntityCondition {
return yMin; return yMin;
} }
public double getWeight() {
return weight;
}
public long getRefreshTime() {
return refreshTime;
}
@Override @Override
public String toString() { public String toString() {
return "EntityCondition{" + return "EntityCondition{" +
@@ -87,6 +134,9 @@ public class EntityCondition {
", nums=" + nums + ", nums=" + nums +
", yMax=" + yMax + ", yMax=" + yMax +
", yMin=" + yMin + ", yMin=" + yMin +
", riskMax=" + riskMax +
", riskMin=" + riskMin +
", weight=" + weight +
'}'; '}';
} }
} }

View File

@@ -0,0 +1,38 @@
package com.yuyu.srwildentity.config.condition;
import java.util.HashMap;
import java.util.List;
/**
* @BelongsProject: SrWildEntity
* @BelongsPackage: com.yuyu.srwildentity.config.condition
* @FileName: LevelRefresh
* @Author: 峰。
* @Date: 2024/4/25-22:06
* @Version: 1.0
* @Description: 按照等级记录怪物
*/
public class LevelRefresh {
private final int riskMax;
private final int riskMin;
// 群系名
private final HashMap<String, List<EntityCondition>> entityConditionHashMap;
public int getRiskMax() {
return riskMax;
}
public int getRiskMin() {
return riskMin;
}
public HashMap<String, List<EntityCondition>> getEntityConditionHashMap() {
return entityConditionHashMap;
}
public LevelRefresh(int riskMax, int riskMin, HashMap<String, List<EntityCondition>> entityConditionHashMap) {
this.riskMax = riskMax;
this.riskMin = riskMin;
this.entityConditionHashMap = entityConditionHashMap;
}
}

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,27 +1,18 @@
package com.yuyu.srwildentity.listener; package com.yuyu.srwildentity.listener;
import com.germ.germplugin.GermPlugin;
import com.palmergames.bukkit.towny.TownyAPI; import com.palmergames.bukkit.towny.TownyAPI;
import com.palmergames.bukkit.towny.event.PlayerEnterTownEvent; import com.palmergames.bukkit.towny.event.PlayerEnterTownEvent;
import com.palmergames.bukkit.towny.event.PlayerLeaveTownEvent; import com.palmergames.bukkit.towny.event.PlayerLeaveTownEvent;
import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.Town;
import com.yuyu.srwildentity.conditionCheck.ConditionCheck;
import com.yuyu.srwildentity.config.ConfigManager; import com.yuyu.srwildentity.config.ConfigManager;
import com.yuyu.srwildentity.config.condition.EntityCondition;
import com.yuyu.srwildentity.config.condition.EntitySite;
import com.yuyu.srwildentity.config.condition.SpawnEntityType;
import com.yuyu.srwildentity.pojo.PlayerRefreshinfo;
import io.lumine.xikage.mythicmobs.MythicMobs; import io.lumine.xikage.mythicmobs.MythicMobs;
import io.lumine.xikage.mythicmobs.api.exceptions.InvalidMobTypeException;
import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.Biome;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@@ -29,6 +20,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.world.ChunkUnloadEvent; import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@@ -47,46 +39,80 @@ import java.util.logging.Logger;
public class EntityRefreshListener implements Listener, CommandExecutor { public class EntityRefreshListener implements Listener, CommandExecutor {
private ConfigManager configManager;//配置相关 private ConfigManager configManager;//配置相关
public static Logger log;
private boolean flag; //用于验证entity是否刷新 public static boolean logBool;
private Logger logger;//日志打印 public static boolean flag; //用于验证entity是否刷新
private Random random;//生成随机数,随机实体的定位 private Random random;//生成随机数,随机实体的定位
private HashMap<UUID,String> entityUUIDToPlayer; public static HashMap<UUID,String> entityUUIDToPlayer = new HashMap<>();//uuid定位到玩家刷新对象
private HashMap<String, PlayerRefreshinfo> refreshPlayer;
private List<String> noRefreshPlayer;//记录不需要刷新的玩家 private List<String> noRefreshPlayer;//记录不需要刷新的玩家
private HashMap<String,PlayerRefreshLintener> refreshPlayer;//用来注册事件
private Plugin plugin; private Plugin plugin;
private MythicMobs mythicMobs; private MythicMobs mythicMobs;
private GermPlugin germPlugin;
public EntityRefreshListener(Logger logger, ConfigManager configManager, Plugin plugin){ public EntityRefreshListener(Logger logger, ConfigManager configManager, Plugin plugin){
this.entityUUIDToPlayer = new HashMap<>();
this.refreshPlayer = new HashMap<>(); this.refreshPlayer = new HashMap<>();
this.configManager = configManager; this.configManager = configManager;
this.random = new Random(); this.random = new Random();
this.logger = logger; EntityRefreshListener.log = logger;
this.flag = true; this.flag = true;
this.noRefreshPlayer = new ArrayList<>(); this.noRefreshPlayer = new ArrayList<>();
this.plugin = plugin; this.plugin = plugin;
logBool = false;
//用于获取MM插件和萌芽的实例对象 //用于获取MM插件和萌芽的实例对象
this.mythicMobs = MythicMobs.inst();
this.germPlugin = GermPlugin.getPlugin();
logger.info(ChatColor.DARK_GREEN+"SrWildEntity定时任务触发");
//注册定时任务
plugin.getServer().getScheduler().scheduleSyncRepeatingTask
(this.plugin,this::timedRdfreshEneity,0,configManager.getRefreshTime()*20);
} }
/**
* 注册监听事件
* @param name
*/
public void regRefreshEvent(String name){
if (!refreshPlayer.containsKey(name)){
if (logBool){
log.info(ChatColor.RED+name+"玩家不在刷新列表!");
}
PlayerRefreshLintener playerRefreshLintener = new PlayerRefreshLintener(name,configManager);
refreshPlayer.put(name, playerRefreshLintener);
}
if (!refreshPlayer.get(name).isFlag()) {
int workId = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, refreshPlayer.get(name)::timedRdfreshEneity, 0,
configManager.getRefreshTime() * 20);
//把线程id记录到类中
refreshPlayer.get(name).setWorkId(workId);
refreshPlayer.get(name).setFlag(true);
if (refreshPlayer.get(name).isFlag() && logBool) {
log.info(ChatColor.GOLD+name+"被加入刷新集合");
}
}
}
/**
* 取消注册的监听事件
* @param name
*/
public void cancleRefreshEvent(String name){
if (!refreshPlayer.containsKey(name)){
if (logBool){
log.info(ChatColor.RED+name+"玩家不在刷新列表!");
}
return;
}
if (refreshPlayer.get(name).isFlag()) {
plugin.getServer().getScheduler().cancelTask(refreshPlayer.get(name).getWorkId());
refreshPlayer.get(name).setFlag(false);
}
}
/** /**
* 此类用于获取玩家的危险度 * 此类用于获取玩家的危险度
* @param player * @param player
*/ */
public int prRisk(Player player){ public static int prRisk(Player player){
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
String placeholder = PlaceholderAPI.setPlaceholders(player, "%prisk_level%"); String placeholder = PlaceholderAPI.setPlaceholders(player, "%prisk_level%");
int level = Integer.parseInt(placeholder); int level = Integer.parseInt(placeholder);
@@ -106,6 +132,16 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
return false; return false;
} }
if (strings.length == 1 && strings[0].equalsIgnoreCase("log")){
logBool = !logBool;
if (logBool){
commandSender.sendMessage(ChatColor.GREEN+"实体刷新开启日志");
}else {
commandSender.sendMessage(ChatColor.GREEN+"实体刷新关闭日志");
}
return true;
}
if (commandSender.isOp()){ if (commandSender.isOp()){
if (strings.length == 0){ if (strings.length == 0){
//只输入despawn,直接停止刷新 //只输入despawn,直接停止刷新
@@ -115,12 +151,19 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
Collection<? extends Player> onlinePlayers = plugin.getServer().getOnlinePlayers(); Collection<? extends Player> onlinePlayers = plugin.getServer().getOnlinePlayers();
for (Player player : onlinePlayers){ for (Player player : onlinePlayers){
String name = player.getName(); String name = player.getName();
Town town = TownyAPI.getInstance().getTown(player.getLocation()); if (!this.playerStayTown(player.getLocation())){
if (town == null){ PlayerRefreshLintener playerRefreshLintener = new PlayerRefreshLintener(name,configManager);
PlayerRefreshinfo playerRefreshinfo = new PlayerRefreshinfo(name, 0, new ArrayList<>()); refreshPlayer.put(name, playerRefreshLintener);
refreshPlayer.put(name, playerRefreshinfo); //注册监听事件
this.regRefreshEvent(name);
}
if (flag) {
log.info(ChatColor.GREEN + "所有在野外的玩家开始刷新实体");
}else {
log.info(ChatColor.GREEN+"实体刷新停止");
entityUUIDToPlayer.clear();
refreshPlayer.clear();
} }
logger.info(ChatColor.GREEN+"所有在野外的玩家开始刷新实体");
commandSender.sendMessage(ChatColor.GREEN+"所有在野外的玩家开始刷新实体"); commandSender.sendMessage(ChatColor.GREEN+"所有在野外的玩家开始刷新实体");
return true; return true;
} }
@@ -128,13 +171,16 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
//flag=false清空所有集合停止刷新实体 //flag=false清空所有集合停止刷新实体
entityUUIDToPlayer.clear(); entityUUIDToPlayer.clear();
refreshPlayer.clear(); refreshPlayer.clear();
logger.info(ChatColor.AQUA+"所有玩家停止刷新实体"); if (logBool) {
log.info(ChatColor.AQUA + "所有玩家停止刷新实体");
}
commandSender.sendMessage(ChatColor.AQUA+"所有玩家停止刷新实体"); commandSender.sendMessage(ChatColor.AQUA+"所有玩家停止刷新实体");
return true; return true;
} }
}else { }else {
String choice = strings[0];//只能是on或者off String choice = strings[0];//只能是onoff或者clear
if (choice.equalsIgnoreCase("on") || choice.equalsIgnoreCase("off")){ if (choice.equalsIgnoreCase("on") || choice.equalsIgnoreCase("off")
|| choice.equalsIgnoreCase("clear") || choice.equalsIgnoreCase("location")){
if (choice.equalsIgnoreCase("on")){ if (choice.equalsIgnoreCase("on")){
Player player = plugin.getServer().getPlayer(strings[1]); Player player = plugin.getServer().getPlayer(strings[1]);
if (player == null){ if (player == null){
@@ -142,12 +188,13 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
return true; return true;
}else { }else {
noRefreshPlayer.remove(strings[1]); noRefreshPlayer.remove(strings[1]);
PlayerRefreshinfo playerRefreshinfo = new PlayerRefreshinfo(strings[1], 0, new ArrayList<>()); PlayerRefreshLintener playerRefreshinfo = new PlayerRefreshLintener(strings[1],configManager);
refreshPlayer.put(strings[1], playerRefreshinfo); refreshPlayer.put(strings[1], playerRefreshinfo);
this.regRefreshEvent(strings[1]);
commandSender.sendMessage(ChatColor.YELLOW+strings[1]+"开始刷怪"); commandSender.sendMessage(ChatColor.YELLOW+strings[1]+"开始刷怪");
return true; return true;
} }
}else { }else if (choice.equalsIgnoreCase("off")){
Player player = plugin.getServer().getPlayer(strings[1]); Player player = plugin.getServer().getPlayer(strings[1]);
if (player == null){ if (player == null){
commandSender.sendMessage("请输入正确的玩家姓名!"); commandSender.sendMessage("请输入正确的玩家姓名!");
@@ -156,9 +203,33 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
//玩家不为空 //玩家不为空
refreshPlayer.remove(strings[1]); refreshPlayer.remove(strings[1]);
noRefreshPlayer.add(strings[1]); noRefreshPlayer.add(strings[1]);
this.cancleRefreshEvent(strings[1]);
commandSender.sendMessage(ChatColor.YELLOW+strings[1]+"停止刷怪"); commandSender.sendMessage(ChatColor.YELLOW+strings[1]+"停止刷怪");
return true; return true;
} }
}else if (choice.equalsIgnoreCase("clear")){
//清空刷新的怪物
this.clearRefreshEntity();
if (logBool) {
log.info(ChatColor.GOLD + "SrWildEntity刷新的所有实体被清除!");
}
commandSender.sendMessage(ChatColor.GOLD+"SrWildEntity刷新的所有实体被清除!");
return true;
}else if (choice.equalsIgnoreCase("location")){
if (commandSender instanceof Player){
Player player = (Player) commandSender;
Location location = player.getLocation();
String blockname = location.getBlock().getType().name();
player.sendMessage(ChatColor.GREEN+"x:"+location.getBlockX()+"\ty:"
+location.getBlockY()+"\tz:"+location.getBlockZ()+"\tworld:"+location.getWorld().getName()+"\t"+blockname);
if (logBool) {
log.info(ChatColor.GREEN + "x:" + location.getBlockX() + "\ty:"
+ location.getBlockY() + "\tz:" + location.getBlockZ() + "\tworld:" + location.getWorld().getName() + "\t" + blockname);
}
return true;
}else {
return false;
}
} }
} }
} }
@@ -176,28 +247,44 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
String name = player.getName(); String name = player.getName();
Town town = TownyAPI.getInstance().getTown(player.getLocation()); Town town = TownyAPI.getInstance().getTown(player.getLocation());
if (town == null){ if (town == null){
PlayerRefreshinfo playerRefreshinfo = new PlayerRefreshinfo(name, 0, new ArrayList<>()); PlayerRefreshLintener playerRefreshinfo = new PlayerRefreshLintener(name, configManager);
refreshPlayer.put(name, playerRefreshinfo); refreshPlayer.put(name, playerRefreshinfo);
} }
logger.info(ChatColor.GREEN+"所有在野外的玩家开始刷新实体"); if (logBool) {
log.info(ChatColor.GREEN + "所有在野外的玩家开始刷新实体");
}
} }
} }
/** /**
* 玩家进入城镇, * 玩家进入城镇,取消玩家的监听事件
* @param event * @param event
*/ */
@EventHandler @EventHandler
public void onPlayerInTown(PlayerEnterTownEvent event) { public void onPlayerInTown(PlayerEnterTownEvent event) {
if (flag){
String name = event.getPlayer().getName(); String name = event.getPlayer().getName();
// List<UUID> entityList = refreshPlayer.get(name).getEntityList(); this.cancleRefreshEvent(name);
// for (UUID uuid : entityList){ if (logBool) {
// //删除储存的实体信息 log.info(name + "开始停止怪物");
// entityUUIDToPlayer.remove(uuid); }
// }
refreshPlayer.remove(name); }
logger.info(name + "开始停止怪物");
/**
* 玩家复活
* @param event
*/
@EventHandler
public void playerRevive(PlayerRespawnEvent event){
Location respawnLocation = event.getRespawnLocation();
if (!this.playerStayTown(respawnLocation)){
// 返回true则表示在城镇不用管
//反之增加
String name = event.getPlayer().getName();
this.regRefreshEvent(name);
}else {
this.cancleRefreshEvent(event.getPlayer().getName());
} }
} }
@@ -207,14 +294,8 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
*/ */
@EventHandler @EventHandler
public void onPlayerLeaveTown(PlayerLeaveTownEvent event) { public void onPlayerLeaveTown(PlayerLeaveTownEvent event) {
if (flag) {
String name = event.getPlayer().getName(); String name = event.getPlayer().getName();
if (!noRefreshPlayer.contains(name)) { this.regRefreshEvent(name);
PlayerRefreshinfo playerRefreshinfo = new PlayerRefreshinfo(name, 0, new ArrayList<>());
refreshPlayer.put(name, playerRefreshinfo);
logger.info(name + "开始刷新实体");
}
}
} }
/** /**
@@ -223,16 +304,12 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
*/ */
@EventHandler @EventHandler
public void onPlayerJoinGame(PlayerJoinEvent event) { public void onPlayerJoinGame(PlayerJoinEvent event) {
if (flag){
Player player = event.getPlayer(); Player player = event.getPlayer();
String name = player.getName(); String name = player.getName();
Town town = TownyAPI.getInstance().getTown(player.getLocation()); if (!this.playerStayTown(player.getLocation()) && !noRefreshPlayer.contains(name)) {
if (town == null && !noRefreshPlayer.contains(name)) {
PlayerRefreshinfo playerRefreshinfo = new PlayerRefreshinfo(name, 0, new ArrayList<>()); this.regRefreshEvent(name);
refreshPlayer.put(name, playerRefreshinfo);
logger.info(ChatColor.MAGIC + player.getName() + "在野外登录,开始刷新实体");
} }
}
} }
/** /**
@@ -240,21 +317,25 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
* @param event * @param event
*/ */
@EventHandler @EventHandler
public void onPlayerOffOnline(PlayerQuitEvent event){ public void onPlayerOffOnline(PlayerQuitEvent event) {
if (flag) {
Player player = event.getPlayer(); Player player = event.getPlayer();
String name = player.getName(); String name = player.getName();
//下线后移出刷新列表 this.cancleRefreshEvent(name);
if (refreshPlayer.get(name) != null) { if (!refreshPlayer.containsKey(name)){
List<UUID> entityList = refreshPlayer.get(name).getEntityList(); if (logBool){
for (UUID uuid : entityList){ log.info(ChatColor.RED+name+"玩家不在刷新列表!");
//删除储存的实体信息
entityUUIDToPlayer.remove(uuid);
}
refreshPlayer.remove(name);
logger.info(ChatColor.GOLD + "玩家被移出刷新集合");
} }
return;
} }
if (refreshPlayer.get(name).isFlag()) {
plugin.getServer().getScheduler().cancelTask(refreshPlayer.get(name).getWorkId());
refreshPlayer.get(name).setFlag(false);
}
if (logBool) {
log.info(ChatColor.GOLD + "玩家被移出刷新集合");
}
} }
/** /**
@@ -269,7 +350,7 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
if (entityUUIDToPlayer.containsKey(uniqueId) && refreshPlayer.containsKey(entityUUIDToPlayer.get(uniqueId))) { if (entityUUIDToPlayer.containsKey(uniqueId) && refreshPlayer.containsKey(entityUUIDToPlayer.get(uniqueId))) {
//通过死亡实体的uuid获取玩家姓名然后删除uuid //通过死亡实体的uuid获取玩家姓名然后删除uuid
String playerName = entityUUIDToPlayer.get(uniqueId); String playerName = entityUUIDToPlayer.get(uniqueId);
refreshPlayer.get(playerName).delEntityList(uniqueId); refreshPlayer.get(playerName).getPlayerRefreshinfo().delEntityList(uniqueId);
entityUUIDToPlayer.remove(uniqueId); entityUUIDToPlayer.remove(uniqueId);
} }
} }
@@ -292,161 +373,96 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
//通过uuid获取对应的玩家姓名,然后通过玩家姓名获取对应的list集合 //通过uuid获取对应的玩家姓名,然后通过玩家姓名获取对应的list集合
String name = entityUUIDToPlayer.get(uniqueId); String name = entityUUIDToPlayer.get(uniqueId);
refreshPlayer.get(name).delEntityList(uniqueId); if (refreshPlayer.containsKey(name)) {
refreshPlayer.get(name).getPlayerRefreshinfo().delEntityList(uniqueId);
}
} }
} }
} }
/** /**
* 定时任务,每隔一段时间在玩家附近刷新实体 * 清空所有记录在的实体
*/ */
public void timedRdfreshEneity(){ public void clearRefreshEntity(){
if (flag) { Server server = plugin.getServer();
int num = configManager.getNum();//每次执行时刷新的总数 // Collection<? extends Player> onlinePlayers = server.getOnlinePlayers();
for (String name : refreshPlayer.keySet()) {
if (noRefreshPlayer.contains(name)){
continue;
}
int sum = 0;//用于记录此次刷新生成的总数
//获取玩家信息
Player player = plugin.getServer().getPlayer(name);
PlayerRefreshinfo playerRefreshinfo = refreshPlayer.get(name);
//玩家危险度,用于刷新实体的等级 for (PlayerRefreshLintener player : refreshPlayer.values()){
int level = this.prRisk(player);
//TODO(危险度提示,后续需要使用这个变量去控制怪物的参数等级`)
logger.info(ChatColor.GREEN + "危险度为:" + level);
List<UUID> entityList = player.getPlayerRefreshinfo().getEntityList();
Location playerlocation = player.getLocation(); for (UUID uuid : entityList){
Entity entity = server.getEntity(uuid);
//获取玩家位置信息 if (entity != null){
World world = playerlocation.getWorld(); entity.remove();
int blockZ = playerlocation.getBlockZ(); if (entityUUIDToPlayer.containsKey(uuid)){
int blockX = playerlocation.getBlockX(); entityUUIDToPlayer.remove(uuid);
int blockY = playerlocation.getBlockY();
Biome biome = world.getBiome(blockX, blockZ);
String biomeName = biome.name();
//需要刷新的entity列表
List<String> entityList = configManager.getBiomeEntityRefreshSettings().getBiomeEntityMap().get(biomeName);
//entity条件配置
HashMap<String, EntityCondition> entityConditionHashMap =
configManager.getBiomeEntityRefreshSettings().getBiomeEntityConditionMap().get(biomeName);
if (entityList == null || entityConditionHashMap == null){
logger.info(ChatColor.RED+"没有配置"+biomeName+"群系的实体刷新案例");
continue;
}
for (String entityName : entityList){
//获取entity配置
EntityCondition entityCondition = entityConditionHashMap.get(entityName);
int yMin = entityCondition.getyMin();
int yMax = entityCondition.getyMax();
//如果玩家所在位置不再设置的y轴高度内则不刷新此entity
if (yMin > blockY || yMax < blockY){
continue;
} }
}else {
int nums = entityCondition.getNums();//当前实体需要刷新的数量 if (entityUUIDToPlayer.containsKey(uuid)){
entityUUIDToPlayer.remove(uuid);
for (int i = 0;i<nums &&
playerRefreshinfo.getEntityList().size() < configManager.getTotal()
&& sum <= num; i++) {
// 生成x和y坐标,会随机在玩家方圆15个方块的距离内随机生成
int x =blockX + random.nextInt(30) - 15; // 生成0到60之间的随机数然后减去30得到-30到30的范围
int z =blockZ + random.nextInt(30) - 15; // 同上,在玩家附近随机位置生成
int y;
//刷新在地上直接获取最高的x z 最高处的坐标
if (entityCondition.getEntitySite() == EntitySite.ON_GROUND) {
y = world.getHighestBlockYAt(x, z);
Location location = new Location(world, x, y + 1, z);
//判断位置是否符合
if (ConditionCheck.checkEntityRefresh(world, location, entityCondition)) {
//通过则生成
// Entity entity = world.spawnEntity(location, EntityType.valueOf(entityCondition.getEntityName()));
Entity entity;
//MC原生实体
if (entityCondition.getEntityType() == SpawnEntityType.PROTOGENESIS){
entity = world.spawnEntity(location, EntityType.valueOf(entityCondition.getEntityName()));
}else {
//刷新MM怪物
try {
entity = mythicMobs.getAPIHelper().spawnMythicMob(entityName, location);
} catch (InvalidMobTypeException e) {
throw new RuntimeException(e);
}
}
logger.info(ChatColor.GOLD + "" + x + " " + y + " " + z + "位置刷新了" + entityName);
UUID uniqueId = entity.getUniqueId();
//存入玩家对应的刷新的实体集合,便于寻找
entityUUIDToPlayer.put(uniqueId, name);
//存入
playerRefreshinfo.addEntityList(uniqueId);
sum++;
}
} else {
//不刷新在地上,在定义的范围内随机高度,概率生成实体,
for (int c = 0; i<nums && c < 10 && sum <= num &&
playerRefreshinfo.getEntityList().size() < configManager.getTotal();
c++) {
//循环十次验证刷新位置
y = blockY + random.nextInt(6) - 6;//在玩家所在高度的上下六格内生成,便于当玩家在洞穴时,定位洞穴
x = blockX + random.nextInt(30) - 15; // 生成0到60之间的随机数然后减去30得到-30到30的范围
z = blockZ + random.nextInt(30) - 15; // 同上,在玩家附近随机位置生成
Location location = new Location(world, x, y + 1, z);
//判断位置是否符合
if (ConditionCheck.checkEntityRefresh(world, location, entityCondition)) {
//通过则生成
Entity entity;
//MC原生实体
if (entityCondition.getEntityType() == SpawnEntityType.PROTOGENESIS){
entity = world.spawnEntity(location, EntityType.valueOf(entityCondition.getEntityName()));
}else {
//刷新MM怪物
try {
entity = mythicMobs.getAPIHelper().spawnMythicMob(entityName, location);
} catch (InvalidMobTypeException e) {
throw new RuntimeException(e);
}
}
logger.info(ChatColor.GOLD + "" + x + " " + y + " " + z + "位置刷新了" + entityName);
UUID uniqueId = entity.getUniqueId();
//存入玩家对应的刷新的实体集合,便于寻找
entityUUIDToPlayer.put(uniqueId, name);
//存入
playerRefreshinfo.addEntityList(uniqueId);
i++;
sum++;
}
}
}
} }
} }
} }
//entity清除完后
player.getPlayerRefreshinfo().setEntityList(new ArrayList<>());
}
if(!entityUUIDToPlayer.isEmpty()) {
for (UUID uuid : entityUUIDToPlayer.keySet()) {
Entity entity = plugin.getServer().getEntity(uuid);
if (entity != null) {
entity.remove();
entityUUIDToPlayer.remove(uuid);
} else {
entityUUIDToPlayer.remove(uuid);
}
}
} }
} }
public void playerRefreshEntiyt(String name){
if (!noRefreshPlayer.contains(name) && !entityUUIDToPlayer.containsValue(name)) {
PlayerRefreshLintener playerRefreshinfo = new PlayerRefreshLintener(name, configManager);
refreshPlayer.put(name, playerRefreshinfo);
if (logBool) {
log.info(name + "开始刷新实体");
}
}else {
List<UUID> uuidList = new ArrayList<>();
for (UUID uuid : entityUUIDToPlayer.keySet()){
String s = entityUUIDToPlayer.get(uuid);
if (s.equals(name)){
uuidList.add(uuid);
}
}
PlayerRefreshLintener playerRefreshinfo = new PlayerRefreshLintener(name, configManager);
refreshPlayer.put(name, playerRefreshinfo);
if (logBool) {
log.info(name + "开始刷新实体");
}
}
}
/**
* 用于判断玩家是否在城镇
* @param location
* @return
*/
public boolean playerStayTown(Location location) {
Town town = TownyAPI.getInstance().getTown(location);
if (town == null){
//为空则不再城镇
return false;
}else {
return true;
}
}
public ConfigManager getConfigManager() { public ConfigManager getConfigManager() {
return configManager; return configManager;
} }
@@ -458,5 +474,8 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
public void setConfigManager(ConfigManager configManager) { public void setConfigManager(ConfigManager configManager) {
this.configManager = configManager; this.configManager = configManager;
for (String name : refreshPlayer.keySet()){
refreshPlayer.get(name).setConfigManager(configManager);
}
} }
} }

View File

@@ -0,0 +1,312 @@
package com.yuyu.srwildentity.listener;
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.EntitySite;
import com.yuyu.srwildentity.config.condition.LevelRefresh;
import com.yuyu.srwildentity.config.condition.SpawnEntityType;
import com.yuyu.srwildentity.pojo.AreaRefresh;
import com.yuyu.srwildentity.pojo.BlackListArea;
import com.yuyu.srwildentity.pojo.PlayerRefreshinfo;
import io.lumine.xikage.mythicmobs.MythicMobs;
import io.lumine.xikage.mythicmobs.api.exceptions.InvalidMobTypeException;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import java.util.*;
/**
* @author 峰。
* @version 1.0
* @project SrWildEntityNew
* @date 2024/8/3 19:35:39
* @description 针对单个玩家的监听类,注意这里要在实体刷新的监听类中统一管理
*/
public class PlayerRefreshLintener {
private String playerName;
private ConfigManager configManager;
private Random random;
private PlayerRefreshinfo playerRefreshinfo;
private Integer workId;
private boolean flag = false;
private MythicMobs mythicMobs;
public PlayerRefreshLintener(String player, ConfigManager configManager) {
this.playerRefreshinfo = new PlayerRefreshinfo(playerName,0,new ArrayList<>());
this.playerName = player;
this.configManager = configManager;
this.random = new Random();
this.mythicMobs = MythicMobs.inst();
}
/**
* 定时任务,每隔一段时间在玩家附近刷新实体
*/
public void timedRdfreshEneity(){
if (EntityRefreshListener.flag) {
if (!flag){
return;
}
if (EntityRefreshListener.logBool){
EntityRefreshListener.log.info(ChatColor.GOLD+playerName+"执行刷新任务");
}
int num = configManager.getNum();//每次执行时刷新的总数
int attempts = 0;
int sum = 0;//用于记录此次刷新生成的总数
//获取玩家信息
Player player = Bukkit.getPlayer(playerName);
//玩家不在线
if (player == null){
if (EntityRefreshListener.logBool){
EntityRefreshListener.log.info(ChatColor.RED + "Player " + playerName + " not found");
}
//返回之前取消定时任务
Bukkit.getScheduler().cancelTask(this.workId);
return;
}
Location playerlocation = player.getLocation();
World world = playerlocation.getWorld();
String worldName = world.getName();
boolean pass = false;
//如果黑名单的set集合里面包含有该世界的名字则跳过
if (configManager.getBlacklistWorldSet().contains(worldName)){
if (EntityRefreshListener.logBool){
EntityRefreshListener.log.info(ChatColor.RED + "黑名单世界 " + worldName+"\t"+playerName);
}
return;
}
if (configManager.getBlackListAreaMap().containsKey(worldName)){
List<BlackListArea> blackListAreas = configManager.getBlackListAreaMap().get(worldName);
for (BlackListArea blackListArea : blackListAreas){
int blockX = playerlocation.getBlockX();
int blockZ = playerlocation.getBlockZ();
if (blackListArea.getX1() >= blockX && blockX >= blackListArea.getX2()
&& blackListArea.getY1() >= blockZ && blockZ >= blackListArea.getY2()){
//tag为循环标志此处会直接结束tag标志处的循环
if (EntityRefreshListener.logBool){
EntityRefreshListener.log.info(ChatColor.RED + "黑名单区域 " + worldName+"\t"+playerName);
}
return;
}
}
}
//玩家危险度,用于刷新实体的等级
int riskLevel = EntityRefreshListener.prRisk(player);
if (riskLevel == 0){
//等于0不刷新怪物,直接跳过
if (EntityRefreshListener.logBool){
EntityRefreshListener.log.info(ChatColor.RED+playerName+"危险度为0");
}
return;
}
LevelRefresh refreshList = null;
List<LevelRefresh> levelRefreshesList = configManager.getBiomeEntityRefreshSettings().getLevelRefreshesList();
for (LevelRefresh levelRefresh : levelRefreshesList){
if (riskLevel > levelRefresh.getRiskMin() && riskLevel <= levelRefresh.getRiskMax()){
refreshList = levelRefresh;
}
}
if (refreshList == null){
if ( EntityRefreshListener.logBool) {
EntityRefreshListener.log.info(ChatColor.MAGIC + playerName + "所在群系" + "没有危险度为:" + riskLevel + "时适配的刷新列表");
}
return;
}
//获取玩家位置信息
int blockZ = playerlocation.getBlockZ();
int blockX = playerlocation.getBlockX();
int blockY = playerlocation.getBlockY();
Biome biome = world.getBiome(blockX, blockZ);
String biomeName = biome.name();
List<EntityCondition> entityConditionList = null;
HashMap<String, List<EntityCondition>> entityConditionHashMap = refreshList.getEntityConditionHashMap();
for (String refreshBiome : entityConditionHashMap.keySet()){
if (biomeName.contains(refreshBiome)){
entityConditionList = entityConditionHashMap.get(refreshBiome);
}
}
if (entityConditionList == null){
if (EntityRefreshListener.logBool) {
EntityRefreshListener.log.info(ChatColor.RED + "没有配置" + biomeName + "群系的实体刷新案例");
}
return;
}
for (EntityCondition entityCondition : entityConditionList){
int yMin = entityCondition.getyMin();
int yMax = entityCondition.getyMax();
//如果玩家所在位置不再设置的y轴高度内则不刷新此entity
if (yMin > blockY || yMax < blockY){
if (EntityRefreshListener.logBool) {
EntityRefreshListener.log.info(ChatColor.RED + "刷新高度不通过" + entityCondition.getEntityName()+"\tyMax="+yMax+"\tyMin="+yMin+"\tblockY="+blockY);
}
continue;
}
float v = random.nextFloat();
if ( entityCondition.getWeight() <= v){
if (EntityRefreshListener.logBool) {
//刷新不通过,进入下一个验证的实体
EntityRefreshListener.log.info(ChatColor.RED + "刷新权重不通过" + entityCondition.getEntityName() + "权重:" + entityCondition.getWeight() + "\t" + v);
}
continue;
}
int nums = entityCondition.getNums();//当前实体需要刷新的数量
for (int i = 0;i<nums &&
playerRefreshinfo.getEntityList().size() < configManager.getTotal()
&& sum <= num
&& attempts <= configManager.getAttempts(); i++) {
// 生成x和y坐标,会随机在玩家方圆15个方块的距离内随机生成
int x =blockX + random.nextInt(30) - 15; // 生成0到60之间的随机数然后减去30得到-30到30的范围
int z =blockZ + random.nextInt(30) - 15; // 同上,在玩家附近随机位置生成
int y =blockY + random.nextInt(3) - 3; //在玩家Y轴上下3格尝试刷新
//刷新在地上直接获取最高的x z 最高处的坐标
if (entityCondition.getEntitySite() == EntitySite.ON_GROUND) {
Location location = new Location(world, x, y , z);
//判断位置是否符合
if (ConditionCheck.checkEntityRefresh(world, location, entityCondition)) {
//通过则生成
// Entity entity = world.spawnEntity(location, EntityType.valueOf(entityCondition.getEntityName()));
Entity entity;
//MC原生实体
if (entityCondition.getEntityType() == SpawnEntityType.PROTOGENESIS){
entity = world.spawnEntity(location, EntityType.valueOf(entityCondition.getEntityName()));
}else {
//刷新MM怪物
try {
entity = mythicMobs.getAPIHelper().spawnMythicMob(entityCondition.getEntityName(),location,riskLevel);
} catch (InvalidMobTypeException e) {
throw new RuntimeException(e);
}
}
if (EntityRefreshListener.logBool) {
EntityRefreshListener.log.info(ChatColor.GOLD + "" + x + " " + y + " " + z + "位置刷新了" + entityCondition.getEntityName());
}
UUID uniqueId = entity.getUniqueId();
//存入玩家对应的刷新的实体集合,便于寻找
EntityRefreshListener.entityUUIDToPlayer.put(uniqueId, playerName);
//存入
playerRefreshinfo.addEntityList(uniqueId);
attempts++;
sum++;
}
} else {
//不刷新在地上,在定义的范围内随机高度,概率生成实体,
for (int c = 0; i<nums && c < 10 && sum <= num &&
playerRefreshinfo.getEntityList().size() < configManager.getTotal();
c++) {
//循环十次验证刷新位置
y = blockY + random.nextInt(3) - 3;//在玩家所在高度的上下三格内生成,便于当玩家在洞穴时,定位洞穴
x = blockX + random.nextInt(30) - 15; // 生成0到60之间的随机数然后减去30得到-30到30的范围
z = blockZ + random.nextInt(30) - 15; // 同上,在玩家附近随机位置生成
if (entityCondition.getEntitySite() == EntitySite.ON_GROUND) {
y = world.getHighestBlockYAt(x,z);
}
Location location = new Location(world, x, y + 1, z);
//判断位置是否符合
if (ConditionCheck.checkEntityRefresh(world, location, entityCondition)) {
//通过则生成
Entity entity;
//MC原生实体
if (entityCondition.getEntityType() == SpawnEntityType.PROTOGENESIS){
entity = world.spawnEntity(location, EntityType.valueOf(entityCondition.getEntityName()));
}else {
//刷新MM怪物
try {
entity = MythicMobs.inst().getAPIHelper().spawnMythicMob(entityCondition.getEntityName(), location);
} catch (InvalidMobTypeException e) {
throw new RuntimeException(e);
}
}
if (EntityRefreshListener.logBool) {
EntityRefreshListener.log.info(ChatColor.GOLD + "" + x + " " + y + " " + z + "位置刷新了" + entityCondition.getEntityName());
}
UUID uniqueId = entity.getUniqueId();
//存入玩家对应的刷新的实体集合,便于寻找
EntityRefreshListener.entityUUIDToPlayer.put(uniqueId, playerName);
//存入
playerRefreshinfo.addEntityList(uniqueId);
i++;
sum++;
attempts++;
}
}
}
}
}
}
}
public Integer getWorkId() {
return workId;
}
public void setWorkId(Integer workId) {
this.workId = workId;
}
public ConfigManager getConfigManager() {
return configManager;
}
public void setConfigManager(ConfigManager configManager) {
this.configManager = configManager;
}
public PlayerRefreshinfo getPlayerRefreshinfo() {
return playerRefreshinfo;
}
public void setPlayerRefreshinfo(PlayerRefreshinfo playerRefreshinfo) {
this.playerRefreshinfo = playerRefreshinfo;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}

View File

@@ -0,0 +1,105 @@
package com.yuyu.srwildentity.pojo;
import com.yuyu.srwildentity.JDBC.JdbcSqlClass;
import com.yuyu.srwildentity.config.condition.EntityCondition;
import java.util.HashMap;
import java.util.List;
/**
* @author 峰。
* @version 1.0
* @project SrWildEntity
* @date 2024/7/8 23:13:33
* @description 区域刷新的类
*/
public class AreaRefresh {
private final int x1;
private final int z1;
private final int x2;
private final int z2;
private final int y1;
private final int y2;
private final String worldName;
private final String area;
private final HashMap<String,EntityCondition> entityConditionList;
private HashMap<String,Integer> entityNums;//用于记录怪物区域的怪物数量
public AreaRefresh(int x1, int z1, int x2, int z2, String worldName, HashMap<String,EntityCondition> entityConditionList, int y1, int y2, String area) {
if (x2 >= x1){
this.x2 = x2;
this.x1 = x1;
}else {
this.x2 = x1;
this.x1 = x2;
}
if (z2 >= z1){
this.z2 = z2;
this.z1 = z1;
}else {
this.z2 = z1;
this.z1 = z2;
}
if (y2 >= y1){
this.y2 = y2;
this.y1 = y1;
}else {
this.y2 = y1;
this.y1 = y2;
}
this.area = area;
this.worldName = worldName;
this.entityConditionList = entityConditionList;
this.entityNums = new HashMap<>();
//属性初始化完成后,查询数据库
}
public String getArea() {
return area;
}
public void setEntityNums(String entityName, int num) {
this.entityNums.put(entityName, num);
}
public int getY1() {
return y1;
}
public int getY2() {
return y2;
}
public int getX1() {
return x1;
}
public int getZ1() {
return z1;
}
public int getX2() {
return x2;
}
public int getZ2() {
return z2;
}
public String getWorldName() {
return worldName;
}
public HashMap<String, Integer> getEntityNums() {
return entityNums;
}
public HashMap<String, EntityCondition> getEntityConditionList() {
return entityConditionList;
}
}

View File

@@ -0,0 +1,81 @@
package com.yuyu.srwildentity.pojo;
/**
* @author 峰。
* @version 1.0
* @project SrWildEntity
* @date 2024/7/7 14:23:54
* @description 黑名单区域
*/
public class BlackListArea {
private String worldName;
private int x1;
private int y1;
private int x2;
private int y2;
public BlackListArea(String worldName, int x1, int y1, int x2, int y2) {
this.worldName = worldName;
this.setXY(x1,y1,x2,y2);
}
/**
* 此方法可以固定x1>x2 y1>y2
* @param x1
* @param y1
* @param x2
* @param y2
*/
public void setXY(int x1, int y1,int x2, int y2) {
if (x1 > x2) {
this.x1 = x1;
this.x2 = x2;
}else {
this.x1 = x2;
this.x2 = x1;
}
if (y1 > y2) {
this.y1 = y1;
this.y2 = y2;
}else {
this.y1 = y2;
this.y2 = y1;
}
}
public String getWorldName() {
return worldName;
}
public boolean isPointInRectangle(int x, int z) {
// 确保x1 < x2 和 z1 < z2如果不是则交换它们但在这个示例中我们假设输入总是有效的
// 检查x坐标是否在范围内
if (x >= x1 && x <= x2) {
// 检查z坐标是否在范围内
if (z >= y1 && z <= y2) {
return true; // 如果两个条件都满足,则点在矩形内
}
}
// 如果不满足任一条件,则点在矩形外
return false;
}
public int getX1() {
return x1;
}
public int getY1() {
return y1;
}
public int getX2() {
return x2;
}
public int getY2() {
return y2;
}
}

View File

@@ -0,0 +1,18 @@
#RISK_MAX: 10 #当最大危险度为多少时读取这个yml文件10的时候会读取
#RISK_MIN: 0 #当最小危险度为多少时读取这个yml文件0的时候不会读取
DESERT:
ZOMBIE: #指出entity在该群系的刷新条件
Matching_direction: ROOFED_FOREST_ZOMBIE #群系_怪物 会直接读取该实体的刷新配置
ROOFED_FOREST:
ZOMBIE: #指出entity在该群系的刷新条件
type: 0 #0表示生成mc原生实体1表示生成MM怪物2表示生成萌芽怪物
site: 1 #刷新位置,数字代表不同的刷新位置
light: 15 #刷新亮度
startTiming: 0 #刷新怪物的时间注意这里需要用mc中的时间格式来表示而不是现实中的时间
endTiming: 24000 #结束刷新的时间,怪物会在这个区间内刷新
nums: 2 #entity的刷新数量注意这里的数量会和通群系中其他entity相关总数不会超过config.yml中的定义
yMax: 150 #极限刷新高度
yMin: 60 #最小刷新高度
riskMax: 10 #刷新危险度的范围
riskMin: 0

View File

View File

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

View File

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

View File

@@ -0,0 +1,13 @@
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

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

View File

@@ -1,3 +1,12 @@
RefreshTime: 10 #刷新时间单位为s RefreshTime: 10 #刷新时间单位为s
total: 12 #每个玩家每次刷新的实体数量 total: 12 #每个玩家最多刷新的实体数量
num: 4 #单次刷新的数量每RefreshTime秒刷新的数量 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

@@ -0,0 +1,6 @@
database:
sql:
user: root
password:
driver: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mc_service

View File

@@ -1,30 +0,0 @@
DESERT:
ZOMBIE: #指出entity在该群系的刷新条件
type: 0 #0表示生成mc原生实体1表示生成MM怪物,不能为空!
site: 1 #刷新位置,数字代表不同的刷新位置
light: 15 #刷新亮度
startTiming: 0 #刷新怪物的时间注意这里需要用mc中的时间格式来表示而不是现实中的时间
endTiming: 20000 #结束刷新的时间,怪物会在这个区间内刷新
nums: 2 #entity的刷新数量注意这里的数量会和通群系中其他entity相关总数不会超过config.yml中的定义
yMax: 150 #极限刷新高度
yMin: 60 #最小刷新高度
ROOFED_FOREST:
ZOMBIE: #指出entity在该群系的刷新条件
type: 0 #0表示生成mc原生实体1表示生成MM怪物2表示生成萌芽怪物
site: 1 #刷新位置,数字代表不同的刷新位置
light: 15 #刷新亮度
startTiming: 0 #刷新怪物的时间注意这里需要用mc中的时间格式来表示而不是现实中的时间
endTiming: 24000 #结束刷新的时间,怪物会在这个区间内刷新
nums: 2 #entity的刷新数量注意这里的数量会和通群系中其他entity相关总数不会超过config.yml中的定义
yMax: 150 #极限刷新高度
yMin: 60 #最小刷新高度
PIG_ZOMBIE: #指出entity在该群系的刷新条件
type: 0 #0表示生成mc原生实体1表示生成MM怪物2表示生成萌芽怪物
site: 1 #刷新位置,数字代表不同的刷新位置
light: 15 #刷新亮度
startTiming: 0 #刷新怪物的时间注意这里需要用mc中的时间格式来表示而不是现实中的时间
endTiming: 24000 #结束刷新的时间,怪物会在这个区间内刷新
nums: 2 #entity的刷新数量注意这里的数量会和通群系中其他entity相关总数不会超过config.yml中的定义
yMax: 150 #极限刷新高度
yMin: 60 #最小刷新高度

View File

@@ -2,6 +2,12 @@ name: SrWildEntity
version: '${project.version}' version: '${project.version}'
main: com.yuyu.srwildentity.SrWildEntity main: com.yuyu.srwildentity.SrWildEntity
description: 实体刷新插件 description: 实体刷新插件
depend:
- Towny
- PlaceholderAPI
- PlayerRisk
- MythicMobs
- GermPlugin
authors: [Yuyu] authors: [Yuyu]
commands: commands:
despawn: despawn:

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

View File

@@ -1,3 +0,0 @@
RefreshTime: 10 #刷新时间单位为s
total: 12 #每个玩家每次刷新的实体数量
num: 4 #单次刷新的数量每RefreshTime秒刷新的数量

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: 你没有使用权限!