initial commit
This commit is contained in:
commit
014f65bc86
29
.gitignore
vendored
Normal file
29
.gitignore
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
# gradle
|
||||
|
||||
.gradle/
|
||||
build/
|
||||
out/
|
||||
classes/
|
||||
|
||||
# eclipse
|
||||
|
||||
*.launch
|
||||
|
||||
# idea
|
||||
|
||||
.idea/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
# vscode
|
||||
|
||||
.settings/
|
||||
.vscode/
|
||||
bin/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
# fabric
|
||||
|
||||
run/
|
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Fabric Example Mod
|
||||
|
||||
## Setup
|
||||
|
||||
For setup instructions please see the [fabric wiki page](https://fabricmc.net/wiki/tutorial:setup) that relates to the IDE that you are using.
|
||||
|
||||
## License
|
||||
|
||||
This template is available under the CC0 license. Feel free to learn from it and incorporate it in your own projects.
|
84
build.gradle
Normal file
84
build.gradle
Normal file
@ -0,0 +1,84 @@
|
||||
plugins {
|
||||
id 'fabric-loom' version '0.4-SNAPSHOT'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
|
||||
archivesBaseName = project.archives_base_name
|
||||
version = project.mod_version
|
||||
group = project.maven_group
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//to change the versions see the gradle.properties file
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
|
||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||
|
||||
compile group: 'org.yaml', name: 'snakeyaml', version: '1.25'
|
||||
include group: 'org.yaml', name: 'snakeyaml', version: '1.25'
|
||||
|
||||
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
|
||||
// You may need to force-disable transitiveness on them.
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include "fabric.mod.json"
|
||||
expand "version": project.version
|
||||
}
|
||||
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude "fabric.mod.json"
|
||||
}
|
||||
}
|
||||
|
||||
// ensure that the encoding is set to UTF-8, no matter what the system default is
|
||||
// this fixes some edge cases with special characters not displaying correctly
|
||||
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||||
// if it is present.
|
||||
// If you remove this task, sources will not be generated.
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = "sources"
|
||||
from sourceSets.main.allSource
|
||||
}
|
||||
|
||||
jar {
|
||||
from "LICENSE"
|
||||
}
|
||||
|
||||
// configure the maven publication
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
// add all the jars that should be included when publishing to maven
|
||||
artifact(remapJar) {
|
||||
builtBy remapJar
|
||||
}
|
||||
artifact(sourcesJar) {
|
||||
builtBy remapSourcesJar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// select the repositories you want to publish to
|
||||
repositories {
|
||||
// uncomment to publish to the local maven
|
||||
// mavenLocal()
|
||||
}
|
||||
}
|
18
gradle.properties
Normal file
18
gradle.properties
Normal file
@ -0,0 +1,18 @@
|
||||
# Done to increase the memory available to gradle.
|
||||
org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/use
|
||||
minecraft_version=1.16.2
|
||||
yarn_mappings=1.16.2+build.1
|
||||
loader_version=0.9.1+build.205
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.0.0
|
||||
maven_group = com.flemmli97
|
||||
archives_base_name = thisismyland
|
||||
|
||||
# Dependencies
|
||||
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
||||
fabric_version=0.17.2+build.396-1.16
|
||||
cca_version=2.5.0-nightly.1.16.2-rc2
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
183
gradlew
vendored
Executable file
183
gradlew
vendored
Executable file
@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
103
gradlew.bat
vendored
Normal file
103
gradlew.bat
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
10
settings.gradle
Normal file
10
settings.gradle
Normal file
@ -0,0 +1,10 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
jcenter()
|
||||
maven {
|
||||
name = 'Fabric'
|
||||
url = 'https://maven.fabricmc.net/'
|
||||
}
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
37
src/main/java/com/flemmli97/flan/Flan.java
Normal file
37
src/main/java/com/flemmli97/flan/Flan.java
Normal file
@ -0,0 +1,37 @@
|
||||
package com.flemmli97.flan;
|
||||
|
||||
import com.flemmli97.flan.claim.ObjectToPermissionMap;
|
||||
import com.flemmli97.flan.commands.CommandClaim;
|
||||
import com.flemmli97.flan.config.ConfigHandler;
|
||||
import com.flemmli97.flan.event.BlockInteractEvents;
|
||||
import com.flemmli97.flan.event.EntityInteractEvents;
|
||||
import com.flemmli97.flan.event.ItemInteractEvents;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
|
||||
import net.fabricmc.fabric.api.event.player.AttackEntityCallback;
|
||||
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
|
||||
import net.fabricmc.fabric.api.event.player.UseEntityCallback;
|
||||
import net.fabricmc.fabric.api.event.player.UseItemCallback;
|
||||
|
||||
public class Flan implements ModInitializer {
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
|
||||
//Events
|
||||
AttackBlockCallback.EVENT.register(BlockInteractEvents::breakBlocks);
|
||||
UseBlockCallback.EVENT.register(BlockInteractEvents::useBlocks);
|
||||
UseEntityCallback.EVENT.register(EntityInteractEvents::useAtEntity);
|
||||
AttackEntityCallback.EVENT.register(EntityInteractEvents::attackEntity);
|
||||
UseItemCallback.EVENT.register(ItemInteractEvents::useItem);
|
||||
ServerLifecycleEvents.SERVER_STARTING.register(ConfigHandler::serverLoad);
|
||||
ServerLifecycleEvents.SERVER_STARTING.register(ObjectToPermissionMap::reload);
|
||||
//Explosion
|
||||
//XP
|
||||
//TARGETBLOCK
|
||||
//Commands
|
||||
CommandRegistrationCallback.EVENT.register(CommandClaim::register);
|
||||
}
|
||||
}
|
6
src/main/java/com/flemmli97/flan/IClaimData.java
Normal file
6
src/main/java/com/flemmli97/flan/IClaimData.java
Normal file
@ -0,0 +1,6 @@
|
||||
package com.flemmli97.flan;
|
||||
|
||||
public interface IClaimData {
|
||||
|
||||
Object getClaimData();
|
||||
}
|
417
src/main/java/com/flemmli97/flan/claim/Claim.java
Normal file
417
src/main/java/com/flemmli97/flan/claim/Claim.java
Normal file
@ -0,0 +1,417 @@
|
||||
package com.flemmli97.flan.claim;
|
||||
|
||||
import com.flemmli97.flan.player.PlayerClaimData;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class Claim {
|
||||
|
||||
private boolean dirty;
|
||||
private int minX, minZ, maxX, maxZ, minY;
|
||||
|
||||
private UUID owner;
|
||||
private UUID claimID;
|
||||
private final EnumSet<EnumPermission> globalPerm = EnumSet.noneOf(EnumPermission.class);
|
||||
private final Map<String, EnumMap<EnumPermission, Boolean>> permissions = Maps.newHashMap();
|
||||
|
||||
private final Map<UUID, String> playersGroups = Maps.newHashMap();
|
||||
|
||||
private final List<Claim> subClaims = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* Flag for players tracking this claim
|
||||
*/
|
||||
private boolean removed;
|
||||
|
||||
private Claim() {
|
||||
}
|
||||
|
||||
public Claim(BlockPos pos1, BlockPos pos2, UUID creator) {
|
||||
this(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ(), Math.min(pos1.getY(), pos2.getY()), creator);
|
||||
}
|
||||
|
||||
public Claim(int x1, int x2, int z1, int z2, int minY, UUID creator) {
|
||||
this.minX = Math.min(x1, x2);
|
||||
this.minZ = Math.min(z1, z2);
|
||||
this.maxX = Math.max(x1, x2);
|
||||
this.maxZ = Math.max(z1, z2);
|
||||
this.minY = Math.max(0, minY);
|
||||
this.owner = creator;
|
||||
}
|
||||
|
||||
public static Claim fromTag(CompoundTag tag) {
|
||||
Claim claim = new Claim();
|
||||
claim.read(tag);
|
||||
return claim;
|
||||
}
|
||||
|
||||
public static Claim fromJson(JsonObject obj, UUID owner) {
|
||||
Claim claim = new Claim();
|
||||
claim.readJson(obj, owner);
|
||||
return claim;
|
||||
}
|
||||
|
||||
public void setClaimID(UUID uuid) {
|
||||
this.claimID = uuid;
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
public UUID getClaimID() {
|
||||
return this.claimID;
|
||||
}
|
||||
|
||||
public UUID getOwner() {
|
||||
return this.owner;
|
||||
}
|
||||
|
||||
public int getPlane() {
|
||||
return (this.maxX - this.minX) * (this.maxZ - this.minZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The claims dimension in order: x, X, z, Z, y
|
||||
*/
|
||||
public int[] getDimensions() {
|
||||
return new int[]{this.minX, this.maxX, this.minZ, this.maxZ, this.minY};
|
||||
}
|
||||
|
||||
public boolean insideClaim(BlockPos pos) {
|
||||
return this.minX <= pos.getX() && this.maxX >= pos.getX() && this.minZ <= pos.getZ() && this.maxZ >= pos.getZ() && this.minY <= pos.getY();
|
||||
}
|
||||
|
||||
public boolean intersects(Claim other) {
|
||||
return this.minX < other.maxX && this.maxX > other.minX && this.minZ < other.maxZ && this.maxZ > other.minZ;
|
||||
}
|
||||
|
||||
public boolean isCorner(BlockPos pos) {
|
||||
return (pos.getX() == this.minX && pos.getZ() == this.minZ) || (pos.getX() == this.minX && pos.getZ() == this.maxZ)
|
||||
|| (pos.getX() == this.maxX && pos.getZ() == this.minZ) || (pos.getX() == this.maxX && pos.getZ() == this.maxZ);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
this.removed = true;
|
||||
}
|
||||
|
||||
public boolean isRemoved() {
|
||||
return this.removed;
|
||||
}
|
||||
|
||||
public boolean canInteract(PlayerEntity player, EnumPermission perm, BlockPos pos) {
|
||||
if (perm == EnumPermission.EXPLOSIONS || perm == EnumPermission.WITHER) {
|
||||
for (Claim claim : this.subClaims) {
|
||||
if (claim.insideClaim(pos)) {
|
||||
if (claim.canInteract(player, perm, pos))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this.permEnabled(perm);
|
||||
}
|
||||
if (player.getUuid().equals(this.owner))
|
||||
return true;
|
||||
PlayerClaimData data = PlayerClaimData.get(player);
|
||||
if (player.hasPermissionLevel(2) && data.isAdminIgnoreClaim())
|
||||
return true;
|
||||
for (Claim claim : this.subClaims) {
|
||||
if (claim.insideClaim(pos)) {
|
||||
if (claim.canInteract(player, perm, pos))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this.playersGroups.containsKey(player.getUuid())) {
|
||||
EnumMap<EnumPermission, Boolean> map = this.permissions.get(this.playersGroups.get(player.getUuid()));
|
||||
if (map != null && map.containsKey(perm))
|
||||
return map.get(perm);
|
||||
}
|
||||
return this.permEnabled(perm);
|
||||
}
|
||||
|
||||
public boolean permEnabled(EnumPermission perm) {
|
||||
return this.globalPerm.contains(perm);
|
||||
}
|
||||
|
||||
public boolean tryCreateSubClaim(BlockPos pos1, BlockPos pos2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Claim getSubClaim(BlockPos pos) {
|
||||
for (Claim claim : this.subClaims)
|
||||
if (claim.insideClaim(pos))
|
||||
return claim;
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean setPlayerGroup(UUID player, String group, boolean force) {
|
||||
if (group == null) {
|
||||
this.playersGroups.remove(player);
|
||||
this.setDirty();
|
||||
return true;
|
||||
}
|
||||
if (!this.playersGroups.containsKey(player) || force) {
|
||||
this.playersGroups.put(player, group);
|
||||
this.setDirty();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<String> playersFromGroup(MinecraftServer server, String group) {
|
||||
List<UUID> l = Lists.newArrayList();
|
||||
this.playersGroups.forEach((uuid, g) -> {
|
||||
if (g.equals(group))
|
||||
l.add(uuid);
|
||||
});
|
||||
List<String> names = Lists.newArrayList();
|
||||
l.forEach(uuid -> {
|
||||
GameProfile prof = server.getUserCache().getByUuid(uuid);
|
||||
if (prof != null)
|
||||
names.add(prof.getName());
|
||||
});
|
||||
names.sort(null);
|
||||
return names;
|
||||
}
|
||||
|
||||
public void editGlobalPerms(EnumPermission toggle) {
|
||||
if (this.globalPerm.contains(toggle))
|
||||
this.globalPerm.remove(toggle);
|
||||
else
|
||||
this.globalPerm.add(toggle);
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit the permissions for a group. If not defined for the group creates a new default permission map for that group
|
||||
*
|
||||
* @param mode -1 = makes it resort to the global perm, 0 = deny perm, 1 = allow perm
|
||||
* @return If editing was successful or not
|
||||
*/
|
||||
public boolean editPerms(PlayerEntity player, String group, EnumPermission perm, int mode) {
|
||||
if (player.getUuid().equals(this.owner) || this.canInteract(player, EnumPermission.EDITPERMS, player.getBlockPos())) {
|
||||
if (mode > 1)
|
||||
mode = -1;
|
||||
boolean has = this.permissions.containsKey(perm);
|
||||
EnumMap<EnumPermission, Boolean> perms = has ? this.permissions.get(group) : new EnumMap(EnumPermission.class);
|
||||
if (mode == -1)
|
||||
perms.remove(perm);
|
||||
else
|
||||
perms.put(perm, mode == 1);
|
||||
if (!has)
|
||||
this.permissions.put(group, perms);
|
||||
this.setDirty();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean removePermGroup(PlayerEntity player, String group) {
|
||||
if (player.getUuid().equals(this.owner) || this.canInteract(player, EnumPermission.EDITPERMS, player.getBlockPos())) {
|
||||
this.permissions.remove(group);
|
||||
List<UUID> toRemove = Lists.newArrayList();
|
||||
this.playersGroups.forEach((uuid, g) -> {
|
||||
if (g.equals(group))
|
||||
toRemove.add(uuid);
|
||||
});
|
||||
toRemove.forEach(uuid -> this.playersGroups.remove(uuid));
|
||||
this.setDirty();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int groupHasPerm(String rank, EnumPermission perm) {
|
||||
if (!this.permissions.containsKey(rank) || !this.permissions.get(rank).containsKey(perm))
|
||||
return -1;
|
||||
return this.permissions.get(rank).get(perm) ? 1 : 0;
|
||||
}
|
||||
|
||||
public List<String> groups() {
|
||||
List<String> l = Lists.newArrayList(this.permissions.keySet());
|
||||
l.sort(null);
|
||||
return l;
|
||||
}
|
||||
|
||||
public boolean addSubClaims(Claim claim) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setDirty() {
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return this.dirty;
|
||||
}
|
||||
|
||||
public void readJson(JsonObject obj, UUID uuid) {
|
||||
JsonArray pos = obj.getAsJsonArray("PosxXzZY");
|
||||
this.minX = pos.get(0).getAsInt();
|
||||
this.maxX = pos.get(1).getAsInt();
|
||||
this.minZ = pos.get(2).getAsInt();
|
||||
this.maxZ = pos.get(3).getAsInt();
|
||||
this.minY = pos.get(4).getAsInt();
|
||||
this.owner = uuid;
|
||||
this.claimID = UUID.fromString(obj.get("ID").getAsString());
|
||||
this.globalPerm.clear();
|
||||
this.permissions.clear();
|
||||
this.subClaims.clear();
|
||||
if (obj.has("GlobalPerms")) {
|
||||
obj.getAsJsonArray("GlobalPerms").forEach(perm -> this.globalPerm.add(EnumPermission.valueOf(perm.getAsString())));
|
||||
}
|
||||
if (obj.has("PermGroup")) {
|
||||
JsonObject perms = obj.getAsJsonObject("PermGroup");
|
||||
perms.entrySet().forEach(key -> {
|
||||
EnumMap<EnumPermission, Boolean> map = new EnumMap(EnumPermission.class);
|
||||
JsonObject group = key.getValue().getAsJsonObject();
|
||||
group.entrySet().forEach(gkey -> map.put(EnumPermission.valueOf(gkey.getKey()), gkey.getValue().getAsBoolean()));
|
||||
this.permissions.put(key.getKey(), map);
|
||||
});
|
||||
}
|
||||
if (obj.has("PlayerPerms")) {
|
||||
JsonObject pl = obj.getAsJsonObject("PlayerPerms");
|
||||
pl.entrySet().forEach(key -> this.playersGroups.put(UUID.fromString(key.getKey()), key.getValue().getAsString()));
|
||||
}
|
||||
if (obj.has("SubClaims")) {
|
||||
obj.getAsJsonArray("SubClaims").forEach(sub -> this.subClaims.add(Claim.fromJson(sub.getAsJsonObject(), this.owner)));
|
||||
}
|
||||
}
|
||||
|
||||
public JsonObject toJson(JsonObject obj) {
|
||||
JsonArray pos = new JsonArray();
|
||||
pos.add(this.minX);
|
||||
pos.add(this.maxX);
|
||||
pos.add(this.minZ);
|
||||
pos.add(this.maxZ);
|
||||
pos.add(this.minY);
|
||||
obj.add("PosxXzZY", pos);
|
||||
|
||||
obj.addProperty("ID", this.claimID.toString());
|
||||
if (!this.globalPerm.isEmpty()) {
|
||||
JsonArray gPerm = new JsonArray();
|
||||
this.globalPerm.forEach(p -> gPerm.add(p.toString()));
|
||||
obj.add("GlobalPerms", gPerm);
|
||||
}
|
||||
if (!this.permissions.isEmpty()) {
|
||||
JsonObject perms = new JsonObject();
|
||||
this.permissions.forEach((s, pmap) -> {
|
||||
JsonObject group = new JsonObject();
|
||||
pmap.forEach((perm, bool) -> group.addProperty(perm.toString(), bool));
|
||||
perms.add(s, group);
|
||||
});
|
||||
obj.add("PermGroup", perms);
|
||||
}
|
||||
if (!this.playersGroups.isEmpty()) {
|
||||
JsonObject pl = new JsonObject();
|
||||
this.playersGroups.forEach((uuid, s) -> pl.addProperty(uuid.toString(), s));
|
||||
obj.add("PlayerPerms", pl);
|
||||
}
|
||||
if (!this.subClaims.isEmpty()) {
|
||||
JsonArray list = new JsonArray();
|
||||
this.subClaims.forEach(p -> list.add(p.toJson(new JsonObject())));
|
||||
obj.add("SubClaims", list);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
public CompoundTag save(CompoundTag tag) {
|
||||
tag.putIntArray("PosxXzZY", new int[]{this.minX, this.maxX, this.minZ, this.maxZ, this.minY});
|
||||
tag.putUuid("Owner", this.owner);
|
||||
tag.putUuid("ID", this.claimID);
|
||||
if (!this.globalPerm.isEmpty()) {
|
||||
ListTag list = new ListTag();
|
||||
this.globalPerm.forEach(p -> list.add(StringTag.of(p.toString())));
|
||||
tag.put("GlobalPerms", list);
|
||||
}
|
||||
if (!this.permissions.isEmpty()) {
|
||||
CompoundTag perms = new CompoundTag();
|
||||
this.permissions.forEach((s, pmap) -> {
|
||||
CompoundTag group = new CompoundTag();
|
||||
pmap.forEach((perm, bool) -> group.putBoolean(perm.toString(), bool));
|
||||
perms.put(s, group);
|
||||
});
|
||||
tag.put("PermGroup", perms);
|
||||
}
|
||||
if (!this.playersGroups.isEmpty()) {
|
||||
CompoundTag pl = new CompoundTag();
|
||||
this.playersGroups.forEach((uuid, s) -> pl.putString(uuid.toString(), s));
|
||||
tag.put("PlayerPerms", pl);
|
||||
}
|
||||
if (!this.subClaims.isEmpty()) {
|
||||
ListTag list = new ListTag();
|
||||
this.subClaims.forEach(p -> list.add(p.save(new CompoundTag())));
|
||||
tag.put("SubClaims", list);
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void read(CompoundTag tag) {
|
||||
int[] pos = tag.getIntArray("PosxXzZY");
|
||||
this.minY = pos[0];
|
||||
this.maxX = pos[1];
|
||||
this.minZ = pos[2];
|
||||
this.maxZ = pos[3];
|
||||
this.minY = pos[4];
|
||||
this.owner = tag.getUuid("Owner");
|
||||
this.claimID = tag.getUuid("ID");
|
||||
this.globalPerm.clear();
|
||||
this.permissions.clear();
|
||||
this.subClaims.clear();
|
||||
if (tag.contains("GlobalPerms")) {
|
||||
tag.getList("GlobalPerms", 8).forEach(perm -> this.globalPerm.add(EnumPermission.valueOf(perm.asString())));
|
||||
}
|
||||
if (tag.contains("PermGroup")) {
|
||||
CompoundTag perms = tag.getCompound("PermGroup");
|
||||
perms.getKeys().forEach(key -> {
|
||||
EnumMap<EnumPermission, Boolean> map = new EnumMap(EnumPermission.class);
|
||||
CompoundTag group = perms.getCompound(key);
|
||||
group.getKeys().forEach(gkey -> map.put(EnumPermission.valueOf(gkey), group.getBoolean(gkey)));
|
||||
this.permissions.put(key, map);
|
||||
});
|
||||
}
|
||||
if (tag.contains("PlayerPerms")) {
|
||||
CompoundTag pl = tag.getCompound("PlayerPerms");
|
||||
pl.getKeys().forEach(key -> this.playersGroups.put(UUID.fromString(key), pl.getString(key)));
|
||||
}
|
||||
if (tag.contains("SubClaims")) {
|
||||
tag.getList("SubClaims", 10).forEach(sub -> this.subClaims.add(Claim.fromTag((CompoundTag) sub)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.claimID.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj instanceof Claim)
|
||||
return this.claimID.equals(((Claim) obj).claimID);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Claim:[Owner:%s, from: x=%d; z=%d, to: x=%d, z=%d", this.owner.toString(), this.minX, this.minZ, this.maxX, this.maxZ);
|
||||
}
|
||||
|
||||
public String formattedClaim() {
|
||||
return String.format("[x=%d,z=%d] to: [x=%d,z=%d]", this.minX, this.minZ, this.maxX, this.maxZ);
|
||||
}
|
||||
}
|
299
src/main/java/com/flemmli97/flan/claim/ClaimStorage.java
Normal file
299
src/main/java/com/flemmli97/flan/claim/ClaimStorage.java
Normal file
@ -0,0 +1,299 @@
|
||||
package com.flemmli97.flan.claim;
|
||||
|
||||
import com.flemmli97.flan.IClaimData;
|
||||
import com.flemmli97.flan.player.PlayerClaimData;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.ibm.icu.impl.Pair;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectArrayMap;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.WorldSavePath;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ClaimStorage {
|
||||
|
||||
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
|
||||
public final Long2ObjectArrayMap<List<Claim>> claims = new Long2ObjectArrayMap();
|
||||
public final Map<UUID, Claim> claimUUIDMap = Maps.newHashMap();
|
||||
public final Map<UUID, Set<Claim>> playerClaimMap = Maps.newHashMap();
|
||||
|
||||
public static ClaimStorage get(ServerWorld world) {
|
||||
return (ClaimStorage) ((IClaimData) world).getClaimData();
|
||||
}
|
||||
|
||||
public ClaimStorage(MinecraftServer server, RegistryKey<World> key) {
|
||||
this.read(server, key);
|
||||
}
|
||||
|
||||
public UUID generateUUID() {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
if (this.claimUUIDMap.containsKey(uuid))
|
||||
return generateUUID();
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public boolean createClaim(BlockPos pos1, BlockPos pos2, PlayerEntity player) {
|
||||
Claim claim = new Claim(pos1.down(5), pos2.down(5), player.getUuid());
|
||||
boolean conflicts = conflicts(claim, null);
|
||||
if (!conflicts) {
|
||||
PlayerClaimData data = PlayerClaimData.get(player);
|
||||
if (!data.useClaimBlocks(claim.getPlane()))
|
||||
return false;
|
||||
claim.setClaimID(this.generateUUID());
|
||||
this.addClaim(claim);
|
||||
data.addDisplayClaim(claim);
|
||||
return true;
|
||||
}
|
||||
player.sendMessage(Text.of("Error creating claim"), false);
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean conflicts(Claim claim, Claim except) {
|
||||
int[] chunks = getChunkPos(claim);
|
||||
for (int x = chunks[0]; x <= chunks[1]; x++)
|
||||
for (int z = chunks[2]; z <= chunks[3]; z++) {
|
||||
List<Claim> claims = this.claims.get(new ChunkPos(x, z).toLong());
|
||||
if (claims != null)
|
||||
for (Claim other : claims) {
|
||||
if (claim.intersects(other) && !claim.equals(except)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean deleteClaim(Claim claim) {
|
||||
System.out.println("claim " + claim);
|
||||
System.out.println("claimmap " + this.claims);
|
||||
|
||||
claim.remove();
|
||||
int[] pos = getChunkPos(claim);
|
||||
System.out.println("" + Arrays.toString(pos));
|
||||
for (int x = pos[0]; x <= pos[1]; x++)
|
||||
for (int z = pos[2]; z <= pos[3]; z++) {
|
||||
ChunkPos chunkPos = new ChunkPos(x, z);
|
||||
this.claims.compute(chunkPos.toLong(), (key, val) -> {
|
||||
if (val == null)
|
||||
return null;
|
||||
val.remove(claim);
|
||||
return val.isEmpty() ? null : val;
|
||||
});
|
||||
}
|
||||
System.out.println(this.claims);
|
||||
this.playerClaimMap.getOrDefault(claim.getOwner(), Sets.newHashSet()).remove(claim);
|
||||
return this.claimUUIDMap.remove(claim.getClaimID()) != null;
|
||||
}
|
||||
|
||||
public boolean resizeClaim(Claim claim, BlockPos pos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Claim getClaimAt(BlockPos pos) {
|
||||
long chunk = new ChunkPos(pos).toLong();
|
||||
if (this.claims.containsKey(chunk))
|
||||
for (Claim claim : this.claims.get(chunk)) {
|
||||
if (claim.insideClaim(pos))
|
||||
return claim;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addClaim(Claim claim) {
|
||||
System.out.println("adding claim " + claim);
|
||||
int[] pos = getChunkPos(claim);
|
||||
System.out.println("" + Arrays.toString(pos));
|
||||
for (int x = pos[0]; x <= pos[1]; x++)
|
||||
for (int z = pos[2]; z <= pos[3]; z++) {
|
||||
ChunkPos chunkPos = new ChunkPos(x, z);
|
||||
this.claims.merge(chunkPos.toLong(), Lists.newArrayList(claim), (key, val) -> {
|
||||
val.add(claim);
|
||||
return val;
|
||||
});
|
||||
}
|
||||
System.out.println("claimmap " + this.claims);
|
||||
this.claimUUIDMap.put(claim.getClaimID(), claim);
|
||||
this.playerClaimMap.merge(claim.getOwner(), Sets.newHashSet(claim), (key, val) -> {
|
||||
val.add(claim);
|
||||
return val;
|
||||
});
|
||||
}
|
||||
|
||||
public Collection<Claim> allClaimsFromPlayer(UUID player) {
|
||||
return this.playerClaimMap.containsKey(player) ? ImmutableSet.copyOf(this.playerClaimMap.get(player)) : ImmutableSet.of();
|
||||
}
|
||||
|
||||
public static int[] getChunkPos(Claim claim) {
|
||||
int[] dim = claim.getDimensions();
|
||||
int[] pos = new int[4];
|
||||
pos[0] = dim[0] >> 4;
|
||||
pos[1] = dim[1] >> 4;
|
||||
pos[2] = dim[2] >> 4;
|
||||
pos[3] = dim[3] >> 4;
|
||||
return pos;
|
||||
}
|
||||
|
||||
public void fromTag(CompoundTag compoundTag) {
|
||||
ListTag list = compoundTag.getList("Claims", 10);
|
||||
list.forEach(tag -> {
|
||||
Claim claim = Claim.fromTag((CompoundTag) tag);
|
||||
this.addClaim(claim);
|
||||
});
|
||||
}
|
||||
|
||||
public CompoundTag toTag(CompoundTag compoundTag) {
|
||||
ListTag list = new ListTag();
|
||||
this.claims.forEach((l, cList) ->
|
||||
cList.forEach(claim -> list.add(claim.save(new CompoundTag()))));
|
||||
compoundTag.put("Claims", list);
|
||||
return compoundTag;
|
||||
}
|
||||
|
||||
public void read(MinecraftServer server, RegistryKey<World> reg) {
|
||||
File dir = new File(DimensionType.getSaveDirectory(reg, server.getSavePath(WorldSavePath.ROOT).toFile()), "/data/claims/");
|
||||
if (dir.exists()) {
|
||||
try {
|
||||
for (File file : dir.listFiles()) {
|
||||
if (!file.getName().endsWith(".json"))
|
||||
continue;
|
||||
UUID uuid = UUID.fromString(file.getName().replace(".json", ""));
|
||||
FileReader reader = new FileReader(file);
|
||||
JsonArray arr = GSON.fromJson(reader, JsonArray.class);
|
||||
if (arr == null)
|
||||
continue;
|
||||
arr.forEach(el -> {
|
||||
if (el.isJsonObject()) {
|
||||
this.addClaim(Claim.fromJson((JsonObject) el, uuid));
|
||||
}
|
||||
});
|
||||
reader.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void save(MinecraftServer server, RegistryKey<World> reg) {
|
||||
File dir = new File(DimensionType.getSaveDirectory(reg, server.getSavePath(WorldSavePath.ROOT).toFile()), "/data/claims/");
|
||||
if (!dir.exists())
|
||||
dir.mkdir();
|
||||
try {
|
||||
for (Map.Entry<UUID, Set<Claim>> e : this.playerClaimMap.entrySet()) {
|
||||
|
||||
File file = new File(dir, e.getKey().toString() + ".json");
|
||||
if (!file.exists()) {
|
||||
if (e.getValue().isEmpty())
|
||||
continue;
|
||||
file.createNewFile();
|
||||
}
|
||||
FileWriter writer = new FileWriter(file);
|
||||
JsonArray arr = new JsonArray();
|
||||
e.getValue().forEach(claim -> arr.add(claim.toJson(new JsonObject())));
|
||||
GSON.toJson(arr, writer);
|
||||
writer.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void readGriefPreventionData(MinecraftServer server) {
|
||||
Yaml yml = new Yaml();
|
||||
File griefPrevention = server.getSavePath(WorldSavePath.ROOT).resolve("GriefPreventionData/ClaimData").toFile();
|
||||
if (!griefPrevention.exists())
|
||||
return;
|
||||
Map<File, List<File>> subClaimMap = Maps.newHashMap();
|
||||
Map<Integer, File> intFileMap = Maps.newHashMap();
|
||||
|
||||
try {
|
||||
//Get all parent claims
|
||||
for (File f : griefPrevention.listFiles()) {
|
||||
if (f.getName().endsWith(".yml")) {
|
||||
FileReader reader = new FileReader(f);
|
||||
Map<String, Object> values = yml.load(reader);
|
||||
if (values.get("Parent Claim ID").equals(Integer.valueOf(-1))) {
|
||||
intFileMap.put(Integer.valueOf(values.get("Parent Claim ID").toString()), f);
|
||||
}
|
||||
}
|
||||
}
|
||||
//Map child to parent claims
|
||||
for (File f : griefPrevention.listFiles()) {
|
||||
if (f.getName().endsWith(".yml")) {
|
||||
FileReader reader = new FileReader(f);
|
||||
Map<String, Object> values = yml.load(reader);
|
||||
if (!values.get("Parent Claim ID").equals(Integer.valueOf(-1))) {
|
||||
subClaimMap.merge(intFileMap.get(Integer.valueOf(values.get("Parent Claim ID").toString()))
|
||||
, Lists.newArrayList(f), (key, val) -> {
|
||||
val.add(f);
|
||||
return val;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (File parent : intFileMap.values()) {
|
||||
Pair<String, Claim> parentClaim = parseFromYaml(parent, yml);
|
||||
List<File> childs = subClaimMap.get(parent);
|
||||
if (childs != null && !childs.isEmpty()) {
|
||||
for (File childF : childs)
|
||||
parentClaim.second.addSubClaims(parseFromYaml(childF, yml).second);
|
||||
}
|
||||
ClaimStorage.get(server.getWorld(worldRegFromString(parentClaim.first))).addClaim(parentClaim.second);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static Pair<String, Claim> parseFromYaml(File file, Yaml yml) throws IOException {
|
||||
FileReader reader = new FileReader(file);
|
||||
Map<String, Object> values = yml.load(reader);
|
||||
reader.close();
|
||||
UUID owner = UUID.fromString(values.get("Owner").toString());
|
||||
String[] lesserCorner = values.get("Lesser Boundary Corner").toString().split(";");
|
||||
String[] greaterCorner = values.get("Greater Boundary Corner").toString().split(";");
|
||||
Claim claim = new Claim(Integer.parseInt(lesserCorner[1]), Integer.parseInt(greaterCorner[1]),
|
||||
Integer.parseInt(lesserCorner[3]), Integer.parseInt(greaterCorner[3]),
|
||||
Integer.parseInt(lesserCorner[2]), owner);
|
||||
|
||||
|
||||
return Pair.of(lesserCorner[0], claim);
|
||||
}
|
||||
|
||||
public static RegistryKey<World> worldRegFromString(String spigot) {
|
||||
if (spigot.equals("world_the_end"))
|
||||
return World.END;
|
||||
if (spigot.equals("world_nether"))
|
||||
return World.NETHER;
|
||||
return World.OVERWORLD;
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.flemmli97.flan.claim;
|
||||
|
||||
public enum EnumClaimRank {
|
||||
|
||||
COOWNER,
|
||||
BUILDER,
|
||||
MANAGER
|
||||
}
|
53
src/main/java/com/flemmli97/flan/claim/EnumPermission.java
Normal file
53
src/main/java/com/flemmli97/flan/claim/EnumPermission.java
Normal file
@ -0,0 +1,53 @@
|
||||
package com.flemmli97.flan.claim;
|
||||
|
||||
import com.flemmli97.flan.config.ConfigHandler;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
|
||||
public enum EnumPermission {
|
||||
|
||||
EDITPERMS(Items.COMMAND_BLOCK), //---
|
||||
EDITCLAIM(ConfigHandler.config.claimingItem), //---
|
||||
BREAK(Items.DIAMOND_PICKAXE),
|
||||
PLACE(Items.GRASS_BLOCK),
|
||||
OPENCONTAINER(Items.CHEST), //---
|
||||
ANVIL(Items.ANVIL),
|
||||
BED(Items.RED_BED),
|
||||
BEACON(Items.BEACON),
|
||||
DOOR(Items.OAK_DOOR),
|
||||
FENCEGATE(Items.OAK_FENCE_GATE),
|
||||
TRAPDOOR(Items.OAK_TRAPDOOR),
|
||||
BUTTONLEVER(Items.LEVER),
|
||||
PRESSUREPLATE(Items.STONE_PRESSURE_PLATE),
|
||||
NOTEBLOCK(Items.NOTE_BLOCK),
|
||||
REDSTONE(Items.REDSTONE),
|
||||
JUKEBOX(Items.JUKEBOX),
|
||||
ITEMFRAMEROTATE(Items.ITEM_FRAME),
|
||||
TARGETBLOCK(Items.TARGET),
|
||||
PROJECTILES(Items.ARROW),
|
||||
TRAMPLE(Items.FARMLAND),
|
||||
PORTAL(Items.OBSIDIAN),
|
||||
BOAT(Items.OAK_BOAT),
|
||||
MINECART(Items.MINECART),
|
||||
BUCKET(Items.BUCKET),
|
||||
ENDERPEARL(Items.ENDER_PEARL),
|
||||
ANIMALINTERACT(Items.CHICKEN_SPAWN_EGG),
|
||||
HURTANIMAL(Items.BEEF),
|
||||
HURTPLAYER(Items.DIAMOND_SWORD),
|
||||
XP(Items.EXPERIENCE_BOTTLE),
|
||||
TRADING(Items.EMERALD),
|
||||
EXPLOSIONS(Items.TNT),
|
||||
WITHER(Items.WITHER_SKELETON_SKULL),
|
||||
ARMORSTAND(Items.ARMOR_STAND),
|
||||
BREAKNONLIVING(Items.COMMAND_BLOCK_MINECART);
|
||||
|
||||
private Item item;
|
||||
|
||||
EnumPermission(Item item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
public Item getItem() {
|
||||
return this.item;
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package com.flemmli97.flan.claim;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import net.minecraft.block.AbstractButtonBlock;
|
||||
import net.minecraft.block.AbstractPressurePlateBlock;
|
||||
import net.minecraft.block.AbstractRedstoneGateBlock;
|
||||
import net.minecraft.block.AnvilBlock;
|
||||
import net.minecraft.block.BeaconBlock;
|
||||
import net.minecraft.block.BedBlock;
|
||||
import net.minecraft.block.BellBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.CampfireBlock;
|
||||
import net.minecraft.block.ChorusFlowerBlock;
|
||||
import net.minecraft.block.DaylightDetectorBlock;
|
||||
import net.minecraft.block.DoorBlock;
|
||||
import net.minecraft.block.FarmlandBlock;
|
||||
import net.minecraft.block.FenceGateBlock;
|
||||
import net.minecraft.block.JukeboxBlock;
|
||||
import net.minecraft.block.LeverBlock;
|
||||
import net.minecraft.block.NetherPortalBlock;
|
||||
import net.minecraft.block.NoteBlock;
|
||||
import net.minecraft.block.RedstoneWireBlock;
|
||||
import net.minecraft.block.TargetBlock;
|
||||
import net.minecraft.block.TntBlock;
|
||||
import net.minecraft.block.TrapdoorBlock;
|
||||
import net.minecraft.block.TurtleEggBlock;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ObjectToPermissionMap {
|
||||
|
||||
private static Map<Block, EnumPermission> blockToPermission = Maps.newHashMap();
|
||||
|
||||
public static void reload(MinecraftServer server) {
|
||||
blockToPermission.clear();
|
||||
for (Block block : Registry.BLOCK) {
|
||||
if (block instanceof AnvilBlock)
|
||||
blockToPermission.put(block, EnumPermission.ANVIL);
|
||||
if (block instanceof BedBlock)
|
||||
blockToPermission.put(block, EnumPermission.BED);
|
||||
if (block instanceof BeaconBlock)
|
||||
blockToPermission.put(block, EnumPermission.BEACON);
|
||||
if (block instanceof DoorBlock)
|
||||
blockToPermission.put(block, EnumPermission.DOOR);
|
||||
if (block instanceof FenceGateBlock)
|
||||
blockToPermission.put(block, EnumPermission.FENCEGATE);
|
||||
if (block instanceof TrapdoorBlock)
|
||||
blockToPermission.put(block, EnumPermission.TRAPDOOR);
|
||||
if (block instanceof LeverBlock || block instanceof AbstractButtonBlock)
|
||||
blockToPermission.put(block, EnumPermission.BUTTONLEVER);
|
||||
if (block instanceof NoteBlock)
|
||||
blockToPermission.put(block, EnumPermission.NOTEBLOCK);
|
||||
if (block instanceof AbstractRedstoneGateBlock || block instanceof RedstoneWireBlock || block instanceof DaylightDetectorBlock)
|
||||
blockToPermission.put(block, EnumPermission.REDSTONE);
|
||||
if (block instanceof JukeboxBlock)
|
||||
blockToPermission.put(block, EnumPermission.JUKEBOX);
|
||||
if (block instanceof AbstractPressurePlateBlock)
|
||||
blockToPermission.put(block, EnumPermission.PRESSUREPLATE);
|
||||
if (block instanceof NetherPortalBlock)
|
||||
blockToPermission.put(block, EnumPermission.PORTAL);
|
||||
if (block instanceof TurtleEggBlock || block instanceof FarmlandBlock)
|
||||
blockToPermission.put(block, EnumPermission.TRAMPLE);
|
||||
if (block instanceof TargetBlock)
|
||||
blockToPermission.put(block, EnumPermission.TARGETBLOCK);
|
||||
if (block instanceof BellBlock || block instanceof CampfireBlock
|
||||
|| block instanceof TntBlock || block instanceof ChorusFlowerBlock)
|
||||
blockToPermission.put(block, EnumPermission.PROJECTILES);
|
||||
}
|
||||
}
|
||||
|
||||
public static EnumPermission getFromBlock(Block block) {
|
||||
return blockToPermission.get(block);
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.flemmli97.flan.claim;
|
||||
|
||||
import net.minecraft.particle.DustParticleEffect;
|
||||
|
||||
public class ParticleIndicators {
|
||||
|
||||
public static final DustParticleEffect CLAIMCORNER = new DustParticleEffect(0.0F, 1.0F, 0.0F, 1.0F);
|
||||
public static final DustParticleEffect CLAIMMIDDLE = new DustParticleEffect(0.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
public static final DustParticleEffect SUBCLAIMCORNER = DustParticleEffect.RED;
|
||||
public static final DustParticleEffect SUBCLAIMMIDDLE = DustParticleEffect.RED;
|
||||
|
||||
public static final DustParticleEffect SETCORNER = new DustParticleEffect(0.0F, 0.9F, 1.0F, 1.0F);
|
||||
|
||||
public static final DustParticleEffect OVERLAPCLAIM = DustParticleEffect.RED;
|
||||
}
|
224
src/main/java/com/flemmli97/flan/commands/CommandClaim.java
Normal file
224
src/main/java/com/flemmli97/flan/commands/CommandClaim.java
Normal file
@ -0,0 +1,224 @@
|
||||
package com.flemmli97.flan.commands;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.claim.ClaimStorage;
|
||||
import com.flemmli97.flan.claim.EnumPermission;
|
||||
import com.flemmli97.flan.config.ConfigHandler;
|
||||
import com.flemmli97.flan.gui.ClaimMenuScreenHandler;
|
||||
import com.flemmli97.flan.player.EnumEditMode;
|
||||
import com.flemmli97.flan.player.PlayerClaimData;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import net.minecraft.command.argument.GameProfileArgumentType;
|
||||
import net.minecraft.server.command.CommandManager;
|
||||
import net.minecraft.server.command.CommandSource;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CommandClaim {
|
||||
|
||||
public static void register(CommandDispatcher<ServerCommandSource> dispatcher, boolean dedicated) {
|
||||
|
||||
LiteralArgumentBuilder<ServerCommandSource> main = CommandManager.literal("claim");
|
||||
dispatcher.register(addToMainCommand(CommandManager.literal("claim"),
|
||||
CommandManager.literal("menu").executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
ClaimStorage storage = ClaimStorage.get(context.getSource().getWorld());
|
||||
Claim claim = storage.getClaimAt(src.getPlayer().getBlockPos());
|
||||
if (claim == null || !claim.canInteract(src.getPlayer(), EnumPermission.EDITCLAIM, src.getPlayer().getBlockPos()))
|
||||
return 0;
|
||||
ClaimMenuScreenHandler.openClaimMenu(src.getPlayer(), claim);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}),
|
||||
CommandManager.literal("delete").executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
ClaimStorage storage = ClaimStorage.get(src.getWorld());
|
||||
Claim claim = storage.getClaimAt(src.getPlayer().getBlockPos());
|
||||
if (claim == null || !claim.canInteract(src.getPlayer(), EnumPermission.EDITCLAIM, src.getPlayer().getBlockPos())) {
|
||||
src.getPlayer().sendMessage(Text.of(ConfigHandler.lang.deleteClaimError), false);
|
||||
return 0;
|
||||
}
|
||||
storage.deleteClaim(claim);
|
||||
src.getPlayer().sendMessage(Text.of(ConfigHandler.lang.deleteClaim), false);
|
||||
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}),
|
||||
CommandManager.literal("deleteAll").executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
PlayerClaimData data = PlayerClaimData.get(src.getPlayer());
|
||||
if (data.confirmedDeleteAll()) {
|
||||
for (ServerWorld world : src.getWorld().getServer().getWorlds()) {
|
||||
ClaimStorage storage = ClaimStorage.get(world);
|
||||
storage.allClaimsFromPlayer(src.getPlayer().getUuid()).forEach(claim -> storage.deleteClaim(claim));
|
||||
}
|
||||
src.getPlayer().sendMessage(Text.of(ConfigHandler.lang.deleteAllClaim), false);
|
||||
data.setConfirmDeleteAll(false);
|
||||
} else {
|
||||
data.setConfirmDeleteAll(true);
|
||||
src.getPlayer().sendMessage(Text.of(ConfigHandler.lang.deleteAllClaimConfirm), false);
|
||||
}
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}),
|
||||
CommandManager.literal("list").executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
Map<World, Collection<Claim>> claims = Maps.newHashMap();
|
||||
for (ServerWorld world : src.getWorld().getServer().getWorlds()) {
|
||||
ClaimStorage storage = ClaimStorage.get(world);
|
||||
claims.put(world, storage.allClaimsFromPlayer(src.getPlayer().getUuid()));
|
||||
}
|
||||
src.getPlayer().sendMessage(Text.of(ConfigHandler.lang.listClaims), false);
|
||||
for (Map.Entry<World, Collection<Claim>> entry : claims.entrySet())
|
||||
for (Claim claim : entry.getValue())
|
||||
src.getPlayer().sendMessage(Text.of(entry.getKey().getRegistryKey().getValue().toString() + " - " + claim.formattedClaim()), false);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}),
|
||||
CommandManager.literal("switchMode").executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
PlayerClaimData data = PlayerClaimData.get(src.getPlayer());
|
||||
data.setEditMode(data.getEditMode() == EnumEditMode.DEFAULT ? EnumEditMode.SUBCLAIM : EnumEditMode.DEFAULT);
|
||||
src.getPlayer().sendMessage(Text.of(String.format(ConfigHandler.lang.editMode, data.getEditMode())), false);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}),
|
||||
CommandManager.literal("adminMode").requires(src -> src.hasPermissionLevel(2)).executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
PlayerClaimData data = PlayerClaimData.get(src.getPlayer());
|
||||
data.setAdminIgnoreClaim(!data.isAdminIgnoreClaim());
|
||||
src.getPlayer().sendMessage(Text.of(String.format(ConfigHandler.lang.adminMode, data.isAdminIgnoreClaim())), false);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}),
|
||||
CommandManager.literal("adminRemove").requires(src -> src.hasPermissionLevel(2)).executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
ClaimStorage storage = ClaimStorage.get(src.getWorld());
|
||||
Claim claim = storage.getClaimAt(new BlockPos(src.getPosition()));
|
||||
if (claim == null) {
|
||||
src.sendFeedback(Text.of(ConfigHandler.lang.deleteClaimError), false);
|
||||
return 0;
|
||||
}
|
||||
storage.deleteClaim(claim);
|
||||
src.sendFeedback(Text.of(ConfigHandler.lang.deleteClaim), true);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}).then(CommandManager.literal("all").then(CommandManager.argument("player", GameProfileArgumentType.gameProfile())).executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
Iterator<GameProfile> it = GameProfileArgumentType.getProfileArgument(context, "player").iterator();
|
||||
List<String> players = Lists.newArrayList();
|
||||
while (it.hasNext()) {
|
||||
GameProfile prof = it.next();
|
||||
for (ServerWorld world : src.getWorld().getServer().getWorlds()) {
|
||||
ClaimStorage storage = ClaimStorage.get(world);
|
||||
storage.allClaimsFromPlayer(prof.getId()).forEach(claim -> storage.deleteClaim(claim));
|
||||
}
|
||||
players.add(prof.getName());
|
||||
}
|
||||
src.sendFeedback(Text.of(String.format(ConfigHandler.lang.adminDeleteAll, players.toString())), true);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})),
|
||||
CommandManager.literal("giveClaimBlocks").requires(src -> src.hasPermissionLevel(2)).then(CommandManager.argument("player", GameProfileArgumentType.gameProfile())
|
||||
.then(CommandManager.argument("amount", IntegerArgumentType.integer()).executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
Iterator<GameProfile> it = GameProfileArgumentType.getProfileArgument(context, "player").iterator();
|
||||
List<String> players = Lists.newArrayList();
|
||||
int amount = IntegerArgumentType.getInteger(context, "amount");
|
||||
while (it.hasNext()) {
|
||||
GameProfile prof = it.next();
|
||||
ServerPlayerEntity player = src.getMinecraftServer().getPlayerManager().getPlayer(prof.getId());
|
||||
if (player != null) {
|
||||
PlayerClaimData data = PlayerClaimData.get(player);
|
||||
data.setAdditionalClaims(data.getAdditionalClaims() + amount);
|
||||
} else
|
||||
PlayerClaimData.editForOfflinePlayer(src.getMinecraftServer(), prof.getId(), amount);
|
||||
players.add(prof.getName());
|
||||
}
|
||||
src.sendFeedback(Text.of(String.format(ConfigHandler.lang.giveClaimBlocks, players.toString(), amount)), true);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}))),
|
||||
addToMainCommand(CommandManager.literal("group"),
|
||||
CommandManager.literal("add").then(CommandManager.argument("name", StringArgumentType.word()).executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
String group = StringArgumentType.getString(context, "name");
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
ClaimStorage storage = ClaimStorage.get(src.getWorld());
|
||||
Claim claim = storage.getClaimAt(src.getPlayer().getBlockPos());
|
||||
if (claim == null || !claim.canInteract(src.getPlayer(), EnumPermission.EDITCLAIM, src.getPlayer().getBlockPos())) {
|
||||
src.getPlayer().sendMessage(Text.of(ConfigHandler.lang.deleteClaimError), false);
|
||||
return 0;
|
||||
}
|
||||
claim.editPerms(src.getPlayer(), group, EnumPermission.EDITCLAIM, -1);
|
||||
src.getPlayer().sendMessage(Text.of(ConfigHandler.lang.deleteClaim), false);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})),
|
||||
CommandManager.literal("remove").then(CommandManager.argument("name", StringArgumentType.word()).suggests((context, build) -> {
|
||||
List<String> list = Lists.newArrayList();
|
||||
ServerCommandSource src = context.getSource();
|
||||
String group = StringArgumentType.getString(context, "name");
|
||||
if (src.getPlayer() != null) {
|
||||
ClaimStorage storage = ClaimStorage.get(src.getWorld());
|
||||
Claim claim = storage.getClaimAt(src.getPlayer().getBlockPos());
|
||||
if (claim != null && claim.canInteract(src.getPlayer(), EnumPermission.EDITCLAIM, src.getPlayer().getBlockPos())) {
|
||||
list = claim.groups();
|
||||
}
|
||||
}
|
||||
return CommandSource.suggestMatching(list, build);
|
||||
}).executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
String group = StringArgumentType.getString(context, "name");
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
ClaimStorage storage = ClaimStorage.get(src.getWorld());
|
||||
Claim claim = storage.getClaimAt(src.getPlayer().getBlockPos());
|
||||
if (claim == null || !claim.canInteract(src.getPlayer(), EnumPermission.EDITCLAIM, src.getPlayer().getBlockPos())) {
|
||||
src.getPlayer().sendMessage(Text.of(ConfigHandler.lang.deleteClaimError), false);
|
||||
return 0;
|
||||
}
|
||||
claim.removePermGroup(src.getPlayer(), group);
|
||||
src.getPlayer().sendMessage(Text.of(ConfigHandler.lang.deleteClaim), false);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})),
|
||||
CommandManager.literal("player").then(CommandManager.argument("player", GameProfileArgumentType.gameProfile())).executes(context -> {
|
||||
ServerCommandSource src = context.getSource();
|
||||
GameProfileArgumentType.getProfileArgument(context, "player");
|
||||
if (src.getPlayer() == null)
|
||||
return 0;
|
||||
|
||||
//print
|
||||
return 0;
|
||||
})
|
||||
)));
|
||||
}
|
||||
|
||||
private static LiteralArgumentBuilder<ServerCommandSource> addToMainCommand(LiteralArgumentBuilder<ServerCommandSource> main, ArgumentBuilder... other) {
|
||||
if (other != null)
|
||||
for (ArgumentBuilder o : other)
|
||||
main.then(o);
|
||||
return main;
|
||||
}
|
||||
|
||||
}
|
38
src/main/java/com/flemmli97/flan/config/Config.java
Normal file
38
src/main/java/com/flemmli97/flan/config/Config.java
Normal file
@ -0,0 +1,38 @@
|
||||
package com.flemmli97.flan.config;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.WorldSavePath;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Config {
|
||||
|
||||
private File configDir;
|
||||
|
||||
public int startingBlocks = 500;
|
||||
public int maxClaimBlocks = 5000;
|
||||
public int ticksForNextBlock = 1200;
|
||||
|
||||
public String[] blacklistedWorlds;
|
||||
public boolean worldWhitelist;
|
||||
|
||||
public Item claimingItem = Items.GOLDEN_HOE;
|
||||
public Item inspectionItem = Items.STICK;
|
||||
|
||||
public int claimDisplayTime = 1000;
|
||||
|
||||
public Config(MinecraftServer server) {
|
||||
this.configDir = server.getSavePath(WorldSavePath.ROOT).resolve("config/claimConfigs").toFile();
|
||||
}
|
||||
|
||||
|
||||
public void load() {
|
||||
|
||||
}
|
||||
|
||||
public void save() {
|
||||
|
||||
}
|
||||
}
|
16
src/main/java/com/flemmli97/flan/config/ConfigHandler.java
Normal file
16
src/main/java/com/flemmli97/flan/config/ConfigHandler.java
Normal file
@ -0,0 +1,16 @@
|
||||
package com.flemmli97.flan.config;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
public class ConfigHandler {
|
||||
|
||||
public static Config config;
|
||||
public static LangConfig lang;
|
||||
|
||||
public static void serverLoad(MinecraftServer server) {
|
||||
config = new Config(server);
|
||||
config.load();
|
||||
lang = new LangConfig(server);
|
||||
lang.load();
|
||||
}
|
||||
}
|
39
src/main/java/com/flemmli97/flan/config/LangConfig.java
Normal file
39
src/main/java/com/flemmli97/flan/config/LangConfig.java
Normal file
@ -0,0 +1,39 @@
|
||||
package com.flemmli97.flan.config;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.WorldSavePath;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class LangConfig {
|
||||
|
||||
private File configDir;
|
||||
|
||||
public String inspectBlockOwner = "This is %1$s's claim";
|
||||
public String inspectNoClaim = "Nobody owns this block";
|
||||
public String cantClaimHere = "Sorry you cant claim here";
|
||||
public String listClaims = "Listing all claims:";
|
||||
|
||||
public String deleteClaim = "Claim deleted";
|
||||
public String deleteAllClaimConfirm = "Are you sure you want to delete all claims? Type it again to confirm";
|
||||
public String deleteAllClaim = "All claims deleted";
|
||||
public String deleteClaimError = "No claim for you to delete here";
|
||||
public String adminDeleteAll = "Deleted all claims for following players: %s";
|
||||
|
||||
public String giveClaimBlocks = "Gave following players %2$d claimblocks: %1$s";
|
||||
public String adminMode = "Adminmode set to: ";
|
||||
public String editMode = "Editing mode set to %s";
|
||||
|
||||
public String stringScreenReturn = "Click on paper to go back";
|
||||
|
||||
public String playerGroupAddFail = "Couldn't add that player to the group either cause the player " +
|
||||
"is already in a group or no player matching the name was found";
|
||||
|
||||
public LangConfig(MinecraftServer server) {
|
||||
this.configDir = server.getSavePath(WorldSavePath.ROOT).resolve("config/claimConfigs").toFile();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
|
||||
}
|
||||
}
|
140
src/main/java/com/flemmli97/flan/event/BlockInteractEvents.java
Normal file
140
src/main/java/com/flemmli97/flan/event/BlockInteractEvents.java
Normal file
@ -0,0 +1,140 @@
|
||||
package com.flemmli97.flan.event;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.claim.ClaimStorage;
|
||||
import com.flemmli97.flan.claim.EnumPermission;
|
||||
import com.flemmli97.flan.claim.ObjectToPermissionMap;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.LockableContainerBlockEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ToolItem;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockInteractEvents {
|
||||
|
||||
public static ActionResult breakBlocks(PlayerEntity player, World world, Hand hand, BlockPos pos, Direction dir) {
|
||||
if (world.isClient)
|
||||
return ActionResult.PASS;
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) world);
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
if (claim != null) {
|
||||
if (!claim.canInteract(player, EnumPermission.BREAK, pos))
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
//Right click block
|
||||
public static ActionResult useBlocks(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) {
|
||||
if (world.isClient)
|
||||
return ActionResult.PASS;
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) world);
|
||||
Claim claim = storage.getClaimAt(hitResult.getBlockPos());
|
||||
if (claim != null) {
|
||||
boolean emptyHand = !player.getMainHandStack().isEmpty() || !player.getOffHandStack().isEmpty();
|
||||
boolean cancelBlockInteract = player.shouldCancelInteraction() && emptyHand;
|
||||
if (!cancelBlockInteract) {
|
||||
BlockState state = world.getBlockState(hitResult.getBlockPos());
|
||||
BlockEntity blockEntity = world.getBlockEntity(hitResult.getBlockPos());
|
||||
if (blockEntity != null) {
|
||||
if (blockEntity instanceof LockableContainerBlockEntity)
|
||||
return claim.canInteract(player, EnumPermission.OPENCONTAINER, hitResult.getBlockPos()) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
}
|
||||
EnumPermission perm = ObjectToPermissionMap.getFromBlock(state.getBlock());
|
||||
if (perm != null)
|
||||
return claim.canInteract(player, perm, hitResult.getBlockPos()) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
}
|
||||
ItemStack stack = player.getStackInHand(hand);
|
||||
if (stack.getItem() instanceof BlockItem || stack.getItem() instanceof ToolItem)
|
||||
return claim.canInteract(player, EnumPermission.PLACE, hitResult.getBlockPos()) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
public static boolean blockCollisionEntity(BlockState state, World world, BlockPos pos, Entity entity) {
|
||||
if (entity.world.isClient)
|
||||
return false;
|
||||
if (entity instanceof PlayerEntity) {
|
||||
EnumPermission perm = ObjectToPermissionMap.getFromBlock(state.getBlock());
|
||||
if (perm == null || (perm != EnumPermission.PRESSUREPLATE && perm != EnumPermission.PORTAL))
|
||||
return false;
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) world);
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
if (claim != null)
|
||||
return !claim.canInteract((PlayerEntity) entity, perm, pos);
|
||||
} else if (entity instanceof ProjectileEntity) {
|
||||
EnumPermission perm = ObjectToPermissionMap.getFromBlock(state.getBlock());
|
||||
if (perm == null || (perm != EnumPermission.PRESSUREPLATE && perm != EnumPermission.BUTTONLEVER))
|
||||
return false;
|
||||
Entity owner = ((ProjectileEntity) entity).getOwner();
|
||||
if (owner instanceof PlayerEntity) {
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) world);
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
if (claim != null)
|
||||
return !claim.canInteract((PlayerEntity) owner, perm, pos);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean entityFall(Entity entity, double heightDifference, boolean onGround, BlockState landedState, BlockPos landedPosition) {
|
||||
if (entity.world.isClient)
|
||||
return false;
|
||||
if (entity instanceof ServerPlayerEntity) {
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) entity.world);
|
||||
Claim claim = storage.getClaimAt(landedPosition);
|
||||
EnumPermission perm = ObjectToPermissionMap.getFromBlock(landedState.getBlock());
|
||||
if (perm != null && perm == EnumPermission.TRAMPLE)
|
||||
return !claim.canInteract((PlayerEntity) entity, perm, landedPosition);
|
||||
} else if (entity instanceof ProjectileEntity) {
|
||||
Entity owner = ((ProjectileEntity) entity).getOwner();
|
||||
if (owner instanceof PlayerEntity) {
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) entity.world);
|
||||
Claim claim = storage.getClaimAt(landedPosition);
|
||||
EnumPermission perm = ObjectToPermissionMap.getFromBlock(landedState.getBlock());
|
||||
if (perm != null && perm == EnumPermission.TRAMPLE)
|
||||
return !claim.canInteract((PlayerEntity) owner, perm, landedPosition);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean turtleEggHandle(World world, BlockPos pos, Entity entity) {
|
||||
if (world.isClient)
|
||||
return false;
|
||||
ServerWorld serverWorld = (ServerWorld) world;
|
||||
if (entity instanceof ServerPlayerEntity) {
|
||||
ClaimStorage storage = ClaimStorage.get(serverWorld);
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
return !claim.canInteract((PlayerEntity) entity, EnumPermission.TRAMPLE, pos);
|
||||
} else if (entity instanceof ProjectileEntity) {
|
||||
Entity owner = ((ProjectileEntity) entity).getOwner();
|
||||
if (owner instanceof PlayerEntity) {
|
||||
ClaimStorage storage = ClaimStorage.get(serverWorld);
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
return !claim.canInteract((PlayerEntity) owner, EnumPermission.TRAMPLE, pos);
|
||||
}
|
||||
} else if (entity instanceof ItemEntity) {
|
||||
Entity owner = serverWorld.getEntity(((ItemEntity) entity).getThrower());
|
||||
if (owner instanceof PlayerEntity) {
|
||||
ClaimStorage storage = ClaimStorage.get(serverWorld);
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
return !claim.canInteract((PlayerEntity) owner, EnumPermission.TRAMPLE, pos);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
162
src/main/java/com/flemmli97/flan/event/EntityInteractEvents.java
Normal file
162
src/main/java/com/flemmli97/flan/event/EntityInteractEvents.java
Normal file
@ -0,0 +1,162 @@
|
||||
package com.flemmli97.flan.event;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.claim.ClaimStorage;
|
||||
import com.flemmli97.flan.claim.EnumPermission;
|
||||
import com.flemmli97.flan.claim.ObjectToPermissionMap;
|
||||
import com.flemmli97.flan.mixin.IPersistentProjectileVars;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.boss.WitherEntity;
|
||||
import net.minecraft.entity.decoration.ArmorStandEntity;
|
||||
import net.minecraft.entity.decoration.ItemFrameEntity;
|
||||
import net.minecraft.entity.mob.Monster;
|
||||
import net.minecraft.entity.passive.VillagerEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.projectile.PersistentProjectileEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.entity.projectile.thrown.EnderPearlEntity;
|
||||
import net.minecraft.entity.vehicle.BoatEntity;
|
||||
import net.minecraft.entity.vehicle.ChestMinecartEntity;
|
||||
import net.minecraft.entity.vehicle.HopperMinecartEntity;
|
||||
import net.minecraft.entity.vehicle.MinecartEntity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.EntityHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityInteractEvents {
|
||||
|
||||
public static ActionResult attackEntity(PlayerEntity player, World world, Hand hand, Entity entity, EntityHitResult hitResult) {
|
||||
return attackSimple(player, entity);
|
||||
}
|
||||
|
||||
public static ActionResult useAtEntity(PlayerEntity player, World world, Hand hand, Entity entity, /* Nullable */ EntityHitResult hitResult) {
|
||||
if (player.world.isClient)
|
||||
return ActionResult.PASS;
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) world);
|
||||
BlockPos pos = entity.getBlockPos();
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
if (claim != null) {
|
||||
if (entity instanceof ArmorStandEntity) {
|
||||
if (!claim.canInteract(player, EnumPermission.ARMORSTAND, pos))
|
||||
return ActionResult.FAIL;
|
||||
}
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
public static ActionResult useEntity(PlayerEntity player, World world, Hand hand, Entity entity) {
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) world);
|
||||
BlockPos pos = entity.getBlockPos();
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
if (claim != null) {
|
||||
//works
|
||||
if (entity instanceof BoatEntity)
|
||||
return claim.canInteract(player, EnumPermission.BOAT, pos) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
if (entity instanceof MinecartEntity) {
|
||||
if (entity instanceof HopperMinecartEntity || entity instanceof ChestMinecartEntity)
|
||||
return claim.canInteract(player, EnumPermission.OPENCONTAINER, pos) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
return claim.canInteract(player, EnumPermission.MINECART, pos) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
}
|
||||
if (entity instanceof VillagerEntity)
|
||||
return claim.canInteract(player, EnumPermission.TRADING, pos) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
if (entity instanceof ItemFrameEntity)
|
||||
return claim.canInteract(player, EnumPermission.ITEMFRAMEROTATE, pos) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
|
||||
return claim.canInteract(player, EnumPermission.ANIMALINTERACT, pos) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
public static boolean projectileHit(ProjectileEntity proj, HitResult res) {
|
||||
if (proj.world.isClient)
|
||||
return false;
|
||||
Entity owner = proj.getOwner();
|
||||
if (owner instanceof PlayerEntity) {
|
||||
PlayerEntity player = (PlayerEntity) owner;
|
||||
if (res.getType() == HitResult.Type.BLOCK) {
|
||||
BlockHitResult blockRes = (BlockHitResult) res;
|
||||
BlockPos pos = blockRes.getBlockPos();
|
||||
BlockState state = proj.world.getBlockState(pos);
|
||||
EnumPermission perm = ObjectToPermissionMap.getFromBlock(state.getBlock());
|
||||
if (proj instanceof EnderPearlEntity)
|
||||
perm = EnumPermission.ENDERPEARL;
|
||||
if (perm == null || (perm != EnumPermission.ENDERPEARL && perm != EnumPermission.TARGETBLOCK && perm != EnumPermission.PROJECTILES))
|
||||
return false;
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) proj.world);
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
if (claim == null)
|
||||
return false;
|
||||
boolean flag = !claim.canInteract(player, perm, pos);
|
||||
if (flag && proj instanceof PersistentProjectileEntity) {
|
||||
PersistentProjectileEntity pers = (PersistentProjectileEntity) proj;
|
||||
((IPersistentProjectileVars) pers).setInBlockState(pers.world.getBlockState(pos));
|
||||
Vec3d vec3d = blockRes.getPos().subtract(pers.getX(), pers.getY(), pers.getZ());
|
||||
pers.setVelocity(vec3d);
|
||||
Vec3d vec3d2 = vec3d.normalize().multiply(0.05000000074505806D);
|
||||
pers.setPos(pers.getX() - vec3d2.x, pers.getY() - vec3d2.y, pers.getZ() - vec3d2.z);
|
||||
pers.playSound(((IPersistentProjectileVars) pers).getSoundEvent(), 1.0F, 1.2F / (pers.world.random.nextFloat() * 0.2F + 0.9F));
|
||||
((IPersistentProjectileVars) pers).setInGround(true);
|
||||
pers.shake = 7;
|
||||
pers.setCritical(false);
|
||||
pers.setPierceLevel((byte) 0);
|
||||
pers.setSound(SoundEvents.ENTITY_ARROW_HIT);
|
||||
pers.setShotFromCrossbow(false);
|
||||
((IPersistentProjectileVars) pers).resetPiercingStatus();
|
||||
}
|
||||
return flag;
|
||||
} else if (res.getType() == HitResult.Type.ENTITY)
|
||||
return attackSimple(player, ((EntityHitResult) res).getEntity()) != ActionResult.PASS;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ActionResult attackSimple(PlayerEntity player, Entity entity) {
|
||||
if (player.world.isClient)
|
||||
return ActionResult.PASS;
|
||||
if (entity instanceof Monster)
|
||||
return ActionResult.PASS;
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) player.world);
|
||||
BlockPos pos = entity.getBlockPos();
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
if (claim != null) {
|
||||
if (entity instanceof ArmorStandEntity || entity instanceof MinecartEntity || entity instanceof BoatEntity || entity instanceof ItemFrameEntity)
|
||||
return claim.canInteract(player, EnumPermission.BREAKNONLIVING, pos) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
if (entity instanceof PlayerEntity)
|
||||
return claim.canInteract(player, EnumPermission.HURTPLAYER, pos) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
return claim.canInteract(player, EnumPermission.HURTANIMAL, pos) ? ActionResult.PASS : ActionResult.FAIL;
|
||||
}
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
public static boolean xpAbsorb(PlayerEntity player) {
|
||||
if (player instanceof ServerPlayerEntity) {
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) player.world);
|
||||
BlockPos pos = player.getBlockPos();
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
if (claim != null)
|
||||
return !claim.canInteract(player, EnumPermission.XP, pos);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean witherCanDestroy(WitherEntity wither) {
|
||||
if (wither.world.isClient)
|
||||
return true;
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) wither.world);
|
||||
for (int x = -1; x <= 1; x++)
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
if (storage.getClaimAt(wither.getBlockPos().add(x, 0, z)) != null)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
109
src/main/java/com/flemmli97/flan/event/ItemInteractEvents.java
Normal file
109
src/main/java/com/flemmli97/flan/event/ItemInteractEvents.java
Normal file
@ -0,0 +1,109 @@
|
||||
package com.flemmli97.flan.event;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.claim.ClaimStorage;
|
||||
import com.flemmli97.flan.claim.EnumPermission;
|
||||
import com.flemmli97.flan.config.ConfigHandler;
|
||||
import com.flemmli97.flan.player.EnumEditMode;
|
||||
import com.flemmli97.flan.player.PlayerClaimData;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BucketItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.util.hit.BlockHitResult;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ItemInteractEvents {
|
||||
|
||||
public static TypedActionResult<ItemStack> useItem(PlayerEntity player, World world, Hand hand) {
|
||||
if (world.isClient)
|
||||
return TypedActionResult.pass(player.getStackInHand(hand));
|
||||
ItemStack stack = player.getStackInHand(hand);
|
||||
if (stack.getItem() == ConfigHandler.config.claimingItem) {
|
||||
HitResult ray = player.rayTrace(64, 0, false);
|
||||
if (ray != null && ray.getType() == HitResult.Type.BLOCK) {
|
||||
BlockHitResult blockRay = (BlockHitResult) ray;
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) world);
|
||||
Claim claim = storage.getClaimAt(blockRay.getBlockPos());
|
||||
PlayerClaimData data = PlayerClaimData.get(player);
|
||||
if (claim != null) {
|
||||
if (claim.canInteract(player, EnumPermission.EDITCLAIM, blockRay.getBlockPos())) {
|
||||
if (data.getEditMode() == EnumEditMode.SUBCLAIM) {
|
||||
Claim subClaim = claim.getSubClaim(blockRay.getBlockPos());
|
||||
if (subClaim != null) {
|
||||
if (subClaim.isCorner(blockRay.getBlockPos()))
|
||||
data.setEditClaim(subClaim);
|
||||
} else {
|
||||
if (data.editingCorner() != null) {
|
||||
if (data.currentEdit() == null) {
|
||||
boolean fl = claim.tryCreateSubClaim(data.editingCorner(), blockRay.getBlockPos());
|
||||
} else {
|
||||
//subClaim.resizeClaim(data.currentEdit(), data.editingCorner());
|
||||
data.setEditClaim(null);
|
||||
}
|
||||
data.setEditingCorner(null);
|
||||
} else
|
||||
data.setEditingCorner(blockRay.getBlockPos());
|
||||
}
|
||||
} else {
|
||||
if (claim.isCorner(blockRay.getBlockPos()))
|
||||
data.setEditClaim(claim);
|
||||
}
|
||||
} else {
|
||||
data.addDisplayClaim(claim);
|
||||
player.sendMessage(Text.of(ConfigHandler.lang.cantClaimHere), false);
|
||||
}
|
||||
} else {
|
||||
if (data.editingCorner() != null) {
|
||||
if (data.currentEdit() == null)
|
||||
storage.createClaim(data.editingCorner(), blockRay.getBlockPos(), player);
|
||||
else {
|
||||
storage.resizeClaim(data.currentEdit(), data.editingCorner());
|
||||
data.setEditClaim(null);
|
||||
}
|
||||
data.setEditingCorner(null);
|
||||
} else
|
||||
data.setEditingCorner(blockRay.getBlockPos());
|
||||
}
|
||||
}
|
||||
return TypedActionResult.success(stack);
|
||||
}
|
||||
if (stack.getItem() == ConfigHandler.config.inspectionItem) {
|
||||
HitResult ray = player.rayTrace(32, 0, false);
|
||||
if (ray != null && ray.getType() == HitResult.Type.BLOCK) {
|
||||
BlockHitResult blockRay = (BlockHitResult) ray;
|
||||
Claim claim = ClaimStorage.get((ServerWorld) world).getClaimAt(new BlockPos(ray.getPos()));
|
||||
if (claim != null) {
|
||||
String owner = "<UNKOWN>";
|
||||
GameProfile prof = world.getServer().getUserCache().getByUuid(claim.getOwner());
|
||||
if (prof != null && prof.getName() != null)
|
||||
owner = prof.getName();
|
||||
Text text = Text.of(String.format(ConfigHandler.lang.inspectBlockOwner,
|
||||
owner,
|
||||
blockRay.getBlockPos().getX(), blockRay.getBlockPos().getY(), blockRay.getBlockPos().getZ()));
|
||||
player.sendMessage(text, false);
|
||||
PlayerClaimData.get(player).addDisplayClaim(claim);
|
||||
} else
|
||||
player.sendMessage(Text.of(ConfigHandler.lang.inspectNoClaim), false);
|
||||
}
|
||||
return TypedActionResult.success(stack);
|
||||
}
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) world);
|
||||
BlockPos pos = player.getBlockPos();
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
if (claim == null)
|
||||
return TypedActionResult.pass(stack);
|
||||
if (stack.getItem() == Items.ENDER_PEARL)
|
||||
return claim.canInteract(player, EnumPermission.ENDERPEARL, pos) ? TypedActionResult.pass(stack) : TypedActionResult.fail(stack);
|
||||
if (stack.getItem() instanceof BucketItem)
|
||||
return claim.canInteract(player, EnumPermission.BUCKET, pos) ? TypedActionResult.pass(stack) : TypedActionResult.fail(stack);
|
||||
return TypedActionResult.pass(stack);
|
||||
}
|
||||
}
|
25
src/main/java/com/flemmli97/flan/event/WorldEvents.java
Normal file
25
src/main/java/com/flemmli97/flan/event/WorldEvents.java
Normal file
@ -0,0 +1,25 @@
|
||||
package com.flemmli97.flan.event;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.claim.ClaimStorage;
|
||||
import com.flemmli97.flan.claim.EnumPermission;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WorldEvents {
|
||||
|
||||
public static void modifyExplosion(List<BlockPos> list, World world) {
|
||||
if (world.isClient)
|
||||
return;
|
||||
ClaimStorage storage = ClaimStorage.get((ServerWorld) world);
|
||||
list.removeIf(pos -> {
|
||||
Claim claim = storage.getClaimAt(pos);
|
||||
if (claim != null)
|
||||
return !claim.canInteract(null, EnumPermission.EXPLOSIONS, pos);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
107
src/main/java/com/flemmli97/flan/gui/ClaimMenuScreenHandler.java
Normal file
107
src/main/java/com/flemmli97/flan/gui/ClaimMenuScreenHandler.java
Normal file
@ -0,0 +1,107 @@
|
||||
package com.flemmli97.flan.gui;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.claim.ClaimStorage;
|
||||
import com.flemmli97.flan.config.ConfigHandler;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
public class ClaimMenuScreenHandler extends ServerOnlyScreenHandler {
|
||||
|
||||
private Claim claim;
|
||||
|
||||
private ClaimMenuScreenHandler(int syncId, PlayerInventory playerInventory, Claim claim) {
|
||||
super(syncId, playerInventory, 1);
|
||||
this.claim = claim;
|
||||
}
|
||||
|
||||
public static void openClaimMenu(PlayerEntity player, Claim claim) {
|
||||
NamedScreenHandlerFactory fac = new NamedScreenHandlerFactory() {
|
||||
@Override
|
||||
public ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player) {
|
||||
return new ClaimMenuScreenHandler(syncId, inv, claim);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDisplayName() {
|
||||
return Text.of("Claim-Menu");
|
||||
}
|
||||
};
|
||||
player.openHandledScreen(fac);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillInventoryWith(PlayerEntity player, Inventory inv, Object... additionalData) {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
ItemStack close = new ItemStack(Items.TNT);
|
||||
close.setCustomName(new LiteralText("Close").setStyle(Style.EMPTY.withFormatting(Formatting.DARK_RED)));
|
||||
inv.setStack(i, close);
|
||||
break;
|
||||
case 2:
|
||||
ItemStack perm = new ItemStack(Items.BEACON);
|
||||
perm.setCustomName(new LiteralText("Edit Global Permissions").setStyle(Style.EMPTY.withFormatting(Formatting.GOLD)));
|
||||
inv.setStack(i, perm);
|
||||
break;
|
||||
case 3:
|
||||
ItemStack group = new ItemStack(Items.WRITABLE_BOOK);
|
||||
group.setCustomName(new LiteralText("Edit Permissiongroups").setStyle(Style.EMPTY.withFormatting(Formatting.GOLD)));
|
||||
inv.setStack(i, group);
|
||||
break;
|
||||
case 8:
|
||||
ItemStack delete = new ItemStack(Items.BARRIER);
|
||||
delete.setCustomName(new LiteralText("Delete Claim").setStyle(Style.EMPTY.withFormatting(Formatting.RED)));
|
||||
inv.setStack(i, delete);
|
||||
break;
|
||||
default:
|
||||
inv.setStack(i, ServerScreenHelper.emptyFiller());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRightSlot(int slot) {
|
||||
return slot == 0 || slot == 2 || slot == 3 || slot == 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean handleSlotClicked(ServerPlayerEntity player, int index, Slot slot, int clickType) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
player.closeHandledScreen();
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
break;
|
||||
case 2:
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> PermissionScreenHandler.openClaimMenu(player, this.claim, null));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
break;
|
||||
case 3:
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> GroupScreenHandler.openGroupMenu(player, this.claim));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
break;
|
||||
case 8:
|
||||
ClaimStorage storage = ClaimStorage.get(player.getServerWorld());
|
||||
storage.deleteClaim(this.claim);
|
||||
player.closeHandledScreen();
|
||||
player.sendMessage(Text.of(ConfigHandler.lang.deleteClaim), false);
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.BLOCK_ANVIL_PLACE, 1, 1f);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
package com.flemmli97.flan.gui;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.config.ConfigHandler;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.block.entity.SkullBlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupPlayerScreenHandler extends ServerOnlyScreenHandler {
|
||||
|
||||
private Claim claim;
|
||||
private String group;
|
||||
private boolean removeMode;
|
||||
|
||||
private GroupPlayerScreenHandler(int syncId, PlayerInventory playerInventory, Claim claim, String group) {
|
||||
super(syncId, playerInventory, 6, claim, group);
|
||||
this.claim = claim;
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public static void openPlayerGroupMenu(PlayerEntity player, Claim claim, String group) {
|
||||
NamedScreenHandlerFactory fac = new NamedScreenHandlerFactory() {
|
||||
@Override
|
||||
public ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player) {
|
||||
return new GroupPlayerScreenHandler(syncId, inv, claim, group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDisplayName() {
|
||||
return Text.of(group + "-Players");
|
||||
}
|
||||
};
|
||||
player.openHandledScreen(fac);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillInventoryWith(PlayerEntity player, Inventory inv, Object... additionalData) {
|
||||
if (additionalData == null || additionalData.length < 2)
|
||||
return;
|
||||
Claim claim = (Claim) additionalData[0];
|
||||
List<String> players = claim.playersFromGroup(player.getServer(), (String) additionalData[1]);
|
||||
for (int i = 0; i < 54; i++) {
|
||||
if (i == 0) {
|
||||
ItemStack close = new ItemStack(Items.TNT);
|
||||
close.setCustomName(new LiteralText("Back").setStyle(Style.EMPTY.withFormatting(Formatting.DARK_RED)));
|
||||
inv.setStack(i, close);
|
||||
} else if (i == 3) {
|
||||
ItemStack stack = new ItemStack(Items.ANVIL);
|
||||
stack.setCustomName(new LiteralText("Add").setStyle(Style.EMPTY.withFormatting(Formatting.DARK_GREEN)));
|
||||
inv.setStack(i, stack);
|
||||
} else if (i == 4) {
|
||||
ItemStack stack = new ItemStack(Items.REDSTONE_BLOCK);
|
||||
stack.setCustomName(new LiteralText("Remove Mode: " + this.removeMode).setStyle(Style.EMPTY.withFormatting(Formatting.DARK_RED)));
|
||||
inv.setStack(i, stack);
|
||||
} else if (i < 9 || i > 44 || i % 9 == 0 || i % 9 == 8)
|
||||
inv.setStack(i, ServerScreenHelper.emptyFiller());
|
||||
else {
|
||||
int row = i / 9 - 1;
|
||||
int id = (i % 9) + row * 7 - 1;
|
||||
if (id < players.size()) {
|
||||
ItemStack group = new ItemStack(Items.PLAYER_HEAD);
|
||||
GameProfile gameProfile = new GameProfile(null, players.get(id));
|
||||
gameProfile = SkullBlockEntity.loadProperties(gameProfile);
|
||||
group.getOrCreateTag().put("SkullOwner", NbtHelper.fromGameProfile(new CompoundTag(), gameProfile));
|
||||
inv.setStack(i, group);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRightSlot(int slot) {
|
||||
return slot == 0 || slot == 3 || slot == 4 || (slot < 45 && slot > 8 && slot % 9 != 0 && slot % 9 != 8);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean handleSlotClicked(ServerPlayerEntity player, int index, Slot slot, int clickType) {
|
||||
if (index == 0) {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> GroupScreenHandler.openGroupMenu(player, this.claim));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
return true;
|
||||
}
|
||||
if (index == 3) {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> StringResultScreenHandler.createNewStringResult(player, this.claim, (s) -> {
|
||||
GameProfile prof = player.getServer().getUserCache().findByName(s);
|
||||
boolean fl = prof == null || this.claim.setPlayerGroup(prof.getId(), this.group, false);
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> GroupPlayerScreenHandler.openPlayerGroupMenu(player, claim, group));
|
||||
if (fl)
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.BLOCK_ANVIL_USE, 1, 1f);
|
||||
else {
|
||||
player.sendMessage(Text.of(ConfigHandler.lang.playerGroupAddFail), false);
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.ENTITY_VILLAGER_NO, 1, 1f);
|
||||
}
|
||||
}, () -> {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> GroupPlayerScreenHandler.openPlayerGroupMenu(player, claim, group));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.ENTITY_VILLAGER_NO, 1, 1f);
|
||||
}));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
return true;
|
||||
}
|
||||
if (index == 4) {
|
||||
this.removeMode = !this.removeMode;
|
||||
ItemStack stack = new ItemStack(Items.REDSTONE_BLOCK);
|
||||
stack.setCustomName(new LiteralText("Remove Mode: " + this.removeMode).setStyle(Style.EMPTY.withFormatting(Formatting.DARK_RED)));
|
||||
slot.setStack(stack);
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
return true;
|
||||
}
|
||||
ItemStack stack = slot.getStack();
|
||||
if (!stack.isEmpty()) {
|
||||
CompoundTag tag = stack.getOrCreateSubTag("SkullOwner");
|
||||
if (this.removeMode && tag.contains("Id")) {
|
||||
this.claim.setPlayerGroup(tag.getUuid("Id"), null, false);
|
||||
slot.setStack(ItemStack.EMPTY);
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.ENTITY_BAT_DEATH, 1, 1f);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
138
src/main/java/com/flemmli97/flan/gui/GroupScreenHandler.java
Normal file
138
src/main/java/com/flemmli97/flan/gui/GroupScreenHandler.java
Normal file
@ -0,0 +1,138 @@
|
||||
package com.flemmli97.flan.gui;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.claim.EnumPermission;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GroupScreenHandler extends ServerOnlyScreenHandler {
|
||||
|
||||
private Claim claim;
|
||||
|
||||
private boolean removeMode;
|
||||
|
||||
private GroupScreenHandler(int syncId, PlayerInventory playerInventory, Claim claim) {
|
||||
super(syncId, playerInventory, 6, claim);
|
||||
this.claim = claim;
|
||||
}
|
||||
|
||||
public static void openGroupMenu(PlayerEntity player, Claim claim) {
|
||||
NamedScreenHandlerFactory fac = new NamedScreenHandlerFactory() {
|
||||
@Override
|
||||
public ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player) {
|
||||
return new GroupScreenHandler(syncId, inv, claim);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDisplayName() {
|
||||
return Text.of("Claim-Groups");
|
||||
}
|
||||
};
|
||||
player.openHandledScreen(fac);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillInventoryWith(PlayerEntity player, Inventory inv, Object... additionalData) {
|
||||
if (additionalData == null)
|
||||
return;
|
||||
Claim claim = (Claim) additionalData[0];
|
||||
for (int i = 0; i < 54; i++) {
|
||||
if (i == 0) {
|
||||
ItemStack close = new ItemStack(Items.TNT);
|
||||
close.setCustomName(new LiteralText("Back").setStyle(Style.EMPTY.withFormatting(Formatting.DARK_RED)));
|
||||
inv.setStack(i, close);
|
||||
} else if (i == 3) {
|
||||
ItemStack stack = new ItemStack(Items.ANVIL);
|
||||
stack.setCustomName(new LiteralText("Add").setStyle(Style.EMPTY.withFormatting(Formatting.DARK_GREEN)));
|
||||
inv.setStack(i, stack);
|
||||
} else if (i == 4) {
|
||||
ItemStack stack = new ItemStack(Items.REDSTONE_BLOCK);
|
||||
stack.setCustomName(new LiteralText("Remove Mode: " + this.removeMode).setStyle(Style.EMPTY.withFormatting(Formatting.DARK_RED)));
|
||||
inv.setStack(i, stack);
|
||||
} else if (i < 9 || i > 44 || i % 9 == 0 || i % 9 == 8)
|
||||
inv.setStack(i, ServerScreenHelper.emptyFiller());
|
||||
else {
|
||||
List<String> groups = claim.groups();
|
||||
int row = i / 9 - 1;
|
||||
int id = (i % 9) + row * 7 - 1;
|
||||
if (id < groups.size()) {
|
||||
ItemStack group = new ItemStack(Items.PAPER);
|
||||
group.setCustomName(new LiteralText(groups.get(id)).setStyle(Style.EMPTY.withFormatting(Formatting.DARK_BLUE)));
|
||||
inv.setStack(i, group);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRightSlot(int slot) {
|
||||
return slot == 0 || slot == 3 || slot == 4 || (slot < 45 && slot > 8 && slot % 9 != 0 && slot % 9 != 8);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean handleSlotClicked(ServerPlayerEntity player, int index, Slot slot, int clickType) {
|
||||
if (index == 0) {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> ClaimMenuScreenHandler.openClaimMenu(player, this.claim));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
return true;
|
||||
}
|
||||
if (index == 3) {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> StringResultScreenHandler.createNewStringResult(player, this.claim, (s) -> {
|
||||
this.claim.editPerms(player, s, EnumPermission.EDITCLAIM, -1);
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> GroupScreenHandler.openGroupMenu(player, this.claim));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.BLOCK_ANVIL_USE, 1, 1f);
|
||||
}, () -> {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> GroupScreenHandler.openGroupMenu(player, this.claim));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.ENTITY_VILLAGER_NO, 1, 1f);
|
||||
}));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
return true;
|
||||
}
|
||||
if (index == 4) {
|
||||
this.removeMode = !this.removeMode;
|
||||
ItemStack stack = new ItemStack(Items.REDSTONE_BLOCK);
|
||||
stack.setCustomName(new LiteralText("Remove Mode: " + this.removeMode).setStyle(Style.EMPTY.withFormatting(Formatting.DARK_RED)));
|
||||
slot.setStack(stack);
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
return true;
|
||||
}
|
||||
ItemStack stack = slot.getStack();
|
||||
if (!stack.isEmpty()) {
|
||||
String name = stack.getName().asString();
|
||||
if (this.removeMode) {
|
||||
this.claim.removePermGroup(player, name);
|
||||
slot.setStack(ItemStack.EMPTY);
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.ENTITY_BAT_DEATH, 1, 1f);
|
||||
} else {
|
||||
if (clickType == 1) {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> PermissionScreenHandler.openClaimMenu(player, this.claim, name));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
} else {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> GroupPlayerScreenHandler.openPlayerGroupMenu(player, this.claim, name));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
package com.flemmli97.flan.gui;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.claim.EnumPermission;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
public class PermissionScreenHandler extends ServerOnlyScreenHandler {
|
||||
|
||||
private Claim claim;
|
||||
private String group;
|
||||
private int page;
|
||||
|
||||
private PermissionScreenHandler(int syncId, PlayerInventory playerInventory, Claim claim, String group, int page) {
|
||||
super(syncId, playerInventory, 6, claim, group, page);
|
||||
this.claim = claim;
|
||||
this.group = group;
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
public static void openClaimMenu(PlayerEntity player, Claim claim, String group) {
|
||||
NamedScreenHandlerFactory fac = new NamedScreenHandlerFactory() {
|
||||
@Override
|
||||
public ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player) {
|
||||
return new PermissionScreenHandler(syncId, inv, claim, group, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDisplayName() {
|
||||
return Text.of(group == null ? "Global-Permissions" : String.format("%s-Permissions", group));
|
||||
}
|
||||
};
|
||||
player.openHandledScreen(fac);
|
||||
}
|
||||
|
||||
private static void openClaimMenu(PlayerEntity player, Claim claim, String group, int page) {
|
||||
NamedScreenHandlerFactory fac = new NamedScreenHandlerFactory() {
|
||||
@Override
|
||||
public ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player) {
|
||||
return new PermissionScreenHandler(syncId, inv, claim, group, page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDisplayName() {
|
||||
return Text.of(group == null ? "Global-Permissions" : String.format("%s-Permissions", group));
|
||||
}
|
||||
};
|
||||
player.openHandledScreen(fac);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillInventoryWith(PlayerEntity player, Inventory inv, Object... additionalData) {
|
||||
if (additionalData == null)
|
||||
return;
|
||||
for (int i = 0; i < 54; i++) {
|
||||
int page = (int) additionalData[2];
|
||||
if (i == 0) {
|
||||
ItemStack close = new ItemStack(Items.TNT);
|
||||
close.setCustomName(new LiteralText("Back").setStyle(Style.EMPTY.withFormatting(Formatting.DARK_RED)));
|
||||
inv.setStack(i, close);
|
||||
} else if (page == 1 && i == 47) {
|
||||
ItemStack close = new ItemStack(Items.ARROW);
|
||||
close.setCustomName(new LiteralText("Prev").setStyle(Style.EMPTY.withFormatting(Formatting.WHITE)));
|
||||
inv.setStack(i, close);
|
||||
} else if (page == 0 && i == 51) {
|
||||
ItemStack close = new ItemStack(Items.ARROW);
|
||||
close.setCustomName(new LiteralText("Next").setStyle(Style.EMPTY.withFormatting(Formatting.WHITE)));
|
||||
inv.setStack(i, close);
|
||||
} else if (i < 9 || i > 44 || i % 9 == 0 || i % 9 == 8)
|
||||
inv.setStack(i, ServerScreenHelper.emptyFiller());
|
||||
else {
|
||||
int row = i / 9 - 1;
|
||||
int id = (i % 9) + row * 7 - 1 + page * 54;
|
||||
if (id < EnumPermission.values().length)
|
||||
inv.setStack(i, ServerScreenHelper.fromPermission((Claim) additionalData[0], EnumPermission.values()[id], additionalData.length == 1 ? null : String.valueOf(additionalData[1])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean handleSlotClicked(ServerPlayerEntity player, int index, Slot slot, int clickType) {
|
||||
if (index == 0) {
|
||||
if (this.group == null) {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> ClaimMenuScreenHandler.openClaimMenu(player, this.claim));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
} else {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> GroupScreenHandler.openGroupMenu(player, this.claim));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (index == 47) {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> PermissionScreenHandler.openClaimMenu(player, this.claim, this.group, 0));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
}
|
||||
if (index == 51) {
|
||||
player.closeHandledScreen();
|
||||
player.getServer().execute(() -> PermissionScreenHandler.openClaimMenu(player, this.claim, this.group, 1));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.UI_BUTTON_CLICK, 1, 1f);
|
||||
}
|
||||
ItemStack stack = slot.getStack();
|
||||
String name = stack.getName().asString();
|
||||
EnumPermission perm;
|
||||
try {
|
||||
perm = EnumPermission.valueOf(name);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
if (this.group == null)
|
||||
this.claim.editGlobalPerms(perm);
|
||||
else
|
||||
this.claim.editPerms(player, this.group, perm, this.claim.groupHasPerm(this.group, perm) + 1);
|
||||
slot.setStack(ServerScreenHelper.fromPermission(this.claim, perm, this.group));
|
||||
ServerScreenHelper.playSongToPlayer(player, SoundEvents.BLOCK_NOTE_BLOCK_PLING, 1, 1.2f);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isRightSlot(int slot) {
|
||||
return slot == 0 || (this.page == 1 && slot == 47) || (this.page == 0 && slot == 51) || (slot < 45 && slot > 8 && slot % 9 != 0 && slot % 9 != 8);
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
package com.flemmli97.flan.gui;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.inventory.SimpleInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerListener;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ServerOnlyScreenHandler extends ScreenHandler {
|
||||
|
||||
private final Inventory inventory;
|
||||
private final List<ScreenHandlerListener> listeners = Lists.newArrayList();
|
||||
|
||||
protected ServerOnlyScreenHandler(int syncId, PlayerInventory playerInventory, int rows, Object... additionalData) {
|
||||
super(fromRows(rows), syncId);
|
||||
int i = (rows - 4) * 18;
|
||||
this.inventory = new SimpleInventory(rows * 9);
|
||||
this.fillInventoryWith(playerInventory.player, this.inventory, additionalData);
|
||||
int n;
|
||||
int m;
|
||||
for (n = 0; n < rows; ++n) {
|
||||
for (m = 0; m < 9; ++m) {
|
||||
this.addSlot(new Slot(inventory, m + n * 9, 8 + m * 18, 18 + n * 18));
|
||||
}
|
||||
}
|
||||
|
||||
for (n = 0; n < 3; ++n) {
|
||||
for (m = 0; m < 9; ++m) {
|
||||
this.addSlot(new Slot(playerInventory, m + n * 9 + 9, 8 + m * 18, 103 + n * 18 + i));
|
||||
}
|
||||
}
|
||||
|
||||
for (n = 0; n < 9; ++n) {
|
||||
this.addSlot(new Slot(playerInventory, n, 8 + n * 18, 161 + i));
|
||||
}
|
||||
}
|
||||
|
||||
private static ScreenHandlerType fromRows(int rows) {
|
||||
switch (rows) {
|
||||
case 2:
|
||||
return ScreenHandlerType.GENERIC_9X2;
|
||||
case 3:
|
||||
return ScreenHandlerType.GENERIC_9X3;
|
||||
case 4:
|
||||
return ScreenHandlerType.GENERIC_9X4;
|
||||
case 5:
|
||||
return ScreenHandlerType.GENERIC_9X5;
|
||||
case 6:
|
||||
return ScreenHandlerType.GENERIC_9X6;
|
||||
}
|
||||
return ScreenHandlerType.GENERIC_9X1;
|
||||
}
|
||||
|
||||
protected abstract void fillInventoryWith(PlayerEntity player, Inventory inv, Object... additionalData);
|
||||
|
||||
@Override
|
||||
public boolean canUse(PlayerEntity player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack onSlotClick(int i, int j, SlotActionType actionType, PlayerEntity playerEntity) {
|
||||
if (i < 0)
|
||||
return ItemStack.EMPTY;
|
||||
Slot slot = this.slots.get(i);
|
||||
if (this.isRightSlot(i))
|
||||
this.handleSlotClicked((ServerPlayerEntity) playerEntity, i, slot, j);
|
||||
this.sendContentUpdates();
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferSlot(PlayerEntity player, int index) {
|
||||
if (!(player instanceof ServerPlayerEntity))
|
||||
return ItemStack.EMPTY;
|
||||
Slot slot = this.slots.get(index);
|
||||
if (this.isRightSlot(index))
|
||||
this.handleSlotClicked((ServerPlayerEntity) player, index, slot, 0);
|
||||
this.sendContentUpdates();
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(ScreenHandlerListener listener) {
|
||||
if (!this.listeners.contains(listener)) {
|
||||
this.listeners.add(listener);
|
||||
listener.onHandlerRegistered(this, this.getStacks());
|
||||
this.sendContentUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
int j;
|
||||
for (j = 0; j < this.slots.size(); ++j) {
|
||||
ItemStack itemStack = this.slots.get(j).getStack();
|
||||
Iterator var5 = this.listeners.iterator();
|
||||
|
||||
while (var5.hasNext()) {
|
||||
ScreenHandlerListener screenHandlerListener = (ScreenHandlerListener) var5.next();
|
||||
screenHandlerListener.onSlotUpdate(this, j, itemStack.copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean isRightSlot(int slot);
|
||||
|
||||
/**
|
||||
* @param clickType 0 for left click, 1 for right click
|
||||
*/
|
||||
protected abstract boolean handleSlotClicked(ServerPlayerEntity player, int index, Slot slot, int clickType);
|
||||
}
|
57
src/main/java/com/flemmli97/flan/gui/ServerScreenHelper.java
Normal file
57
src/main/java/com/flemmli97/flan/gui/ServerScreenHelper.java
Normal file
@ -0,0 +1,57 @@
|
||||
package com.flemmli97.flan.gui;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.claim.EnumPermission;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Style;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
public class ServerScreenHelper {
|
||||
|
||||
public static ItemStack emptyFiller() {
|
||||
ItemStack stack = new ItemStack(Items.GRAY_STAINED_GLASS_PANE);
|
||||
stack.setCustomName(Text.of(""));
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static ItemStack fromPermission(Claim claim, EnumPermission perm, String group) {
|
||||
ItemStack stack = new ItemStack(perm.getItem());
|
||||
stack.setCustomName(new LiteralText(perm.toString()).setStyle(Style.EMPTY.withFormatting(Formatting.GOLD)));
|
||||
ListTag lore = new ListTag();
|
||||
String permFlag;
|
||||
if (group == null)
|
||||
permFlag = "" + claim.permEnabled(perm);
|
||||
else {
|
||||
switch (claim.groupHasPerm(group, perm)) {
|
||||
case -1:
|
||||
permFlag = "default";
|
||||
break;
|
||||
case 1:
|
||||
permFlag = "true";
|
||||
break;
|
||||
default:
|
||||
permFlag = "false";
|
||||
break;
|
||||
}
|
||||
}
|
||||
Text text = new LiteralText("Enabled: " + permFlag).setStyle(Style.EMPTY.withFormatting(permFlag.equals("true") ? Formatting.GREEN : Formatting.RED));
|
||||
lore.add(StringTag.of(Text.Serializer.toJson(text)));
|
||||
stack.getOrCreateSubTag("display").put("Lore", lore);
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static void playSongToPlayer(ServerPlayerEntity player, SoundEvent event, float vol, float pitch) {
|
||||
player.networkHandler.sendPacket(
|
||||
new PlaySoundS2CPacket(event, SoundCategory.PLAYERS, player.getPos().x, player.getPos().y, player.getPos().z, vol, pitch));
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
package com.flemmli97.flan.gui;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.config.ConfigHandler;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.screen.AnvilScreenHandler;
|
||||
import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerListener;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.screen.slot.SlotActionType;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class StringResultScreenHandler extends AnvilScreenHandler {
|
||||
|
||||
private final List<ScreenHandlerListener> listeners = Lists.newArrayList();
|
||||
|
||||
private final Consumer<String> cons;
|
||||
private final Runnable ret;
|
||||
|
||||
private boolean init;
|
||||
private String name;
|
||||
|
||||
private StringResultScreenHandler(int syncId, PlayerInventory playerInventory, Consumer<String> cons, Runnable ret) {
|
||||
super(syncId, playerInventory);
|
||||
ItemStack stack = new ItemStack(Items.PAPER);
|
||||
stack.setCustomName(Text.of(""));
|
||||
this.input.setStack(0, stack);
|
||||
ItemStack out = new ItemStack(Items.BOOK);
|
||||
out.setCustomName(Text.of(ConfigHandler.lang.stringScreenReturn));
|
||||
this.output.setStack(0, out);
|
||||
this.cons = cons;
|
||||
this.ret = ret;
|
||||
|
||||
}
|
||||
|
||||
public static void createNewStringResult(PlayerEntity player, Claim claim, Consumer<String> cons, Runnable ret) {
|
||||
NamedScreenHandlerFactory fac = new NamedScreenHandlerFactory() {
|
||||
@Override
|
||||
public ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player) {
|
||||
return new StringResultScreenHandler(syncId, inv, cons, ret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Text getDisplayName() {
|
||||
return Text.of("");
|
||||
}
|
||||
};
|
||||
player.openHandledScreen(fac);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(PlayerEntity player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canTakeOutput(PlayerEntity player, boolean present) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack onSlotClick(int i, int j, SlotActionType actionType, PlayerEntity playerEntity) {
|
||||
if (i < 0)
|
||||
return ItemStack.EMPTY;
|
||||
if (i == 0)
|
||||
this.ret.run();
|
||||
else if (i == 2) {
|
||||
Slot slot = this.slots.get(i);
|
||||
String s = slot.getStack().hasCustomName() ? slot.getStack().getName().asString() : "";
|
||||
if (!s.isEmpty() && !s.equals(ConfigHandler.lang.stringScreenReturn))
|
||||
this.cons.accept(s);
|
||||
}
|
||||
this.sendContentUpdates();
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferSlot(PlayerEntity player, int index) {
|
||||
if (index == 0)
|
||||
this.ret.run();
|
||||
else if (index == 2) {
|
||||
Slot slot = this.slots.get(index);
|
||||
String s = slot.getStack().hasCustomName() ? slot.getStack().getName().asString() : "";
|
||||
if (!s.isEmpty() && !s.equals(ConfigHandler.lang.stringScreenReturn))
|
||||
this.cons.accept(s);
|
||||
}
|
||||
this.sendContentUpdates();
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(ScreenHandlerListener listener) {
|
||||
if (!this.listeners.contains(listener)) {
|
||||
this.listeners.add(listener);
|
||||
listener.onHandlerRegistered(this, this.getStacks());
|
||||
this.sendContentUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
int j;
|
||||
for (j = 0; j < this.slots.size(); ++j) {
|
||||
ItemStack itemStack = this.slots.get(j).getStack();
|
||||
Iterator var5 = this.listeners.iterator();
|
||||
|
||||
while (var5.hasNext()) {
|
||||
ScreenHandlerListener screenHandlerListener = (ScreenHandlerListener) var5.next();
|
||||
screenHandlerListener.onSlotUpdate(this, j, itemStack.copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateResult() {
|
||||
if (!init)
|
||||
this.init = true;
|
||||
else {
|
||||
ItemStack out = this.slots.get(2).getStack();
|
||||
if (StringUtils.isBlank(this.name))
|
||||
out.removeCustomName();
|
||||
else if (!this.name.equals(out.getName().getString())) {
|
||||
out.setCustomName(new LiteralText(this.name));
|
||||
}
|
||||
}
|
||||
this.sendContentUpdates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNewItemName(String string) {
|
||||
this.name = string;
|
||||
this.updateResult();
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import com.flemmli97.flan.event.BlockInteractEvents;
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(AbstractBlock.AbstractBlockState.class)
|
||||
public abstract class AbstractBlockStateMixin {
|
||||
|
||||
@Inject(method = "onEntityCollision", at = @At(value = "HEAD"), cancellable = true)
|
||||
public void collision(World world, BlockPos pos, Entity entity, CallbackInfo info) {
|
||||
if (BlockInteractEvents.blockCollisionEntity(this.asBlockState(), world, pos, entity)) {
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Shadow
|
||||
protected abstract BlockState asBlockState();
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import com.flemmli97.flan.event.EntityInteractEvents;
|
||||
import net.minecraft.entity.projectile.thrown.EnderPearlEntity;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(EnderPearlEntity.class)
|
||||
public abstract class EnderPearlEntityMixin {
|
||||
|
||||
@Inject(method = "onCollision", at = @At(value = "HEAD"), cancellable = true)
|
||||
public void collision(HitResult hitResult, CallbackInfo info) {
|
||||
if (EntityInteractEvents.projectileHit((EnderPearlEntity) (Object) this, hitResult)) {
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
21
src/main/java/com/flemmli97/flan/mixin/EntityMixin.java
Normal file
21
src/main/java/com/flemmli97/flan/mixin/EntityMixin.java
Normal file
@ -0,0 +1,21 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import com.flemmli97.flan.event.BlockInteractEvents;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Entity.class)
|
||||
public abstract class EntityMixin {
|
||||
|
||||
@Inject(method = "fall", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/Block;onLandedUpon(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/Entity;F)V"), cancellable = true)
|
||||
public void fallOnBlock(double heightDifference, boolean onGround, BlockState landedState, BlockPos landedPosition, CallbackInfo info) {
|
||||
if (BlockInteractEvents.entityFall((Entity) (Object) this, heightDifference, onGround, landedState, landedPosition))
|
||||
info.cancel();
|
||||
}
|
||||
|
||||
}
|
27
src/main/java/com/flemmli97/flan/mixin/ExplosionMixin.java
Normal file
27
src/main/java/com/flemmli97/flan/mixin/ExplosionMixin.java
Normal file
@ -0,0 +1,27 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import com.flemmli97.flan.event.WorldEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.explosion.Explosion;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(Explosion.class)
|
||||
public class ExplosionMixin {
|
||||
|
||||
@Shadow
|
||||
private List<BlockPos> affectedBlocks;
|
||||
@Shadow
|
||||
private World world;
|
||||
|
||||
@Inject(method = "collectBlocksAndDamageEntities", at = @At(value = "RETURN"))
|
||||
public void collision(CallbackInfo info) {
|
||||
WorldEvents.modifyExplosion(this.affectedBlocks, this.world);
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.projectile.PersistentProjectileEntity;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||
|
||||
@Mixin(PersistentProjectileEntity.class)
|
||||
public interface IPersistentProjectileVars {
|
||||
|
||||
@Accessor("inBlockState")
|
||||
void setInBlockState(BlockState state);
|
||||
|
||||
@Accessor("inGround")
|
||||
void setInGround(boolean flag);
|
||||
|
||||
@Invoker("getSound")
|
||||
SoundEvent getSoundEvent();
|
||||
|
||||
@Invoker("clearPiercingStatus")
|
||||
void resetPiercingStatus();
|
||||
}
|
48
src/main/java/com/flemmli97/flan/mixin/PlayerClaimMixin.java
Normal file
48
src/main/java/com/flemmli97/flan/mixin/PlayerClaimMixin.java
Normal file
@ -0,0 +1,48 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import com.flemmli97.flan.IClaimData;
|
||||
import com.flemmli97.flan.player.PlayerClaimData;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
|
||||
@Mixin(ServerPlayerEntity.class)
|
||||
public abstract class PlayerClaimMixin implements IClaimData {
|
||||
@Unique
|
||||
private PlayerClaimData claimData;
|
||||
|
||||
@Shadow
|
||||
private MinecraftServer server;
|
||||
|
||||
@Inject(method = "<init>*", at = @At("RETURN"))
|
||||
private void initData(CallbackInfo info) {
|
||||
this.claimData = new PlayerClaimData((ServerPlayerEntity) (Object) this);
|
||||
}
|
||||
|
||||
@Inject(method = "readCustomDataFromTag", at = @At("RETURN"))
|
||||
private void readData(CompoundTag tag, CallbackInfo info) {
|
||||
this.claimData.read(this.server);
|
||||
}
|
||||
|
||||
@Inject(method = "readCustomDataFromTag", at = @At("RETURN"))
|
||||
private void writeData(CompoundTag tag, CallbackInfo info) {
|
||||
this.claimData.save(this.server);
|
||||
}
|
||||
|
||||
@Inject(method = "tick", at = @At("RETURN"))
|
||||
private void tickData(CallbackInfo info) {
|
||||
this.claimData.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerClaimData getClaimData() {
|
||||
return this.claimData;
|
||||
}
|
||||
}
|
20
src/main/java/com/flemmli97/flan/mixin/ProjectileMixin.java
Normal file
20
src/main/java/com/flemmli97/flan/mixin/ProjectileMixin.java
Normal file
@ -0,0 +1,20 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import com.flemmli97.flan.event.EntityInteractEvents;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.util.hit.HitResult;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(ProjectileEntity.class)
|
||||
public abstract class ProjectileMixin {
|
||||
|
||||
@Inject(method = "onCollision", at = @At(value = "HEAD"), cancellable = true)
|
||||
public void collision(HitResult hitResult, CallbackInfo info) {
|
||||
if (EntityInteractEvents.projectileHit((ProjectileEntity) (Object) this, hitResult)) {
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import com.flemmli97.flan.event.EntityInteractEvents;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* Fabric APIs UseEntityCallback is at Entity#interactAt and thats only used for armor stand. Why its only there idk...
|
||||
*/
|
||||
@Mixin(ServerPlayNetworkHandler.class)
|
||||
public abstract class ServerPlayNetworkHandlerMixin {
|
||||
|
||||
@Shadow
|
||||
public ServerPlayerEntity player;
|
||||
|
||||
@Inject(method = "onPlayerInteractEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;interact(Lnet/minecraft/entity/Entity;Lnet/minecraft/util/Hand;)Lnet/minecraft/util/ActionResult;"), cancellable = true)
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityC2SPacket packet, CallbackInfo info) {
|
||||
World world = player.getEntityWorld();
|
||||
Entity entity = packet.getEntity(world);
|
||||
if (entity != null) {
|
||||
ActionResult result = EntityInteractEvents.useEntity(player, world, packet.getHand(), entity);
|
||||
if (result != ActionResult.PASS) {
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
src/main/java/com/flemmli97/flan/mixin/TurtleEggMixin.java
Normal file
22
src/main/java/com/flemmli97/flan/mixin/TurtleEggMixin.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import com.flemmli97.flan.event.BlockInteractEvents;
|
||||
import net.minecraft.block.TurtleEggBlock;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(TurtleEggBlock.class)
|
||||
public class TurtleEggMixin {
|
||||
|
||||
@Inject(method = "onSteppedOn", at = @At(value = "HEAD"), cancellable = true)
|
||||
public void collision(World world, BlockPos pos, Entity entity, CallbackInfo info) {
|
||||
if (BlockInteractEvents.turtleEggHandle(world, pos, entity)) {
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
22
src/main/java/com/flemmli97/flan/mixin/WitherMixin.java
Normal file
22
src/main/java/com/flemmli97/flan/mixin/WitherMixin.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import com.flemmli97.flan.event.EntityInteractEvents;
|
||||
import net.minecraft.entity.boss.WitherEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(WitherEntity.class)
|
||||
public class WitherMixin {
|
||||
|
||||
@Shadow
|
||||
private int field_7082;
|
||||
|
||||
@Inject(method = "mobTick", at = @At(value = "HEAD"))
|
||||
public void preventClaimDmg(CallbackInfo info) {
|
||||
if (!EntityInteractEvents.witherCanDestroy((WitherEntity) (Object) this))
|
||||
this.field_7082 = -1;
|
||||
}
|
||||
}
|
42
src/main/java/com/flemmli97/flan/mixin/WorldClaimMixin.java
Normal file
42
src/main/java/com/flemmli97/flan/mixin/WorldClaimMixin.java
Normal file
@ -0,0 +1,42 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import com.flemmli97.flan.IClaimData;
|
||||
import com.flemmli97.flan.claim.ClaimStorage;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.profiler.Profiler;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.MutableWorldProperties;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(ServerWorld.class)
|
||||
public abstract class WorldClaimMixin extends World implements IClaimData {
|
||||
@Unique
|
||||
private ClaimStorage claimData;
|
||||
|
||||
protected WorldClaimMixin(MutableWorldProperties properties, RegistryKey<World> registryKey, DimensionType dimensionType, Supplier<Profiler> supplier, boolean bl, boolean bl2, long l) {
|
||||
super(properties, registryKey, dimensionType, supplier, bl, bl2, l);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>*", at = @At("RETURN"))
|
||||
private void initData(CallbackInfo info) {
|
||||
this.claimData = new ClaimStorage(this.getServer(), this.getRegistryKey());
|
||||
}
|
||||
|
||||
@Inject(method = "saveLevel()V", at = @At("RETURN"))
|
||||
private void saveClaimData(CallbackInfo info) {
|
||||
this.claimData.save(this.getServer(), this.getRegistryKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClaimStorage getClaimData() {
|
||||
return this.claimData;
|
||||
}
|
||||
}
|
21
src/main/java/com/flemmli97/flan/mixin/XpEntityMixin.java
Normal file
21
src/main/java/com/flemmli97/flan/mixin/XpEntityMixin.java
Normal file
@ -0,0 +1,21 @@
|
||||
package com.flemmli97.flan.mixin;
|
||||
|
||||
import com.flemmli97.flan.event.EntityInteractEvents;
|
||||
import net.minecraft.entity.ExperienceOrbEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(ExperienceOrbEntity.class)
|
||||
public class XpEntityMixin {
|
||||
|
||||
@Inject(method = "onPlayerCollision", at = @At(value = "HEAD"), cancellable = true)
|
||||
public void collision(PlayerEntity player, CallbackInfo info) {
|
||||
if (EntityInteractEvents.xpAbsorb(player)) {
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
113
src/main/java/com/flemmli97/flan/player/ClaimDisplay.java
Normal file
113
src/main/java/com/flemmli97/flan/player/ClaimDisplay.java
Normal file
@ -0,0 +1,113 @@
|
||||
package com.flemmli97.flan.player;
|
||||
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.claim.ParticleIndicators;
|
||||
import com.flemmli97.flan.config.ConfigHandler;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import net.minecraft.network.packet.s2c.play.ParticleS2CPacket;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.world.Heightmap;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ClaimDisplay {
|
||||
|
||||
private int displayTime;
|
||||
private Claim toDisplay;
|
||||
private int[][] poss;
|
||||
|
||||
private int[][] middlePoss;
|
||||
|
||||
private int[] prevDims;
|
||||
|
||||
public ClaimDisplay(Claim claim) {
|
||||
this.toDisplay = claim;
|
||||
this.displayTime = ConfigHandler.config.claimDisplayTime;
|
||||
this.prevDims = claim.getDimensions();
|
||||
}
|
||||
|
||||
public boolean display(ServerPlayerEntity player) {
|
||||
this.displayTime--;
|
||||
int[] dims = this.toDisplay.getDimensions();
|
||||
if (this.poss == null || this.changed(dims)) {
|
||||
this.middlePoss = this.calculateDisplayPos(player.world);
|
||||
this.poss = new int[][]{
|
||||
this.getPosFrom(player.world, this.prevDims[0], this.prevDims[2], this.prevDims[4]),
|
||||
this.getPosFrom(player.world, this.prevDims[1], this.prevDims[2], this.prevDims[4]),
|
||||
this.getPosFrom(player.world, this.prevDims[0], this.prevDims[3], this.prevDims[4]),
|
||||
this.getPosFrom(player.world, this.prevDims[1], this.prevDims[3], this.prevDims[4]),
|
||||
};
|
||||
}
|
||||
|
||||
if (this.poss != null)
|
||||
for (int[] pos : this.poss) {
|
||||
player.networkHandler.sendPacket(new ParticleS2CPacket(ParticleIndicators.CLAIMCORNER, true, pos[0] + 0.5, pos[1] + 0.25, pos[2] + 0.5, 0, 0.25f, 0, 0, 1));
|
||||
}
|
||||
if (this.middlePoss != null)
|
||||
for (int[] pos : this.middlePoss) {
|
||||
player.networkHandler.sendPacket(new ParticleS2CPacket(ParticleIndicators.CLAIMMIDDLE, true, pos[0] + 0.5, pos[1] + 0.25, pos[2] + 0.5, 0, 0.25f, 0, 0, 1));
|
||||
}
|
||||
this.prevDims = dims;
|
||||
return toDisplay.isRemoved() || displayTime < 0;
|
||||
}
|
||||
|
||||
private boolean changed(int[] dims) {
|
||||
for (int i = 0; i < dims.length; i++)
|
||||
if (dims[i] != this.prevDims[i])
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private int[][] calculateDisplayPos(World world) {
|
||||
List<int[]> l = Lists.newArrayList();
|
||||
Set<Integer> xs = Sets.newHashSet();
|
||||
this.addEvenly(this.prevDims[0], this.prevDims[1], 10, xs);
|
||||
Set<Integer> zs = Sets.newHashSet();
|
||||
this.addEvenly(this.prevDims[2], this.prevDims[3], 10, zs);
|
||||
for (int x : xs) {
|
||||
l.add(this.getPosFrom(world, x, this.prevDims[2], this.prevDims[4]));
|
||||
l.add(this.getPosFrom(world, x, this.prevDims[3], this.prevDims[4]));
|
||||
|
||||
}
|
||||
for (int z : zs) {
|
||||
l.add(this.getPosFrom(world, this.prevDims[0], z, this.prevDims[4]));
|
||||
l.add(this.getPosFrom(world, this.prevDims[1], z, this.prevDims[4]));
|
||||
}
|
||||
|
||||
return l.toArray(new int[0][]);
|
||||
}
|
||||
|
||||
private void addEvenly(int min, int max, int step, Set<Integer> l) {
|
||||
if (max - min < step * 1.5)
|
||||
return;
|
||||
if (max - min > 0 && max - min <= step * 0.5) {
|
||||
l.add(max - step + 1);
|
||||
l.add(min + step - 1);
|
||||
return;
|
||||
}
|
||||
l.add(max - step);
|
||||
l.add(min + step);
|
||||
this.addEvenly(min + step, max - step, step, l);
|
||||
}
|
||||
|
||||
private int[] getPosFrom(World world, int x, int z, int maxY) {
|
||||
return new int[]{x, Math.max(maxY, world.getChunk(x >> 4, z >> 4).sampleHeightmap(Heightmap.Type.WORLD_SURFACE, x & 15, z & 15) + 1), z};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.toDisplay.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj instanceof ClaimDisplay)
|
||||
return this.toDisplay.equals(((ClaimDisplay) obj).toDisplay);
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package com.flemmli97.flan.player;
|
||||
|
||||
public enum EnumEditMode {
|
||||
|
||||
DEFAULT,
|
||||
SUBCLAIM
|
||||
}
|
272
src/main/java/com/flemmli97/flan/player/PlayerClaimData.java
Normal file
272
src/main/java/com/flemmli97/flan/player/PlayerClaimData.java
Normal file
@ -0,0 +1,272 @@
|
||||
package com.flemmli97.flan.player;
|
||||
|
||||
import com.flemmli97.flan.IClaimData;
|
||||
import com.flemmli97.flan.claim.Claim;
|
||||
import com.flemmli97.flan.claim.ClaimStorage;
|
||||
import com.flemmli97.flan.claim.ParticleIndicators;
|
||||
import com.flemmli97.flan.config.ConfigHandler;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.network.packet.s2c.play.ParticleS2CPacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.WorldSavePath;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerClaimData {
|
||||
|
||||
private int claimBlocks, additionalClaimBlocks, usedClaimsBlocks, confirmTick;
|
||||
|
||||
private int lastBlockTick;
|
||||
private EnumEditMode mode = EnumEditMode.DEFAULT;
|
||||
private Claim editingClaim;
|
||||
|
||||
private BlockPos firstCorner;
|
||||
|
||||
private Set<ClaimDisplay> claimDisplayList = Sets.newHashSet();
|
||||
private Set<ClaimDisplay> displayToAdd = Sets.newHashSet();
|
||||
|
||||
private ServerPlayerEntity player;
|
||||
|
||||
private boolean confirmDeleteAll, adminIgnoreClaim;
|
||||
private boolean dirty;
|
||||
|
||||
public PlayerClaimData(ServerPlayerEntity player) {
|
||||
this.player = player;
|
||||
this.claimBlocks = ConfigHandler.config.startingBlocks;
|
||||
}
|
||||
|
||||
public static PlayerClaimData get(PlayerEntity player) {
|
||||
return (PlayerClaimData) ((IClaimData) player).getClaimData();
|
||||
}
|
||||
|
||||
public int getClaimBlocks() {
|
||||
return this.claimBlocks;
|
||||
}
|
||||
|
||||
public void setClaimBlocks(int amount) {
|
||||
this.claimBlocks = amount;
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
public boolean addClaimBlocks(int amount) {
|
||||
if (this.claimBlocks + amount > ConfigHandler.config.maxClaimBlocks)
|
||||
return false;
|
||||
this.claimBlocks += amount;
|
||||
this.dirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getAdditionalClaims() {
|
||||
return this.additionalClaimBlocks;
|
||||
}
|
||||
|
||||
public void setAdditionalClaims(int amount) {
|
||||
this.additionalClaimBlocks = amount;
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
public boolean useClaimBlocks(int amount) {
|
||||
if (this.usedClaimsBlocks + amount > this.claimBlocks + this.additionalClaimBlocks)
|
||||
return false;
|
||||
this.usedClaimsBlocks += amount;
|
||||
this.dirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public Claim currentEdit() {
|
||||
return this.editingClaim;
|
||||
}
|
||||
|
||||
public void setEditClaim(Claim claim) {
|
||||
this.editingClaim = claim;
|
||||
}
|
||||
|
||||
public void addDisplayClaim(Claim claim) {
|
||||
this.displayToAdd.add(new ClaimDisplay(claim));
|
||||
}
|
||||
|
||||
public EnumEditMode getEditMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public void setEditMode(EnumEditMode mode) {
|
||||
this.mode = mode;
|
||||
this.editingClaim = null;
|
||||
this.firstCorner = null;
|
||||
}
|
||||
|
||||
public BlockPos editingCorner() {
|
||||
return this.firstCorner;
|
||||
}
|
||||
|
||||
public void setEditingCorner(BlockPos pos) {
|
||||
if (pos != null) {
|
||||
BlockState state = this.player.world.getBlockState(pos);
|
||||
while (state.isAir() || state.getMaterial().isReplaceable()) {
|
||||
pos = pos.down();
|
||||
state = this.player.world.getBlockState(pos);
|
||||
}
|
||||
}
|
||||
this.firstCorner = pos;
|
||||
}
|
||||
|
||||
public boolean confirmedDeleteAll() {
|
||||
return this.confirmDeleteAll;
|
||||
}
|
||||
|
||||
public void setConfirmDeleteAll(boolean flag) {
|
||||
this.confirmDeleteAll = flag;
|
||||
this.confirmTick = 400;
|
||||
}
|
||||
|
||||
public void setAdminIgnoreClaim(boolean flag) {
|
||||
this.adminIgnoreClaim = flag;
|
||||
}
|
||||
|
||||
public boolean isAdminIgnoreClaim() {
|
||||
return this.adminIgnoreClaim;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
ServerPlayerEntity sPlayer = this.player;
|
||||
this.claimDisplayList.addAll(this.displayToAdd);
|
||||
this.displayToAdd.clear();
|
||||
this.claimDisplayList.removeIf(d -> d.display(sPlayer));
|
||||
if (++this.lastBlockTick > ConfigHandler.config.ticksForNextBlock) {
|
||||
this.addClaimBlocks(1);
|
||||
this.lastBlockTick = 0;
|
||||
}
|
||||
if (this.firstCorner != null) {
|
||||
this.player.networkHandler.sendPacket(new ParticleS2CPacket(ParticleIndicators.SETCORNER, true, this.firstCorner.getX() + 0.5, this.firstCorner.getY() + 1.25, this.firstCorner.getZ() + 0.5, 0, 0.25f, 0, 0, 3));
|
||||
if (this.player.getMainHandStack().getItem() != ConfigHandler.config.claimingItem && this.player.getOffHandStack().getItem() != ConfigHandler.config.claimingItem) {
|
||||
this.firstCorner = null;
|
||||
this.editingClaim = null;
|
||||
}
|
||||
}
|
||||
if (--this.confirmTick < 0)
|
||||
this.confirmDeleteAll = false;
|
||||
}
|
||||
|
||||
public void save(MinecraftServer server) {
|
||||
File dir = new File(server.getSavePath(WorldSavePath.PLAYERDATA).toFile(), "/claimData/");
|
||||
if (!dir.exists())
|
||||
dir.mkdirs();
|
||||
try {
|
||||
if (!this.dirty)
|
||||
return;
|
||||
File file = new File(dir, this.player.getUuid() + ".json");
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
FileWriter writer = new FileWriter(file);
|
||||
JsonObject obj = new JsonObject();
|
||||
obj.addProperty("ClaimBlocks", this.claimBlocks);
|
||||
obj.addProperty("AdditionalBlocks", this.additionalClaimBlocks);
|
||||
ClaimStorage.GSON.toJson(obj, writer);
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void read(MinecraftServer server) {
|
||||
File dir = new File(server.getSavePath(WorldSavePath.PLAYERDATA).toFile(), "/claimData/");
|
||||
if (!dir.exists())
|
||||
return;
|
||||
try {
|
||||
File file = new File(dir, this.player.getUuid() + ".json");
|
||||
if (!file.exists())
|
||||
return;
|
||||
FileReader reader = new FileReader(file);
|
||||
JsonObject obj = ClaimStorage.GSON.fromJson(reader, JsonObject.class);
|
||||
this.claimBlocks = obj.get("ClaimBlocks").getAsInt();
|
||||
this.additionalClaimBlocks = obj.get("AdditionalBlocks").getAsInt();
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void editForOfflinePlayer(MinecraftServer server, UUID uuid, int additionalClaimBlocks) {
|
||||
File dir = new File(server.getSavePath(WorldSavePath.PLAYERDATA).toFile(), "/claimData/");
|
||||
if (!dir.exists())
|
||||
dir.mkdirs();
|
||||
try {
|
||||
File file = new File(dir, uuid.toString() + ".json");
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
FileReader reader = new FileReader(file);
|
||||
JsonObject obj = ClaimStorage.GSON.fromJson(reader, JsonObject.class);
|
||||
reader.close();
|
||||
if (obj == null)
|
||||
obj = new JsonObject();
|
||||
int additionalBlocks = obj.get("AdditionalBlocks").getAsInt();
|
||||
obj.addProperty("AdditionalBlocks", additionalBlocks + additionalClaimBlocks);
|
||||
FileWriter writer = new FileWriter(file);
|
||||
ClaimStorage.GSON.toJson(obj, writer);
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateUsedClaimBlocks() {
|
||||
this.usedClaimsBlocks = 0;
|
||||
for (ServerWorld world : this.player.getServer().getWorlds()) {
|
||||
Collection<Claim> claims = ClaimStorage.get(world).playerClaimMap.get(this.player.getUuid());
|
||||
if (claims != null)
|
||||
claims.forEach(claim -> this.usedClaimsBlocks += claim.getPlane());
|
||||
}
|
||||
}
|
||||
|
||||
public static void readGriefPreventionPlayerData(MinecraftServer server) {
|
||||
File griefPrevention = server.getSavePath(WorldSavePath.ROOT).resolve("GriefPreventionData/PlayerData").toFile();
|
||||
if (!griefPrevention.exists())
|
||||
return;
|
||||
try {
|
||||
for (File f : griefPrevention.listFiles()) {
|
||||
if (f.getName().startsWith("$")) {
|
||||
|
||||
} else {
|
||||
BufferedReader reader = new BufferedReader(new FileReader(f));
|
||||
PlayerEntity player = server.getPlayerManager().getPlayer(UUID.fromString(f.getName()));
|
||||
if (player != null) {
|
||||
PlayerClaimData data = PlayerClaimData.get(player);
|
||||
reader.readLine();
|
||||
data.claimBlocks = Integer.parseInt(reader.readLine());
|
||||
data.additionalClaimBlocks = Integer.parseInt(reader.readLine());
|
||||
} else {
|
||||
File dir = new File(server.getSavePath(WorldSavePath.PLAYERDATA).toFile(), "/claimData/");
|
||||
if (!dir.exists())
|
||||
dir.mkdir();
|
||||
File file = new File(dir, f.getName() + ".json");
|
||||
if (!file.exists())
|
||||
file.createNewFile();
|
||||
reader.readLine();
|
||||
FileWriter writer = new FileWriter(file);
|
||||
JsonObject obj = new JsonObject();
|
||||
obj.addProperty("ClaimBlocks", reader.readLine());
|
||||
obj.addProperty("AdditionalBlocks", reader.readLine());
|
||||
ClaimStorage.GSON.toJson(obj, writer);
|
||||
writer.close();
|
||||
}
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
BIN
src/main/resources/assets/flan/icon.png
Normal file
BIN
src/main/resources/assets/flan/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 453 B |
37
src/main/resources/fabric.mod.json
Normal file
37
src/main/resources/fabric.mod.json
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "flan",
|
||||
"version": "${version}",
|
||||
|
||||
"name": "Flan",
|
||||
"description": "A claiming mod for fabric",
|
||||
"authors": [
|
||||
"Flemmli97"
|
||||
],
|
||||
"contact": {
|
||||
"homepage": "",
|
||||
"sources": "https://github.com/FabricMC/fabric-example-mod"
|
||||
},
|
||||
|
||||
"license": "CC0-1.0",
|
||||
"icon": "assets/modid/icon.png",
|
||||
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"com.flemmli97.flan.Flan"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
"flan.mixins.json"
|
||||
],
|
||||
|
||||
"depends": {
|
||||
"fabricloader": ">=0.7.4",
|
||||
"fabric": "*",
|
||||
"minecraft": "1.16.x"
|
||||
},
|
||||
"suggests": {
|
||||
"flamingo": "*"
|
||||
}
|
||||
}
|
25
src/main/resources/flan.mixins.json
Normal file
25
src/main/resources/flan.mixins.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "com.flemmli97.flan.mixin",
|
||||
"compatibilityLevel": "JAVA_8",
|
||||
"mixins": [
|
||||
"PlayerClaimMixin",
|
||||
"WorldClaimMixin",
|
||||
"ServerPlayNetworkHandlerMixin",
|
||||
"AbstractBlockStateMixin",
|
||||
"EntityMixin",
|
||||
"ProjectileMixin",
|
||||
"TurtleEggMixin",
|
||||
"XpEntityMixin",
|
||||
"WitherMixin",
|
||||
"ExplosionMixin",
|
||||
"EnderPearlEntityMixin",
|
||||
"IPersistentProjectileVars"
|
||||
],
|
||||
"server": [
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user