Compare commits
12 Commits
76d2724786
...
9c23f5fc3d
Author | SHA1 | Date | |
---|---|---|---|
9c23f5fc3d | |||
d21bf4b7f5 | |||
667f88fe7e | |||
1dc5223a8f | |||
43e041955f | |||
14dbe32c26 | |||
3ca0f1f960 | |||
29da41875e | |||
f41a8511dd | |||
ac3ed0ac88 | |||
|
d142afe61e | ||
|
ee4fe335a6 |
9
.idea/compiler.xml
generated
9
.idea/compiler.xml
generated
@@ -2,6 +2,7 @@
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="true" />
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
@@ -9,8 +10,10 @@
|
||||
<module name="SrWildEntity" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
<bytecodeTargetLevel>
|
||||
<module name="SrWildEntity" target="1.8" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
<component name="JavacSettings">
|
||||
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
|
||||
<module name="SrWildEntity" options="-extdirs lib" />
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
17
.idea/dataSources.xml
generated
Normal file
17
.idea/dataSources.xml
generated
Normal 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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
13
.idea/libraries/Maven__junit_junit_4_10.xml
generated
13
.idea/libraries/Maven__junit_junit_4_10.xml
generated
@@ -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>
|
@@ -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>
|
@@ -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>
|
@@ -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>
|
13
.idea/libraries/Maven__org_yaml_snakeyaml_1_19.xml
generated
13
.idea/libraries/Maven__org_yaml_snakeyaml_1_19.xml
generated
@@ -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
10
.idea/libraries/lib__2_.xml
generated
Normal 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
10
.idea/libraries/lib__3_.xml
generated
Normal 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
10
.idea/libraries/lib__4_.xml
generated
Normal 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
1
.idea/misc.xml
generated
@@ -5,6 +5,7 @@
|
||||
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
|
||||
</list>
|
||||
</component>
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
|
2
README.md
Normal file
2
README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
刷新实体插件,除了当玩家跑出一定距离后despawn刷新的实体个人认为有争议外,其他基本都完成了,可以通过despawn控制是否刷新实体,
|
||||
缩写为dsp,并且dsp on/off 玩家姓名 可以控制是否在玩家附近刷新实体,如果单输入despawn或者dsp的话,会关闭所有玩家的实体刷新
|
@@ -1,5 +1,5 @@
|
||||
<?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">
|
||||
<facet type="minecraft" name="Minecraft">
|
||||
<configuration>
|
||||
@@ -9,25 +9,4 @@
|
||||
</configuration>
|
||||
</facet>
|
||||
</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>
|
Binary file not shown.
BIN
lib/GermPlugin-Snapshot-4.4.1-1.jar
Normal file
BIN
lib/GermPlugin-Snapshot-4.4.1-1.jar
Normal file
Binary file not shown.
BIN
lib/MythicMobs-4.11.0-013.jar
Normal file
BIN
lib/MythicMobs-4.11.0-013.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/PlaceholderAPI-2.11.6.jar
Normal file
BIN
lib/PlaceholderAPI-2.11.6.jar
Normal file
Binary file not shown.
Binary file not shown.
BIN
lib/PlayerRisk-1.2.jar
Normal file
BIN
lib/PlayerRisk-1.2.jar
Normal file
Binary file not shown.
BIN
lib/Towny-0.97.0.0_for_1.12.2.jar
Normal file
BIN
lib/Towny-0.97.0.0_for_1.12.2.jar
Normal file
Binary file not shown.
Binary file not shown.
19
pom.xml
19
pom.xml
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>com.yuyu</groupId>
|
||||
<artifactId>SrWildEntity</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<version>2.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>SrWildEntity</name>
|
||||
@@ -17,7 +17,19 @@
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
|
||||
<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>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
@@ -70,5 +82,10 @@
|
||||
<version>1.12.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.16.10</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
224
src/main/java/com/yuyu/srwildentity/JDBC/JdbcSqlClass.java
Normal file
224
src/main/java/com/yuyu/srwildentity/JDBC/JdbcSqlClass.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,12 +1,16 @@
|
||||
package com.yuyu.srwildentity;
|
||||
|
||||
import com.yuyu.srwildentity.JDBC.JdbcSqlClass;
|
||||
import com.yuyu.srwildentity.config.ConfigManager;
|
||||
import com.yuyu.srwildentity.listener.AreaRefershListener;
|
||||
import com.yuyu.srwildentity.listener.EntityRefreshListener;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
/**
|
||||
@@ -21,18 +25,33 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
public final class SrWildEntity extends JavaPlugin implements CommandExecutor {
|
||||
|
||||
private EntityRefreshListener entityRefreshListener;
|
||||
private AreaRefershListener areaRefershListener;
|
||||
public static Plugin getInance(){
|
||||
return Bukkit.getPluginManager().getPlugin("SrWildEntity");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
getLogger().info(ChatColor.AQUA+"SrWildEntity开始运行");
|
||||
onload();
|
||||
ConfigManager onload = onload();
|
||||
|
||||
|
||||
//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(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("SrWildEntity").setExecutor(this::onCommand);
|
||||
@@ -50,6 +69,9 @@ public final class SrWildEntity extends JavaPlugin implements CommandExecutor {
|
||||
|
||||
@Override
|
||||
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操作");
|
||||
}else {
|
||||
if (strings[0].equalsIgnoreCase("reload")){
|
||||
|
||||
getLogger().info(ChatColor.GOLD+"SrWildEntity定时任务关闭");
|
||||
// Bukkit.getScheduler().cancelTasks(this);
|
||||
|
||||
getLogger().info(ChatColor.AQUA+"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定时任务触发");
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
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.EntitySite;
|
||||
import org.bukkit.Location;
|
||||
@@ -7,6 +8,8 @@ import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* @BelongsProject: SrWildEntity
|
||||
* @BelongsPackage: com.yuyu.srwildentity.conditionCheck
|
||||
@@ -17,6 +20,11 @@ import org.bukkit.block.Block;
|
||||
* @Description: 用于检查是否通过
|
||||
*/
|
||||
public class ConditionCheck {
|
||||
|
||||
|
||||
//实体碰撞
|
||||
public static final HashSet<Material> noEntityCollision = new HashSet<>();
|
||||
|
||||
/**
|
||||
* 检查entity生成位置是否符合
|
||||
* 1.位置
|
||||
@@ -30,10 +38,10 @@ public class ConditionCheck {
|
||||
*/
|
||||
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())
|
||||
&& 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){
|
||||
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){
|
||||
|
@@ -1,11 +1,24 @@
|
||||
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.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.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @BelongsProject: SrWildEntity
|
||||
@@ -21,19 +34,175 @@ public class ConfigManager {
|
||||
private final int refreshTime;
|
||||
private final int total;
|
||||
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) {
|
||||
//加载配置文件
|
||||
this.biomeEntityRefreshSettings = new BiomeEntityRefreshSettings(plugin);
|
||||
//保存配置文件
|
||||
plugin.saveResource("config.yml",false);
|
||||
FileConfiguration config;
|
||||
File file = new File(plugin.getDataFolder(), "config.yml");
|
||||
config = YamlConfiguration.loadConfiguration(file);
|
||||
|
||||
|
||||
this.refreshTime = config.getInt("RefreshTime");
|
||||
this.total = config.getInt("total");
|
||||
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() {
|
||||
@@ -51,4 +220,32 @@ public class ConfigManager {
|
||||
public int getTotal() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@@ -19,57 +20,26 @@ import java.util.List;
|
||||
* @Description: 读取实体刷新的配置相关文件
|
||||
*/
|
||||
public class BiomeEntityRefreshSettings {
|
||||
private final HashMap<String,List<String>> biomeEntityMap;//此集合储存了群系内需要刷新的怪物
|
||||
|
||||
private final HashMap<String,HashMap<String,EntityCondition>> biomeEntityConditionMap;//此集合储存需要刷新的怪物的相关配置
|
||||
// private final HashMap<String,List<String>> biomeEntityMap;//此集合储存了群系内需要刷新的怪物
|
||||
//
|
||||
// private final HashMap<String,HashMap<String,EntityCondition>> biomeEntityConditionMap;//此集合储存需要刷新的怪物的相关配置
|
||||
private final List<LevelRefresh> levelRefreshesList;
|
||||
|
||||
|
||||
public BiomeEntityRefreshSettings(Plugin plugin) {
|
||||
this.biomeEntityMap = new HashMap<>();
|
||||
this.biomeEntityConditionMap = new HashMap<>();
|
||||
public BiomeEntityRefreshSettings(Plugin plugin,int levelMax) {
|
||||
// this.biomeEntityMap = 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) {
|
||||
//保存文件
|
||||
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){
|
||||
private void loadRefreshEntity(Plugin plugin,int level){
|
||||
//保存文件
|
||||
plugin.saveResource("biomeEntity.yml",false);
|
||||
|
||||
@@ -90,26 +60,168 @@ public class BiomeEntityRefreshSettings {
|
||||
plugin.getLogger().info("biomeEntity.yml或者 biome.yml文件读取失败!");
|
||||
return;
|
||||
}
|
||||
// 等级 群系 实体列表
|
||||
HashMap<String,HashMap<String,List<String>>> levelBiomeMap = new HashMap<>();
|
||||
|
||||
//遍历所有可能的生物群系
|
||||
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());
|
||||
//按level循环
|
||||
for (int i = 1;i <= level;i++){
|
||||
HashMap<String,List<String>> biomeMap = new HashMap<>();
|
||||
//按群系循环
|
||||
for (String biome : biomeList){
|
||||
//判断该群系是否存在该等级的配置
|
||||
if (config.contains(biome)){
|
||||
//获取到后保存
|
||||
List<String> stringList = config.getStringList(biome + ".ENTITY_LEVEL_" + i);
|
||||
if (stringList.size() > 0) {
|
||||
biomeMap.put(biome, stringList);
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getLogger().info("biomeEntity.读取完成");
|
||||
}
|
||||
levelBiomeMap.put("level_"+i,biomeMap);
|
||||
}
|
||||
|
||||
public HashMap<String, List<String>> getBiomeEntityMap() {
|
||||
return biomeEntityMap;
|
||||
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());
|
||||
}
|
||||
|
||||
public HashMap<String, HashMap<String, EntityCondition>> getBiomeEntityConditionMap() {
|
||||
return biomeEntityConditionMap;
|
||||
//此处按群系储存list
|
||||
listHashMap.put(biome,entityConditions);
|
||||
}
|
||||
|
||||
//此处按等级储存对应等级的LevelRefresh对象
|
||||
this.levelRefreshesList.add(new LevelRefresh(riskMax,riskMin,listHashMap));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// private void loadEntityConditionConfig(Plugin plugin,int levelMax) {
|
||||
//
|
||||
// //保存文件
|
||||
// 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, List<String>> getBiomeEntityMap() {
|
||||
// return biomeEntityMap;
|
||||
// }
|
||||
//
|
||||
// public HashMap<String, HashMap<String, EntityCondition>> getBiomeEntityConditionMap() {
|
||||
// return biomeEntityConditionMap;
|
||||
// }
|
||||
|
||||
public List<LevelRefresh> getLevelRefreshesList() {
|
||||
return levelRefreshesList;
|
||||
}
|
||||
}
|
||||
|
@@ -20,8 +20,14 @@ public class EntityCondition {
|
||||
private final int nums;//刷新的数量
|
||||
private final int yMax;
|
||||
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.biome = biome;
|
||||
this.spawnEntityType = spawnEntityType;
|
||||
@@ -32,6 +38,39 @@ public class EntityCondition {
|
||||
this.nums = nums;
|
||||
this.yMax = yMax;
|
||||
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() {
|
||||
@@ -74,6 +113,14 @@ public class EntityCondition {
|
||||
return yMin;
|
||||
}
|
||||
|
||||
public double getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public long getRefreshTime() {
|
||||
return refreshTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EntityCondition{" +
|
||||
@@ -87,6 +134,9 @@ public class EntityCondition {
|
||||
", nums=" + nums +
|
||||
", yMax=" + yMax +
|
||||
", yMin=" + yMin +
|
||||
", riskMax=" + riskMax +
|
||||
", riskMin=" + riskMin +
|
||||
", weight=" + weight +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -1,27 +1,18 @@
|
||||
package com.yuyu.srwildentity.listener;
|
||||
|
||||
|
||||
import com.germ.germplugin.GermPlugin;
|
||||
import com.palmergames.bukkit.towny.TownyAPI;
|
||||
import com.palmergames.bukkit.towny.event.PlayerEnterTownEvent;
|
||||
import com.palmergames.bukkit.towny.event.PlayerLeaveTownEvent;
|
||||
import com.palmergames.bukkit.towny.object.Town;
|
||||
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.SpawnEntityType;
|
||||
import com.yuyu.srwildentity.pojo.PlayerRefreshinfo;
|
||||
import io.lumine.xikage.mythicmobs.MythicMobs;
|
||||
import io.lumine.xikage.mythicmobs.api.exceptions.InvalidMobTypeException;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -29,6 +20,7 @@ import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
@@ -47,46 +39,80 @@ import java.util.logging.Logger;
|
||||
public class EntityRefreshListener implements Listener, CommandExecutor {
|
||||
|
||||
private ConfigManager configManager;//配置相关
|
||||
|
||||
private boolean flag; //用于验证entity是否刷新
|
||||
private Logger logger;//日志打印
|
||||
public static Logger log;
|
||||
public static boolean logBool;
|
||||
public static boolean flag; //用于验证entity是否刷新
|
||||
private Random random;//生成随机数,随机实体的定位
|
||||
private HashMap<UUID,String> entityUUIDToPlayer;
|
||||
private HashMap<String, PlayerRefreshinfo> refreshPlayer;
|
||||
public static HashMap<UUID,String> entityUUIDToPlayer = new HashMap<>();//uuid定位到玩家刷新对象
|
||||
private List<String> noRefreshPlayer;//记录不需要刷新的玩家
|
||||
|
||||
private HashMap<String,PlayerRefreshLintener> refreshPlayer;//用来注册事件
|
||||
private Plugin plugin;
|
||||
private MythicMobs mythicMobs;
|
||||
private GermPlugin germPlugin;
|
||||
|
||||
|
||||
|
||||
|
||||
public EntityRefreshListener(Logger logger, ConfigManager configManager, Plugin plugin){
|
||||
|
||||
this.entityUUIDToPlayer = new HashMap<>();
|
||||
this.refreshPlayer = new HashMap<>();
|
||||
this.configManager = configManager;
|
||||
this.random = new Random();
|
||||
this.logger = logger;
|
||||
EntityRefreshListener.log = logger;
|
||||
this.flag = true;
|
||||
this.noRefreshPlayer = new ArrayList<>();
|
||||
this.plugin = plugin;
|
||||
logBool = false;
|
||||
//用于获取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
|
||||
*/
|
||||
public int prRisk(Player player){
|
||||
public static int prRisk(Player player){
|
||||
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
|
||||
String placeholder = PlaceholderAPI.setPlaceholders(player, "%prisk_level%");
|
||||
int level = Integer.parseInt(placeholder);
|
||||
@@ -106,6 +132,16 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
|
||||
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 (strings.length == 0){
|
||||
//只输入despawn,直接停止刷新
|
||||
@@ -115,12 +151,19 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
|
||||
Collection<? extends Player> onlinePlayers = plugin.getServer().getOnlinePlayers();
|
||||
for (Player player : onlinePlayers){
|
||||
String name = player.getName();
|
||||
Town town = TownyAPI.getInstance().getTown(player.getLocation());
|
||||
if (town == null){
|
||||
PlayerRefreshinfo playerRefreshinfo = new PlayerRefreshinfo(name, 0, new ArrayList<>());
|
||||
refreshPlayer.put(name, playerRefreshinfo);
|
||||
if (!this.playerStayTown(player.getLocation())){
|
||||
PlayerRefreshLintener playerRefreshLintener = new PlayerRefreshLintener(name,configManager);
|
||||
refreshPlayer.put(name, playerRefreshLintener);
|
||||
//注册监听事件
|
||||
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+"所有在野外的玩家开始刷新实体");
|
||||
return true;
|
||||
}
|
||||
@@ -128,13 +171,16 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
|
||||
//flag=false,清空所有集合,停止刷新实体
|
||||
entityUUIDToPlayer.clear();
|
||||
refreshPlayer.clear();
|
||||
logger.info(ChatColor.AQUA+"所有玩家停止刷新实体");
|
||||
if (logBool) {
|
||||
log.info(ChatColor.AQUA + "所有玩家停止刷新实体");
|
||||
}
|
||||
commandSender.sendMessage(ChatColor.AQUA+"所有玩家停止刷新实体");
|
||||
return true;
|
||||
}
|
||||
}else {
|
||||
String choice = strings[0];//只能是on,或者off
|
||||
if (choice.equalsIgnoreCase("on") || choice.equalsIgnoreCase("off")){
|
||||
String choice = strings[0];//只能是on,off或者clear
|
||||
if (choice.equalsIgnoreCase("on") || choice.equalsIgnoreCase("off")
|
||||
|| choice.equalsIgnoreCase("clear") || choice.equalsIgnoreCase("location")){
|
||||
if (choice.equalsIgnoreCase("on")){
|
||||
Player player = plugin.getServer().getPlayer(strings[1]);
|
||||
if (player == null){
|
||||
@@ -142,12 +188,13 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
|
||||
return true;
|
||||
}else {
|
||||
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);
|
||||
this.regRefreshEvent(strings[1]);
|
||||
commandSender.sendMessage(ChatColor.YELLOW+strings[1]+"开始刷怪");
|
||||
return true;
|
||||
}
|
||||
}else {
|
||||
}else if (choice.equalsIgnoreCase("off")){
|
||||
Player player = plugin.getServer().getPlayer(strings[1]);
|
||||
if (player == null){
|
||||
commandSender.sendMessage("请输入正确的玩家姓名!");
|
||||
@@ -156,9 +203,33 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
|
||||
//玩家不为空
|
||||
refreshPlayer.remove(strings[1]);
|
||||
noRefreshPlayer.add(strings[1]);
|
||||
this.cancleRefreshEvent(strings[1]);
|
||||
commandSender.sendMessage(ChatColor.YELLOW+strings[1]+"停止刷怪");
|
||||
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();
|
||||
Town town = TownyAPI.getInstance().getTown(player.getLocation());
|
||||
if (town == null){
|
||||
PlayerRefreshinfo playerRefreshinfo = new PlayerRefreshinfo(name, 0, new ArrayList<>());
|
||||
PlayerRefreshLintener playerRefreshinfo = new PlayerRefreshLintener(name, configManager);
|
||||
refreshPlayer.put(name, playerRefreshinfo);
|
||||
}
|
||||
logger.info(ChatColor.GREEN+"所有在野外的玩家开始刷新实体");
|
||||
if (logBool) {
|
||||
log.info(ChatColor.GREEN + "所有在野外的玩家开始刷新实体");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家进入城镇,
|
||||
* 玩家进入城镇,取消玩家的监听事件
|
||||
* @param event
|
||||
*/
|
||||
@EventHandler
|
||||
public void onPlayerInTown(PlayerEnterTownEvent event) {
|
||||
if (flag){
|
||||
|
||||
String name = event.getPlayer().getName();
|
||||
// List<UUID> entityList = refreshPlayer.get(name).getEntityList();
|
||||
// for (UUID uuid : entityList){
|
||||
// //删除储存的实体信息
|
||||
// entityUUIDToPlayer.remove(uuid);
|
||||
// }
|
||||
refreshPlayer.remove(name);
|
||||
logger.info(name + "开始停止怪物");
|
||||
this.cancleRefreshEvent(name);
|
||||
if (logBool) {
|
||||
log.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
|
||||
public void onPlayerLeaveTown(PlayerLeaveTownEvent event) {
|
||||
if (flag) {
|
||||
String name = event.getPlayer().getName();
|
||||
if (!noRefreshPlayer.contains(name)) {
|
||||
PlayerRefreshinfo playerRefreshinfo = new PlayerRefreshinfo(name, 0, new ArrayList<>());
|
||||
refreshPlayer.put(name, playerRefreshinfo);
|
||||
logger.info(name + "开始刷新实体");
|
||||
}
|
||||
}
|
||||
this.regRefreshEvent(name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,15 +304,11 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
|
||||
*/
|
||||
@EventHandler
|
||||
public void onPlayerJoinGame(PlayerJoinEvent event) {
|
||||
if (flag){
|
||||
Player player = event.getPlayer();
|
||||
String name = player.getName();
|
||||
Town town = TownyAPI.getInstance().getTown(player.getLocation());
|
||||
if (town == null && !noRefreshPlayer.contains(name)) {
|
||||
PlayerRefreshinfo playerRefreshinfo = new PlayerRefreshinfo(name, 0, new ArrayList<>());
|
||||
refreshPlayer.put(name, playerRefreshinfo);
|
||||
logger.info(ChatColor.MAGIC + player.getName() + "在野外登录,开始刷新实体");
|
||||
}
|
||||
if (!this.playerStayTown(player.getLocation()) && !noRefreshPlayer.contains(name)) {
|
||||
|
||||
this.regRefreshEvent(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,21 +317,25 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
|
||||
* @param event
|
||||
*/
|
||||
@EventHandler
|
||||
public void onPlayerOffOnline(PlayerQuitEvent event){
|
||||
if (flag) {
|
||||
public void onPlayerOffOnline(PlayerQuitEvent event) {
|
||||
|
||||
Player player = event.getPlayer();
|
||||
String name = player.getName();
|
||||
//下线后移出刷新列表
|
||||
if (refreshPlayer.get(name) != null) {
|
||||
List<UUID> entityList = refreshPlayer.get(name).getEntityList();
|
||||
for (UUID uuid : entityList){
|
||||
//删除储存的实体信息
|
||||
entityUUIDToPlayer.remove(uuid);
|
||||
this.cancleRefreshEvent(name);
|
||||
if (!refreshPlayer.containsKey(name)){
|
||||
if (logBool){
|
||||
log.info(ChatColor.RED+name+"玩家不在刷新列表!");
|
||||
}
|
||||
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))) {
|
||||
//通过死亡实体的uuid获取玩家姓名然后删除uuid
|
||||
String playerName = entityUUIDToPlayer.get(uniqueId);
|
||||
refreshPlayer.get(playerName).delEntityList(uniqueId);
|
||||
refreshPlayer.get(playerName).getPlayerRefreshinfo().delEntityList(uniqueId);
|
||||
entityUUIDToPlayer.remove(uniqueId);
|
||||
}
|
||||
}
|
||||
@@ -292,160 +373,95 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
|
||||
//通过uuid获取对应的玩家姓名,然后通过玩家姓名获取对应的list集合
|
||||
String name = entityUUIDToPlayer.get(uniqueId);
|
||||
|
||||
refreshPlayer.get(name).delEntityList(uniqueId);
|
||||
if (refreshPlayer.containsKey(name)) {
|
||||
refreshPlayer.get(name).getPlayerRefreshinfo().delEntityList(uniqueId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 定时任务,每隔一段时间在玩家附近刷新实体
|
||||
* 清空所有记录在的实体
|
||||
*/
|
||||
public void timedRdfreshEneity(){
|
||||
if (flag) {
|
||||
int num = configManager.getNum();//每次执行时刷新的总数
|
||||
for (String name : refreshPlayer.keySet()) {
|
||||
if (noRefreshPlayer.contains(name)){
|
||||
continue;
|
||||
public void clearRefreshEntity(){
|
||||
Server server = plugin.getServer();
|
||||
// Collection<? extends Player> onlinePlayers = server.getOnlinePlayers();
|
||||
|
||||
for (PlayerRefreshLintener player : refreshPlayer.values()){
|
||||
|
||||
List<UUID> entityList = player.getPlayerRefreshinfo().getEntityList();
|
||||
for (UUID uuid : entityList){
|
||||
Entity entity = server.getEntity(uuid);
|
||||
if (entity != null){
|
||||
entity.remove();
|
||||
if (entityUUIDToPlayer.containsKey(uuid)){
|
||||
entityUUIDToPlayer.remove(uuid);
|
||||
}
|
||||
int sum = 0;//用于记录此次刷新生成的总数
|
||||
//获取玩家信息
|
||||
Player player = plugin.getServer().getPlayer(name);
|
||||
PlayerRefreshinfo playerRefreshinfo = refreshPlayer.get(name);
|
||||
|
||||
//玩家危险度,用于刷新实体的等级
|
||||
int level = this.prRisk(player);
|
||||
//TODO(危险度提示,后续需要使用这个变量去控制怪物的参数等级`)
|
||||
logger.info(ChatColor.GREEN + "危险度为:" + level);
|
||||
|
||||
|
||||
Location playerlocation = player.getLocation();
|
||||
|
||||
//获取玩家位置信息
|
||||
World world = playerlocation.getWorld();
|
||||
int blockZ = playerlocation.getBlockZ();
|
||||
int blockX = playerlocation.getBlockX();
|
||||
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;
|
||||
}
|
||||
|
||||
int nums = entityCondition.getNums();//当前实体需要刷新的数量
|
||||
|
||||
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);
|
||||
if (entityUUIDToPlayer.containsKey(uuid)){
|
||||
entityUUIDToPlayer.remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
logger.info(ChatColor.GOLD + "在" + x + " " + y + " " + z + "位置刷新了" + entityName);
|
||||
UUID uniqueId = entity.getUniqueId();
|
||||
|
||||
//存入玩家对应的刷新的实体集合,便于寻找
|
||||
entityUUIDToPlayer.put(uniqueId, name);
|
||||
|
||||
//存入
|
||||
playerRefreshinfo.addEntityList(uniqueId);
|
||||
|
||||
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 {
|
||||
//不刷新在地上,在定义的范围内随机高度,概率生成实体,
|
||||
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; // 同上,在玩家附近随机位置生成
|
||||
entityUUIDToPlayer.remove(uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Location location = new Location(world, x, y + 1, z);
|
||||
public void playerRefreshEntiyt(String name){
|
||||
if (!noRefreshPlayer.contains(name) && !entityUUIDToPlayer.containsValue(name)) {
|
||||
|
||||
//判断位置是否符合
|
||||
if (ConditionCheck.checkEntityRefresh(world, location, entityCondition)) {
|
||||
//通过则生成
|
||||
Entity entity;
|
||||
//MC原生实体
|
||||
if (entityCondition.getEntityType() == SpawnEntityType.PROTOGENESIS){
|
||||
entity = world.spawnEntity(location, EntityType.valueOf(entityCondition.getEntityName()));
|
||||
PlayerRefreshLintener playerRefreshinfo = new PlayerRefreshLintener(name, configManager);
|
||||
refreshPlayer.put(name, playerRefreshinfo);
|
||||
if (logBool) {
|
||||
log.info(name + "开始刷新实体");
|
||||
}
|
||||
}else {
|
||||
//刷新MM怪物
|
||||
try {
|
||||
entity = mythicMobs.getAPIHelper().spawnMythicMob(entityName, location);
|
||||
} catch (InvalidMobTypeException e) {
|
||||
throw new RuntimeException(e);
|
||||
List<UUID> uuidList = new ArrayList<>();
|
||||
for (UUID uuid : entityUUIDToPlayer.keySet()){
|
||||
String s = entityUUIDToPlayer.get(uuid);
|
||||
if (s.equals(name)){
|
||||
uuidList.add(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(ChatColor.GOLD + "在" + x + " " + y + " " + z + "位置刷新了" + entityName);
|
||||
UUID uniqueId = entity.getUniqueId();
|
||||
|
||||
//存入玩家对应的刷新的实体集合,便于寻找
|
||||
entityUUIDToPlayer.put(uniqueId, name);
|
||||
|
||||
//存入
|
||||
playerRefreshinfo.addEntityList(uniqueId);
|
||||
i++;
|
||||
sum++;
|
||||
|
||||
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() {
|
||||
return configManager;
|
||||
@@ -458,5 +474,8 @@ public class EntityRefreshListener implements Listener, CommandExecutor {
|
||||
|
||||
public void setConfigManager(ConfigManager configManager) {
|
||||
this.configManager = configManager;
|
||||
for (String name : refreshPlayer.keySet()){
|
||||
refreshPlayer.get(name).setConfigManager(configManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
105
src/main/java/com/yuyu/srwildentity/pojo/AreaRefresh.java
Normal file
105
src/main/java/com/yuyu/srwildentity/pojo/AreaRefresh.java
Normal 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;
|
||||
}
|
||||
}
|
81
src/main/java/com/yuyu/srwildentity/pojo/BlackListArea.java
Normal file
81
src/main/java/com/yuyu/srwildentity/pojo/BlackListArea.java
Normal 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;
|
||||
}
|
||||
}
|
18
src/main/resources/LEVEL_1.yml
Normal file
18
src/main/resources/LEVEL_1.yml
Normal 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
|
||||
|
0
src/main/resources/LEVEL_2.yml
Normal file
0
src/main/resources/LEVEL_2.yml
Normal file
10
src/main/resources/areaRefresh.yml
Normal file
10
src/main/resources/areaRefresh.yml
Normal 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]
|
12
src/main/resources/area_Entity.yml
Normal file
12
src/main/resources/area_Entity.yml
Normal 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
|
@@ -1,6 +1,7 @@
|
||||
DESERT: #群系名称,下方标出该群系需要刷新的entity
|
||||
ENTITY: [ZOMBIE,PIG_ZOMBIE] #该群系刷新的entity,具体的怪物刷新配置需要去entityConfig.yml中配置,!!注意此处的实体配置一定要在实体配置文件中存在,否则会不会刷新!
|
||||
ENTITY_LEVEL_1: [ZOMBIE,PIG_ZOMBIE] #该群系刷新的entity,具体的怪物刷新配置需要去entityConfig.yml中配置,!!注意此处的实体配置一定要在实体配置文件中存在,否则会不会刷新!
|
||||
|
||||
|
||||
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中配置,!!注意此处的实体配置一定要在实体配置文件中存在,否则会不会刷新!
|
||||
|
13
src/main/resources/blacklistArea.yml
Normal file
13
src/main/resources/blacklistArea.yml
Normal 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
|
3
src/main/resources/blacklistWorld.yml
Normal file
3
src/main/resources/blacklistWorld.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
#世界黑名单
|
||||
blacklistWorld:
|
||||
- TravelersDreamCompact
|
@@ -1,3 +1,12 @@
|
||||
RefreshTime: 10 #刷新时间,单位为s
|
||||
total: 12 #每个玩家每次刷新的实体数量
|
||||
num: 4 #单次刷新的数量,每RefreshTime秒刷新的数量
|
||||
total: 12 #每个玩家最多刷新的实体数量
|
||||
num: 4 #单次刷新的最大数量,每RefreshTime秒刷新的数量
|
||||
LEVEL_MAX: 2 #能够刷新的最高等级,便于读取文件
|
||||
attempts: 6 #权重通过时,随机位置的最大次数
|
||||
blacklistNums: 1 #黑名单区域的数量的数量
|
||||
location_1: #黑名单区域
|
||||
world_name: TravelersDreamCompact
|
||||
x1: 100
|
||||
z1: 100
|
||||
x2: 200
|
||||
z2: 200
|
6
src/main/resources/datasource.yml
Normal file
6
src/main/resources/datasource.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
database:
|
||||
sql:
|
||||
user: root
|
||||
password:
|
||||
driver: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/mc_service
|
@@ -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 #最小刷新高度
|
@@ -2,6 +2,12 @@ name: SrWildEntity
|
||||
version: '${project.version}'
|
||||
main: com.yuyu.srwildentity.SrWildEntity
|
||||
description: 实体刷新插件
|
||||
depend:
|
||||
- Towny
|
||||
- PlaceholderAPI
|
||||
- PlayerRisk
|
||||
- MythicMobs
|
||||
- GermPlugin
|
||||
authors: [Yuyu]
|
||||
commands:
|
||||
despawn:
|
||||
|
@@ -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
|
@@ -1,6 +0,0 @@
|
||||
DESERT: #群系名称,下方标出该群系需要刷新的entity
|
||||
ENTITY: [ZOMBIE,PIG_ZOMBIE] #该群系刷新的entity,具体的怪物刷新配置需要去entityConfig.yml中配置,!!注意此处的实体配置一定要在实体配置文件中存在,否则会不会刷新!
|
||||
|
||||
|
||||
ROOFED_FOREST: #群系名称,下方标出该群系需要刷新的entity
|
||||
ENTITY: [ZOMBIE,PIG_ZOMBIE] #该群系刷新的entity,具体的怪物刷新配置需要去entityConfig.yml中配置,!!注意此处的实体配置一定要在实体配置文件中存在,否则会不会刷新!
|
@@ -1,3 +0,0 @@
|
||||
RefreshTime: 10 #刷新时间,单位为s
|
||||
total: 12 #每个玩家每次刷新的实体数量
|
||||
num: 4 #单次刷新的数量,每RefreshTime秒刷新的数量
|
@@ -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: 你没有使用权限!
|
Reference in New Issue
Block a user