From b80f0bed1d5eb3c2522529ae3ffd573f1ee30598 Mon Sep 17 00:00:00 2001 From: AlexProgrammerDE <40795980+AlexProgrammerDE@users.noreply.github.com> Date: Mon, 30 Dec 2024 12:48:14 +0100 Subject: [PATCH] Add email field --- proto/src/main/proto/soulfire/config.proto | 1 + proto/src/main/proto/soulfire/user.proto | 3 + .../launcher/SoulFireAbstractBootstrap.java | 78 +-- .../com/soulfiremc/server/SoulFireServer.java | 4 +- .../server/brigadier/ArgumentTypeHelper.java | 6 +- .../server/data/GsonDataHelper.java | 6 +- .../server/database/InstanceEntity.java | 44 +- .../server/database/UserEntity.java | 56 +- .../server/grpc/ConfigServiceImpl.java | 1 + .../server/grpc/UserServiceImpl.java | 3 + .../graph/actions/movement/BodyPart.java | 2 +- .../actions/movement/MovementModifier.java | 1 - .../server/protocol/bot/state/Level.java | 3 +- .../protocol/bot/state/entity/Entity.java | 508 +++++++++--------- .../bot/state/entity/LivingEntity.java | 36 +- .../bot/state/entity/LocalPlayer.java | 2 +- .../protocol/bot/state/entity/Player.java | 16 +- .../server/settings/BotSettings.java | 3 +- .../settings/property/ComboProperty.java | 16 +- .../soulfiremc/server/user/AuthSystem.java | 8 + .../soulfiremc/server/user/SoulFireUser.java | 2 + .../soulfiremc/server/util/MathHelper.java | 41 +- .../server/util/mcstructs/BlockHitResult.java | 8 +- .../server/util/mcstructs/Direction.java | 170 +++--- .../server/util/mcstructs/VecDeltaCodec.java | 26 +- 25 files changed, 534 insertions(+), 510 deletions(-) diff --git a/proto/src/main/proto/soulfire/config.proto b/proto/src/main/proto/soulfire/config.proto index 9e3de8b34..2ea0ff9cb 100644 --- a/proto/src/main/proto/soulfire/config.proto +++ b/proto/src/main/proto/soulfire/config.proto @@ -138,6 +138,7 @@ message ClientDataResponse { string id = 6; string username = 1; UserRole role = 7; + string email = 8; repeated GlobalPermissionState serverPermissions = 2; repeated ServerPlugin plugins = 3; repeated SettingsPage settings = 5; diff --git a/proto/src/main/proto/soulfire/user.proto b/proto/src/main/proto/soulfire/user.proto index 3c9697ce1..daed0b850 100644 --- a/proto/src/main/proto/soulfire/user.proto +++ b/proto/src/main/proto/soulfire/user.proto @@ -10,6 +10,7 @@ import "soulfire/common.proto"; message UserCreateRequest { string username = 1; UserRole role = 2; + string email = 3; } message UserCreateResponse { @@ -31,6 +32,7 @@ message UserListResponse { string id = 1; string username = 2; UserRole role = 3; + string email = 4; } repeated User users = 1; @@ -43,6 +45,7 @@ message UserInfoRequest { message UserInfoResponse { string username = 1; UserRole role = 2; + string email = 3; } service UserService { diff --git a/server/src/main/java/com/soulfiremc/launcher/SoulFireAbstractBootstrap.java b/server/src/main/java/com/soulfiremc/launcher/SoulFireAbstractBootstrap.java index 6eae62037..3ea01a4c6 100644 --- a/server/src/main/java/com/soulfiremc/launcher/SoulFireAbstractBootstrap.java +++ b/server/src/main/java/com/soulfiremc/launcher/SoulFireAbstractBootstrap.java @@ -105,6 +105,45 @@ public static void injectExceptionHandler() { }); } + public static void injectMixins(@Nullable PluginManager pluginManager) { + var mixinPaths = new HashSet(); + Stream.concat(pluginManager == null ? Stream.empty() : pluginManager + .getExtensions(MixinExtension.class) + .stream(), + Stream.of(new SFDefaultMixinExtension())) + .forEach( + mixinExtension -> { + for (var mixinPath : mixinExtension.getMixinPaths()) { + if (mixinPaths.add(mixinPath)) { + log.info("Added mixin \"{}\"", mixinPath); + } else { + log.warn("Mixin path \"{}\" is already added!", mixinPath); + } + } + }); + + var classLoaders = new ArrayList(); + classLoaders.add(SoulFireAbstractBootstrap.class.getClassLoader()); + if (pluginManager != null) { + pluginManager + .getPlugins() + .forEach(pluginWrapper -> classLoaders.add(pluginWrapper.getPluginClassLoader())); + } + + var classProvider = new CustomClassProvider(classLoaders); + var transformerManager = new TransformerManager(classProvider); + transformerManager.addTransformerPreprocessor(new MixinsTranslator()); + mixinPaths.forEach(transformerManager::addTransformer); + + try { + transformerManager.hookInstrumentation(Agents.getInstrumentation()); + log.info("Used Runtime Agent to inject mixins"); + } catch (IOException t) { + log.error("Failed to inject mixins", t); + throw new IllegalStateException("Failed to inject mixins", t); + } + } + private void initPlugins(List classLoaders) { try { Files.createDirectories(pluginsDirectory); @@ -168,45 +207,6 @@ public void injectMixinsAndRun(String[] args) { this.postMixinMain(args); } - public static void injectMixins(@Nullable PluginManager pluginManager) { - var mixinPaths = new HashSet(); - Stream.concat(pluginManager == null ? Stream.empty() : pluginManager - .getExtensions(MixinExtension.class) - .stream(), - Stream.of(new SFDefaultMixinExtension())) - .forEach( - mixinExtension -> { - for (var mixinPath : mixinExtension.getMixinPaths()) { - if (mixinPaths.add(mixinPath)) { - log.info("Added mixin \"{}\"", mixinPath); - } else { - log.warn("Mixin path \"{}\" is already added!", mixinPath); - } - } - }); - - var classLoaders = new ArrayList(); - classLoaders.add(SoulFireAbstractBootstrap.class.getClassLoader()); - if (pluginManager != null) { - pluginManager - .getPlugins() - .forEach(pluginWrapper -> classLoaders.add(pluginWrapper.getPluginClassLoader())); - } - - var classProvider = new CustomClassProvider(classLoaders); - var transformerManager = new TransformerManager(classProvider); - transformerManager.addTransformerPreprocessor(new MixinsTranslator()); - mixinPaths.forEach(transformerManager::addTransformer); - - try { - transformerManager.hookInstrumentation(Agents.getInstrumentation()); - log.info("Used Runtime Agent to inject mixins"); - } catch (IOException t) { - log.error("Failed to inject mixins", t); - throw new IllegalStateException("Failed to inject mixins", t); - } - } - protected abstract void postMixinMain(String[] args); protected abstract Path getBaseDirectory(); diff --git a/server/src/main/java/com/soulfiremc/server/SoulFireServer.java b/server/src/main/java/com/soulfiremc/server/SoulFireServer.java index 15e1fb399..9d54577cc 100644 --- a/server/src/main/java/com/soulfiremc/server/SoulFireServer.java +++ b/server/src/main/java/com/soulfiremc/server/SoulFireServer.java @@ -291,8 +291,8 @@ public UUID createInstance(String friendlyName, SoulFireUser owner) { public CompletableFuture shutdownInstances() { return CompletableFuture.allOf(instances.values().stream() - .map(InstanceManager::shutdownHook) - .toArray(CompletableFuture[]::new)); + .map(InstanceManager::shutdownHook) + .toArray(CompletableFuture[]::new)); } public Optional> deleteInstance(UUID id) { diff --git a/server/src/main/java/com/soulfiremc/server/brigadier/ArgumentTypeHelper.java b/server/src/main/java/com/soulfiremc/server/brigadier/ArgumentTypeHelper.java index 1cf8c71b6..55cfb6242 100644 --- a/server/src/main/java/com/soulfiremc/server/brigadier/ArgumentTypeHelper.java +++ b/server/src/main/java/com/soulfiremc/server/brigadier/ArgumentTypeHelper.java @@ -52,9 +52,6 @@ public static DoubleAxisData readAxis(StringReader reader) throws CommandSyntaxE return new DoubleAxisData(false, reader.readDouble()); } - public record DoubleAxisData(boolean relative, double value) { - } - public static OptionalInt parseEntityId(BotConnection bot, String input) { var dataManager = bot.dataManager(); @@ -78,4 +75,7 @@ public static OptionalInt parseEntityId(BotConnection bot, String input) { return OptionalInt.empty(); } + + public record DoubleAxisData(boolean relative, double value) { + } } diff --git a/server/src/main/java/com/soulfiremc/server/data/GsonDataHelper.java b/server/src/main/java/com/soulfiremc/server/data/GsonDataHelper.java index 41533dc9b..b43799ec3 100644 --- a/server/src/main/java/com/soulfiremc/server/data/GsonDataHelper.java +++ b/server/src/main/java/com/soulfiremc/server/data/GsonDataHelper.java @@ -32,7 +32,6 @@ import java.util.function.Function; public class GsonDataHelper { - private static final Map LOADED_DATA = new HashMap<>(); public static final TypeAdapter RESOURCE_KEY_ADAPTER = new TypeAdapter<>() { @Override @@ -47,7 +46,8 @@ public Key read(JsonReader in) throws IOException { return Key.key(key); } }; - private static final Function, Object>, Gson> GSON_FACTORY = (typeAdapters) -> { + private static final Map LOADED_DATA = new HashMap<>(); + private static final Function, Object>, Gson> GSON_FACTORY = (typeAdapters) -> { var builder = new GsonBuilder() .registerTypeAdapter(Key.class, RESOURCE_KEY_ADAPTER) .registerTypeAdapter(ByteDataComponents.class, ByteDataComponents.SERIALIZER); @@ -88,7 +88,7 @@ public static T fromJson(String dataFile, String dataKey, Class clazz, throw new RuntimeException("Failed to find data key %s in file %s".formatted(dataKey, dataFile)); } - public static Gson createGson(Map, Object> typeAdapters) { + public static Gson createGson(Map, Object> typeAdapters) { return GSON_FACTORY.apply(typeAdapters); } } diff --git a/server/src/main/java/com/soulfiremc/server/database/InstanceEntity.java b/server/src/main/java/com/soulfiremc/server/database/InstanceEntity.java index 33a7d541e..045331dd3 100644 --- a/server/src/main/java/com/soulfiremc/server/database/InstanceEntity.java +++ b/server/src/main/java/com/soulfiremc/server/database/InstanceEntity.java @@ -20,6 +20,7 @@ import com.soulfiremc.server.api.AttackLifecycle; import com.soulfiremc.server.settings.lib.InstanceSettingsImpl; import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.CreationTimestamp; @@ -33,33 +34,34 @@ @Entity @Table(name = "instances") public class InstanceEntity { - @Id - @GeneratedValue(strategy = GenerationType.UUID) - private UUID id; + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private UUID id; - @Column(nullable = false, unique = true, length = 32) - private String friendlyName; + @NotBlank(message = "Friendly name cannot be blank") + @Column(nullable = false, unique = true, length = 32) + private String friendlyName; - @ManyToOne - @JoinColumn(nullable = false) - private UserEntity owner; + @ManyToOne + @JoinColumn(nullable = false) + private UserEntity owner; - @Enumerated(EnumType.STRING) - @Column(nullable = false) - private AttackLifecycle attackLifecycle = AttackLifecycle.STOPPED; + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private AttackLifecycle attackLifecycle = AttackLifecycle.STOPPED; @Convert(converter = InstanceSettingsConverter.class) - @Column(nullable = false) - private InstanceSettingsImpl settings = InstanceSettingsImpl.EMPTY; + @Column(nullable = false) + private InstanceSettingsImpl settings = InstanceSettingsImpl.EMPTY; - @CreationTimestamp - @Column(nullable = false, updatable = false) - private Instant createdAt; + @CreationTimestamp + @Column(nullable = false, updatable = false) + private Instant createdAt; - @UpdateTimestamp - @Column(nullable = false) - private Instant updatedAt; + @UpdateTimestamp + @Column(nullable = false) + private Instant updatedAt; - @Version - private long version; + @Version + private long version; } diff --git a/server/src/main/java/com/soulfiremc/server/database/UserEntity.java b/server/src/main/java/com/soulfiremc/server/database/UserEntity.java index c8dda3456..32f2d9442 100644 --- a/server/src/main/java/com/soulfiremc/server/database/UserEntity.java +++ b/server/src/main/java/com/soulfiremc/server/database/UserEntity.java @@ -18,6 +18,8 @@ package com.soulfiremc.server.database; import jakarta.persistence.*; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; import org.hibernate.annotations.CreationTimestamp; @@ -31,36 +33,42 @@ @Entity @Table(name = "users") public class UserEntity { - @Id - @GeneratedValue(strategy = GenerationType.UUID) - private UUID id; + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private UUID id; - @Column(nullable = false, unique = true, length = 32) - private String username; + @NotBlank(message = "Username cannot be blank") + @Column(nullable = false, unique = true, length = 32) + private String username; - @Enumerated(EnumType.STRING) - @Column(nullable = false) - private Role role; + @NotBlank(message = "Email cannot be blank") + @Email(message = "Invalid email format") + @Column(nullable = false, unique = true) + private String email; - @CreationTimestamp - @Column(nullable = false, updatable = false) - private Instant createdAt; + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private Role role; - @UpdateTimestamp - @Column(nullable = false) - private Instant updatedAt; + @CreationTimestamp + @Column(nullable = false, updatable = false) + private Instant createdAt; - private Instant lastLoginAt; + @UpdateTimestamp + @Column(nullable = false) + private Instant updatedAt; - @CreationTimestamp - @Column(nullable = false) - private Instant minIssuedAt; + private Instant lastLoginAt; - @Version - private long version; + @CreationTimestamp + @Column(nullable = false) + private Instant minIssuedAt; - public enum Role { - USER, - ADMIN - } + @Version + private long version; + + public enum Role { + USER, + ADMIN + } } diff --git a/server/src/main/java/com/soulfiremc/server/grpc/ConfigServiceImpl.java b/server/src/main/java/com/soulfiremc/server/grpc/ConfigServiceImpl.java index 901602fdc..48d9b4c13 100644 --- a/server/src/main/java/com/soulfiremc/server/grpc/ConfigServiceImpl.java +++ b/server/src/main/java/com/soulfiremc/server/grpc/ConfigServiceImpl.java @@ -67,6 +67,7 @@ public void getClientData( ClientDataResponse.newBuilder() .setId(currentUSer.getUniqueId().toString()) .setUsername(currentUSer.getUsername()) + .setEmail(currentUSer.getEmail()) .setRole(switch (currentUSer.getRole()) { case ADMIN -> UserRole.ADMIN; case USER -> UserRole.USER; diff --git a/server/src/main/java/com/soulfiremc/server/grpc/UserServiceImpl.java b/server/src/main/java/com/soulfiremc/server/grpc/UserServiceImpl.java index dc500ee5f..90af25cb4 100644 --- a/server/src/main/java/com/soulfiremc/server/grpc/UserServiceImpl.java +++ b/server/src/main/java/com/soulfiremc/server/grpc/UserServiceImpl.java @@ -42,6 +42,7 @@ public void createUser(UserCreateRequest request, StreamObserver { var userEntity = new UserEntity(); userEntity.username(request.getUsername()); + userEntity.email(request.getEmail()); userEntity.role(switch (request.getRole()) { case ADMIN -> UserEntity.Role.ADMIN; case USER -> UserEntity.Role.USER; @@ -92,6 +93,7 @@ public void listUsers(UserListRequest request, StreamObserver .addAllUsers(users.stream().map(user -> UserListResponse.User.newBuilder() .setId(user.id().toString()) .setUsername(user.username()) + .setEmail(user.email()) .setRole(switch (user.role()) { case ADMIN -> UserRole.ADMIN; case USER -> UserRole.USER; @@ -118,6 +120,7 @@ public void getUserInfo(UserInfoRequest request, StreamObserver UserRole.ADMIN; case USER -> UserRole.USER; diff --git a/server/src/main/java/com/soulfiremc/server/pathfinding/graph/actions/movement/BodyPart.java b/server/src/main/java/com/soulfiremc/server/pathfinding/graph/actions/movement/BodyPart.java index aba5635bf..da31395ed 100644 --- a/server/src/main/java/com/soulfiremc/server/pathfinding/graph/actions/movement/BodyPart.java +++ b/server/src/main/java/com/soulfiremc/server/pathfinding/graph/actions/movement/BodyPart.java @@ -24,7 +24,7 @@ public enum BodyPart { HEAD { @Override - public SFVec3i offset(SFVec3i position) { + public SFVec3i offset(SFVec3i position) { return position.add(0, 1, 0); } }, diff --git a/server/src/main/java/com/soulfiremc/server/pathfinding/graph/actions/movement/MovementModifier.java b/server/src/main/java/com/soulfiremc/server/pathfinding/graph/actions/movement/MovementModifier.java index 9812251a5..a12056ae2 100644 --- a/server/src/main/java/com/soulfiremc/server/pathfinding/graph/actions/movement/MovementModifier.java +++ b/server/src/main/java/com/soulfiremc/server/pathfinding/graph/actions/movement/MovementModifier.java @@ -19,7 +19,6 @@ import com.soulfiremc.server.pathfinding.SFVec3i; import lombok.RequiredArgsConstructor; -import org.cloudburstmc.math.vector.Vector3d; @RequiredArgsConstructor public enum MovementModifier { diff --git a/server/src/main/java/com/soulfiremc/server/protocol/bot/state/Level.java b/server/src/main/java/com/soulfiremc/server/protocol/bot/state/Level.java index a9ee367b0..3fb6b529b 100644 --- a/server/src/main/java/com/soulfiremc/server/protocol/bot/state/Level.java +++ b/server/src/main/java/com/soulfiremc/server/protocol/bot/state/Level.java @@ -47,12 +47,11 @@ public class Level implements LevelHeightAccessor { private final boolean debug; private final int seaLevel; private final LevelData levelData; - - private boolean tickDayTime; protected float oRainLevel; protected float rainLevel; protected float oThunderLevel; protected float thunderLevel; + private boolean tickDayTime; public Level( TagsState tagsState, diff --git a/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/Entity.java b/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/Entity.java index f2cb76c40..e65918d8c 100644 --- a/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/Entity.java +++ b/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/Entity.java @@ -66,21 +66,38 @@ @Getter public class Entity { protected static final int FLAG_ONFIRE = 0; + protected static final int FLAG_GLOWING = 6; + protected static final int FLAG_FALL_FLYING = 7; private static final int FLAG_SHIFT_KEY_DOWN = 1; private static final int FLAG_SPRINTING = 3; private static final int FLAG_SWIMMING = 4; private static final int FLAG_INVISIBLE = 5; - protected static final int FLAG_GLOWING = 6; - protected static final int FLAG_FALL_FLYING = 7; private static final AABB INITIAL_AABB = new AABB(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); protected final EntityAttributeState attributeState = new EntityAttributeState(); protected final EntityEffectState effectState = new EntityEffectState(); protected final Set> fluidOnEyes = new HashSet<>(); - public int invulnerableTime; - protected Object2DoubleMap> fluidHeight = new Object2DoubleArrayMap<>(2); - private final VecDeltaCodec packetPositionCodec = new VecDeltaCodec(); protected final EntityType entityType; protected final EntityMetadataState metadataState; + private final VecDeltaCodec packetPositionCodec = new VecDeltaCodec(); + private final List movementThisTick = new ArrayList<>(); + private final Set blocksInside = new ReferenceArraySet<>(); + private final LongSet visitedBlocks = new LongOpenHashSet(); + private final int remainingFireTicks = -this.getFireImmuneTicks(); + private final ImmutableList passengers = ImmutableList.of(); + public int invulnerableTime; + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + public Optional mainSupportingBlockPos = Optional.empty(); + public double xo; + public double yo; + public double zo; + public double xOld; + public double yOld; + public double zOld; + public float yRotO; + public float xRotO; + public boolean noPhysics; + public boolean hasImpulse; + protected Object2DoubleMap> fluidHeight = new Object2DoubleArrayMap<>(2); protected float fallDistance; @Setter protected UUID uuid = UUID.randomUUID(); @@ -92,46 +109,29 @@ public class Entity { protected Level level; protected BlockState inBlockState = null; protected boolean firstTick = true; - @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - public Optional mainSupportingBlockPos = Optional.empty(); - private boolean onGroundNoBlocks = false; - private Vector3d pos; protected Vector3d deltaMovement = Vector3d.ZERO; protected float yRot; protected float xRot; - private final List movementThisTick = new ArrayList<>(); - private final Set blocksInside = new ReferenceArraySet<>(); - private final LongSet visitedBlocks = new LongOpenHashSet(); - public double xo; - public double yo; - public double zo; - public double xOld; - public double yOld; protected float headYRot; protected boolean onGround; protected boolean horizontalCollision; protected boolean verticalCollision; protected boolean verticalCollisionBelow; protected boolean minorHorizontalCollision; - public double zOld; protected boolean wasInPowderSnow; protected boolean wasTouchingWater; protected boolean wasEyeInWater; + @Setter + protected boolean isInPowderSnow; + protected Vector3d stuckSpeedMultiplier = Vector3d.ZERO; + private boolean onGroundNoBlocks = false; + private Vector3d pos; private Vector3i blockPosition; private ChunkKey chunkPosition; private EntityDimensions dimensions; private float eyeHeight; private AABB bb = INITIAL_AABB; private int portalCooldown; - public float yRotO; - public float xRotO; - @Setter - protected boolean isInPowderSnow; - protected Vector3d stuckSpeedMultiplier = Vector3d.ZERO; - public boolean noPhysics; - public boolean hasImpulse; - private final int remainingFireTicks = -this.getFireImmuneTicks(); - private final ImmutableList passengers = ImmutableList.of(); @Nullable private Entity vehicle; @@ -155,6 +155,229 @@ public Entity(EntityType entityType, Level level) { this.eyeHeight = entityType.dimensions().eyeHeight(); } + private static float[] collectCandidateStepUpHeights(AABB box, List colliders, float deltaY, float maxUpStep) { + FloatSet floatSet = new FloatArraySet(4); + + for (var collider : colliders) { + var doubleList = collider.getCoords(Direction.Axis.Y); + for (double coord : doubleList) { + var h = (float) (coord - box.minY); + if (!(h < 0.0F) && h != maxUpStep) { + if (h > deltaY) { + break; + } + + floatSet.add(h); + } + } + } + + var fs = floatSet.toFloatArray(); + FloatArrays.unstableSort(fs); + return fs; + } + + static Iterable boxTraverseBlocks(Vector3d from, Vector3d to, AABB bb) { + var length = to.sub(from); + var iterable = betweenClosed(bb); + if (length.lengthSquared() < (double) MathHelper.square(0.99999F)) { + return iterable; + } else { + Set set = new ObjectLinkedOpenHashSet<>(); + var normalizedLength = length.normalize().mul(1.0E-7); + var offsetMin = bb.getMinPosition().add(normalizedLength); + var lv4 = bb.getMinPosition().sub(length).sub(normalizedLength); + addCollisionsAlongTravel(set, lv4, offsetMin, bb); + + for (var pos : iterable) { + set.add(pos); + } + + return set; + } + } + + private static void addCollisionsAlongTravel(Set set, Vector3d from, Vector3d to, AABB bb) { + var length = to.sub(from); + var startX = MathHelper.floor(from.getX()); + var startY = MathHelper.floor(from.getY()); + var startZ = MathHelper.floor(from.getZ()); + var l = MathHelper.sign(length.getX()); + var m = MathHelper.sign(length.getY()); + var n = MathHelper.sign(length.getZ()); + var d = l == 0 ? Double.MAX_VALUE : (double) l / length.getX(); + var e = m == 0 ? Double.MAX_VALUE : (double) m / length.getY(); + var f = n == 0 ? Double.MAX_VALUE : (double) n / length.getZ(); + var g = d * (l > 0 ? 1.0 - MathHelper.frac(from.getX()) : MathHelper.frac(from.getX())); + var h = e * (m > 0 ? 1.0 - MathHelper.frac(from.getY()) : MathHelper.frac(from.getY())); + var o = f * (n > 0 ? 1.0 - MathHelper.frac(from.getZ()) : MathHelper.frac(from.getZ())); + var p = 0; + + while (g <= 1.0 || h <= 1.0 || o <= 1.0) { + if (g < h) { + if (g < o) { + startX += l; + g += d; + } else { + startZ += n; + o += f; + } + } else if (h < o) { + startY += m; + h += e; + } else { + startZ += n; + o += f; + } + + if (p++ > 16) { + break; + } + + var optional = AABB.clip(startX, startY, startZ, startX + 1, startY + 1, startZ + 1, from, to); + if (optional.isPresent()) { + var lv2 = optional.get(); + var xClamp = MathHelper.clamp(lv2.getX(), (double) startX + 1.0E-5F, (double) startX + 1.0 - 1.0E-5F); + var yClamp = MathHelper.clamp(lv2.getY(), (double) startY + 1.0E-5F, (double) startY + 1.0 - 1.0E-5F); + var zClamp = MathHelper.clamp(lv2.getZ(), (double) startZ + 1.0E-5F, (double) startZ + 1.0 - 1.0E-5F); + var endX = MathHelper.floor(xClamp + bb.getXsize()); + var endY = MathHelper.floor(yClamp + bb.getYsize()); + var endZ = MathHelper.floor(zClamp + bb.getZsize()); + + for (var x = startX; x <= endX; x++) { + for (var y = startY; y <= endY; y++) { + for (var z = startZ; z <= endZ; z++) { + set.add(Vector3i.from(x, y, z)); + } + } + } + } + } + } + + public static Iterable betweenClosed(AABB arg) { + var lv = Vector3i.from(arg.minX, arg.minY, arg.minZ); + var lv2 = Vector3i.from(arg.maxX, arg.maxY, arg.maxZ); + return betweenClosed(lv, lv2); + } + + public static Iterable betweenClosed(Vector3i firstPos, Vector3i secondPos) { + return betweenClosed( + Math.min(firstPos.getX(), secondPos.getX()), + Math.min(firstPos.getY(), secondPos.getY()), + Math.min(firstPos.getZ(), secondPos.getZ()), + Math.max(firstPos.getX(), secondPos.getX()), + Math.max(firstPos.getY(), secondPos.getY()), + Math.max(firstPos.getZ(), secondPos.getZ()) + ); + } + + public static Iterable betweenClosed(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + var o = maxX - minX + 1; + var p = maxY - minY + 1; + var q = maxZ - minZ + 1; + var r = o * p * q; + return () -> new AbstractIterator<>() { + private int index; + + protected Vector3i computeNext() { + if (this.index == r) { + return this.endOfData(); + } else { + var i = this.index % o; + var j = this.index / o; + var k = j % p; + var l = j / p; + this.index++; + return Vector3i.from(minX + i, minY + k, minZ + l); + } + } + }; + } + + public static Vector3d collideBoundingBox(@Nullable Entity entity, Vector3d vec, AABB collisionBox, Level level, List potentialHits) { + var list2 = collectColliders(entity, level, potentialHits, collisionBox.expandTowards(vec)); + return collideWithShapes(vec, collisionBox, list2); + } + + private static List collectColliders(@Nullable Entity entity, Level level, List collisions, AABB boundingBox) { + ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(collisions.size() + 1); + if (!collisions.isEmpty()) { + builder.addAll(collisions); + } + + // TODO: WorldBorder + // WorldBorder lv = level.getWorldBorder(); + // boolean bl = entity != null && lv.isInsideCloseToBorder(entity, boundingBox); + // if (bl) { + // builder.add(lv.getCollisionShape()); + // } + + builder.addAll(level.getBlockCollisionBoxes(boundingBox)); + return builder.build(); + } + + public static double collide(Direction.Axis movementAxis, AABB collisionBox, Iterable possibleHits, double desiredOffset) { + for (var hit : possibleHits) { + if (Math.abs(desiredOffset) < 1.0E-7) { + return 0.0; + } + + desiredOffset = hit.collide(movementAxis, collisionBox, desiredOffset); + } + + return desiredOffset; + } + + private static Vector3d collideWithShapes(Vector3d deltaMovement, AABB entityBB, List shapes) { + if (shapes.isEmpty()) { + return deltaMovement; + } else { + var x = deltaMovement.getX(); + var y = deltaMovement.getY(); + var z = deltaMovement.getZ(); + if (y != 0.0) { + y = collide(Direction.Axis.Y, entityBB, shapes, y); + if (y != 0.0) { + entityBB = entityBB.move(0.0, y, 0.0); + } + } + + var bl = Math.abs(x) < Math.abs(z); + if (bl && z != 0.0) { + z = collide(Direction.Axis.Z, entityBB, shapes, z); + if (z != 0.0) { + entityBB = entityBB.move(0.0, 0.0, z); + } + } + + if (x != 0.0) { + x = collide(Direction.Axis.X, entityBB, shapes, x); + if (!bl && x != 0.0) { + entityBB = entityBB.move(x, 0.0, 0.0); + } + } + + if (!bl && z != 0.0) { + z = collide(Direction.Axis.Z, entityBB, shapes, z); + } + + return Vector3d.from(x, y, z); + } + } + + protected static Vector3d getInputVector(Vector3d relative, float motionScale, float facing) { + var d = relative.lengthSquared(); + if (d < 1.0E-7) { + return Vector3d.ZERO; + } else { + var scaledMotion = (d > 1.0 ? relative.normalize() : relative).mul((double) motionScale); + var h = MathHelper.sin(facing * (float) (Math.PI / 180.0)); + var i = MathHelper.cos(facing * (float) (Math.PI / 180.0)); + return Vector3d.from(scaledMotion.getX() * (double) i - scaledMotion.getZ() * (double) h, scaledMotion.getY(), scaledMotion.getZ() * (double) i + scaledMotion.getX() * (double) h); + } + } + public void fromAddEntityPacket(ClientboundAddEntityPacket packet) { var x = packet.getX(); var y = packet.getY(); @@ -371,6 +594,10 @@ protected Vector3d getDeltaMovement() { return deltaMovement; } + public void setDeltaMovement(Vector3d deltaMovement) { + this.deltaMovement = deltaMovement; + } + protected boolean getSharedFlag(int flag) { return (this.metadataState.getMetadata(NamedEntityData.ENTITY__SHARED_FLAGS, MetadataType.BYTE) & 1 << flag) != 0; } @@ -443,146 +670,6 @@ public double attributeValue(AttributeType type) { return attributeState.getOrCreateAttribute(type).calculateValue(); } - private static float[] collectCandidateStepUpHeights(AABB box, List colliders, float deltaY, float maxUpStep) { - FloatSet floatSet = new FloatArraySet(4); - - for (var collider : colliders) { - var doubleList = collider.getCoords(Direction.Axis.Y); - for (double coord : doubleList) { - var h = (float) (coord - box.minY); - if (!(h < 0.0F) && h != maxUpStep) { - if (h > deltaY) { - break; - } - - floatSet.add(h); - } - } - } - - var fs = floatSet.toFloatArray(); - FloatArrays.unstableSort(fs); - return fs; - } - - static Iterable boxTraverseBlocks(Vector3d from, Vector3d to, AABB bb) { - var length = to.sub(from); - var iterable = betweenClosed(bb); - if (length.lengthSquared() < (double) MathHelper.square(0.99999F)) { - return iterable; - } else { - Set set = new ObjectLinkedOpenHashSet<>(); - var normalizedLength = length.normalize().mul(1.0E-7); - var offsetMin = bb.getMinPosition().add(normalizedLength); - var lv4 = bb.getMinPosition().sub(length).sub(normalizedLength); - addCollisionsAlongTravel(set, lv4, offsetMin, bb); - - for (var pos : iterable) { - set.add(pos); - } - - return set; - } - } - - private static void addCollisionsAlongTravel(Set set, Vector3d from, Vector3d to, AABB bb) { - var length = to.sub(from); - var startX = MathHelper.floor(from.getX()); - var startY = MathHelper.floor(from.getY()); - var startZ = MathHelper.floor(from.getZ()); - var l = MathHelper.sign(length.getX()); - var m = MathHelper.sign(length.getY()); - var n = MathHelper.sign(length.getZ()); - var d = l == 0 ? Double.MAX_VALUE : (double) l / length.getX(); - var e = m == 0 ? Double.MAX_VALUE : (double) m / length.getY(); - var f = n == 0 ? Double.MAX_VALUE : (double) n / length.getZ(); - var g = d * (l > 0 ? 1.0 - MathHelper.frac(from.getX()) : MathHelper.frac(from.getX())); - var h = e * (m > 0 ? 1.0 - MathHelper.frac(from.getY()) : MathHelper.frac(from.getY())); - var o = f * (n > 0 ? 1.0 - MathHelper.frac(from.getZ()) : MathHelper.frac(from.getZ())); - var p = 0; - - while (g <= 1.0 || h <= 1.0 || o <= 1.0) { - if (g < h) { - if (g < o) { - startX += l; - g += d; - } else { - startZ += n; - o += f; - } - } else if (h < o) { - startY += m; - h += e; - } else { - startZ += n; - o += f; - } - - if (p++ > 16) { - break; - } - - var optional = AABB.clip(startX, startY, startZ, startX + 1, startY + 1, startZ + 1, from, to); - if (optional.isPresent()) { - var lv2 = optional.get(); - var xClamp = MathHelper.clamp(lv2.getX(), (double) startX + 1.0E-5F, (double) startX + 1.0 - 1.0E-5F); - var yClamp = MathHelper.clamp(lv2.getY(), (double) startY + 1.0E-5F, (double) startY + 1.0 - 1.0E-5F); - var zClamp = MathHelper.clamp(lv2.getZ(), (double) startZ + 1.0E-5F, (double) startZ + 1.0 - 1.0E-5F); - var endX = MathHelper.floor(xClamp + bb.getXsize()); - var endY = MathHelper.floor(yClamp + bb.getYsize()); - var endZ = MathHelper.floor(zClamp + bb.getZsize()); - - for (var x = startX; x <= endX; x++) { - for (var y = startY; y <= endY; y++) { - for (var z = startZ; z <= endZ; z++) { - set.add(Vector3i.from(x, y, z)); - } - } - } - } - } - } - - public static Iterable betweenClosed(AABB arg) { - var lv = Vector3i.from(arg.minX, arg.minY, arg.minZ); - var lv2 = Vector3i.from(arg.maxX, arg.maxY, arg.maxZ); - return betweenClosed(lv, lv2); - } - - public static Iterable betweenClosed(Vector3i firstPos, Vector3i secondPos) { - return betweenClosed( - Math.min(firstPos.getX(), secondPos.getX()), - Math.min(firstPos.getY(), secondPos.getY()), - Math.min(firstPos.getZ(), secondPos.getZ()), - Math.max(firstPos.getX(), secondPos.getX()), - Math.max(firstPos.getY(), secondPos.getY()), - Math.max(firstPos.getZ(), secondPos.getZ()) - ); - } - - public static Iterable betweenClosed(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { - var o = maxX - minX + 1; - var p = maxY - minY + 1; - var q = maxZ - minZ + 1; - var r = o * p * q; - return () -> new AbstractIterator<>() { - private int index; - - protected Vector3i computeNext() { - if (this.index == r) { - return this.endOfData(); - } else { - var i = this.index % o; - var j = this.index / o; - var k = j % p; - var l = j / p; - this.index++; - return Vector3i.from(minX + i, minY + k, minZ + l); - } - } - }; - } - public final Vector3d calculateViewVector(float xRot, float yRot) { var h = xRot * (float) (Math.PI / 180.0); var i = -yRot * (float) (Math.PI / 180.0); @@ -593,89 +680,6 @@ public final Vector3d calculateViewVector(float xRot, float yRot) { return Vector3d.from(k * l, -m, (double) (j * l)); } - public static Vector3d collideBoundingBox(@Nullable Entity entity, Vector3d vec, AABB collisionBox, Level level, List potentialHits) { - var list2 = collectColliders(entity, level, potentialHits, collisionBox.expandTowards(vec)); - return collideWithShapes(vec, collisionBox, list2); - } - - private static List collectColliders(@Nullable Entity entity, Level level, List collisions, AABB boundingBox) { - ImmutableList.Builder builder = ImmutableList.builderWithExpectedSize(collisions.size() + 1); - if (!collisions.isEmpty()) { - builder.addAll(collisions); - } - - // TODO: WorldBorder - // WorldBorder lv = level.getWorldBorder(); - // boolean bl = entity != null && lv.isInsideCloseToBorder(entity, boundingBox); - // if (bl) { - // builder.add(lv.getCollisionShape()); - // } - - builder.addAll(level.getBlockCollisionBoxes(boundingBox)); - return builder.build(); - } - - public static double collide(Direction.Axis movementAxis, AABB collisionBox, Iterable possibleHits, double desiredOffset) { - for (var hit : possibleHits) { - if (Math.abs(desiredOffset) < 1.0E-7) { - return 0.0; - } - - desiredOffset = hit.collide(movementAxis, collisionBox, desiredOffset); - } - - return desiredOffset; - } - - private static Vector3d collideWithShapes(Vector3d deltaMovement, AABB entityBB, List shapes) { - if (shapes.isEmpty()) { - return deltaMovement; - } else { - var x = deltaMovement.getX(); - var y = deltaMovement.getY(); - var z = deltaMovement.getZ(); - if (y != 0.0) { - y = collide(Direction.Axis.Y, entityBB, shapes, y); - if (y != 0.0) { - entityBB = entityBB.move(0.0, y, 0.0); - } - } - - var bl = Math.abs(x) < Math.abs(z); - if (bl && z != 0.0) { - z = collide(Direction.Axis.Z, entityBB, shapes, z); - if (z != 0.0) { - entityBB = entityBB.move(0.0, 0.0, z); - } - } - - if (x != 0.0) { - x = collide(Direction.Axis.X, entityBB, shapes, x); - if (!bl && x != 0.0) { - entityBB = entityBB.move(x, 0.0, 0.0); - } - } - - if (!bl && z != 0.0) { - z = collide(Direction.Axis.Z, entityBB, shapes, z); - } - - return Vector3d.from(x, y, z); - } - } - - protected static Vector3d getInputVector(Vector3d relative, float motionScale, float facing) { - var d = relative.lengthSquared(); - if (d < 1.0E-7) { - return Vector3d.ZERO; - } else { - var scaledMotion = (d > 1.0 ? relative.normalize() : relative).mul((double) motionScale); - var h = MathHelper.sin(facing * (float) (Math.PI / 180.0)); - var i = MathHelper.cos(facing * (float) (Math.PI / 180.0)); - return Vector3d.from(scaledMotion.getX() * (double) i - scaledMotion.getZ() * (double) h, scaledMotion.getY(), scaledMotion.getZ() * (double) i + scaledMotion.getX() * (double) h); - } - } - public final void setOldPosAndRot() { this.setOldPos(); this.setOldRot(); @@ -944,10 +948,6 @@ protected void setSharedFlag(int flag, boolean set) { } } - public void setDeltaMovement(Vector3d deltaMovement) { - this.deltaMovement = deltaMovement; - } - public boolean isNoGravity() { return this.metadataState.getMetadata(NamedEntityData.ENTITY__NO_GRAVITY, MetadataType.BOOLEAN); } diff --git a/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/LivingEntity.java b/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/LivingEntity.java index 45132b86d..bade28532 100644 --- a/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/LivingEntity.java +++ b/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/LivingEntity.java @@ -44,21 +44,22 @@ @Getter public abstract class LivingEntity extends Entity { + protected static final EntityDimensions SLEEPING_DIMENSIONS = EntityDimensions.fixed(0.2F, 0.2F).withEyeHeight(0.2F); private static final Key SPEED_MODIFIER_POWDER_SNOW_ID = Key.key("powder_snow"); private static final Key SPRINTING_MODIFIER_ID = Key.key("sprinting"); private static final AttributeModifier SPEED_MODIFIER_SPRINTING = new AttributeModifier( SPRINTING_MODIFIER_ID, 0.3F, ModifierOperation.ADD_MULTIPLIED_TOTAL ); - protected static final EntityDimensions SLEEPING_DIMENSIONS = EntityDimensions.fixed(0.2F, 0.2F).withEyeHeight(0.2F); - protected int fallFlyTicks; - protected float appliedScale = 1.0F; + private final boolean discardFriction = false; public float xxa; public float yya; public float zza; + public int hurtTime; + public int hurtDuration; + public int deathTime; + protected int fallFlyTicks; + protected float appliedScale = 1.0F; protected boolean jumping; - private int noJumpDelay; - private float speed; - private final boolean discardFriction = false; protected int lerpSteps; protected double lerpX; protected double lerpY; @@ -67,10 +68,9 @@ public abstract class LivingEntity extends Entity { protected double lerpXRot; protected double lerpYHeadRot; protected int lerpHeadSteps; - public int hurtTime; - public int hurtDuration; - public int deathTime; protected float lastHurt; + private int noJumpDelay; + private float speed; @SuppressWarnings("OptionalUsedAsFieldOrParameterType") private Optional lastClimbablePos = Optional.empty(); @@ -81,6 +81,15 @@ public LivingEntity(EntityType entityType, Level level) { this.setYRot((float) (Math.random() * (float) (Math.PI * 2))); } + public static boolean canGlideUsing(SFItemStack stack, EquipmentSlot slow) { + if (!stack.has(DataComponentType.GLIDER)) { + return false; + } else { + var equippable = stack.get(DataComponentType.EQUIPPABLE); + return equippable != null && slow == EquipmentSlot.fromMCPl(equippable.slot()) && !stack.nextDamageWillBreak(); + } + } + @Override public void tick() { super.tick(); @@ -132,15 +141,6 @@ public void handleEntityEvent(EntityEvent event) { } } - public static boolean canGlideUsing(SFItemStack stack, EquipmentSlot slow) { - if (!stack.has(DataComponentType.GLIDER)) { - return false; - } else { - var equippable = stack.get(DataComponentType.EQUIPPABLE); - return equippable != null && slow == EquipmentSlot.fromMCPl(equippable.slot()) && !stack.nextDamageWillBreak(); - } - } - @Override public void fromAddEntityPacket(ClientboundAddEntityPacket packet) { var x = packet.getX(); diff --git a/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/LocalPlayer.java b/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/LocalPlayer.java index 8e72bbc29..4309db582 100644 --- a/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/LocalPlayer.java +++ b/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/LocalPlayer.java @@ -48,6 +48,7 @@ public class LocalPlayer extends AbstractClientPlayer { private final BotConnection connection; private final InputState input; + protected int sprintTriggerTime; private int permissionLevel; private double lastX = 0; private double lastY = 0; @@ -59,7 +60,6 @@ public class LocalPlayer extends AbstractClientPlayer { private boolean wasShiftKeyDown; private boolean wasSprinting; private boolean noPhysics = false; - protected int sprintTriggerTime; private boolean crouching; private int positionReminder = 0; private boolean wasFallFlying; diff --git a/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/Player.java b/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/Player.java index 5b3e030a3..ce028318a 100644 --- a/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/Player.java +++ b/server/src/main/java/com/soulfiremc/server/protocol/bot/state/entity/Player.java @@ -43,11 +43,6 @@ @SuppressWarnings("OptionalUsedAsFieldOrParameterType") public abstract class Player extends LivingEntity { - @Getter - private final PlayerInventoryContainer inventory = new PlayerInventoryContainer(); - @Getter - private final AbilitiesState abilitiesState = new AbilitiesState(); - protected FoodData foodData = new FoodData(); public static final float CROUCH_BB_HEIGHT = 1.5F; public static final float SWIMMING_BB_WIDTH = 0.6F; public static final float SWIMMING_BB_HEIGHT = 0.6F; @@ -64,14 +59,19 @@ public abstract class Player extends LivingEntity { .put(Pose.DYING, EntityDimensions.fixed(0.2F, 0.2F).withEyeHeight(DEFAULT_EYE_HEIGHT)) .build(); public static final int CLIENT_LOADED_TIMEOUT_TIME = 60; + protected final GameProfile gameProfile; + protected final float defaultFlySpeed = 0.02F; + @Getter + private final PlayerInventoryContainer inventory = new PlayerInventoryContainer(); + @Getter + private final AbilitiesState abilitiesState = new AbilitiesState(); public int experienceLevel; public int totalExperience; public float experienceProgress; - protected final GameProfile gameProfile; + protected FoodData foodData = new FoodData(); protected boolean wasUnderwater = false; - private boolean reducedDebugInfo; - protected final float defaultFlySpeed = 0.02F; protected int clientLoadedTimeoutTimer = CLIENT_LOADED_TIMEOUT_TIME; + private boolean reducedDebugInfo; private boolean clientLoaded = false; private Optional lastDeathLocation = Optional.empty(); diff --git a/server/src/main/java/com/soulfiremc/server/settings/BotSettings.java b/server/src/main/java/com/soulfiremc/server/settings/BotSettings.java index ed12232b5..a01178c04 100644 --- a/server/src/main/java/com/soulfiremc/server/settings/BotSettings.java +++ b/server/src/main/java/com/soulfiremc/server/settings/BotSettings.java @@ -30,7 +30,6 @@ @NoArgsConstructor(access = AccessLevel.PRIVATE) public class BotSettings implements SettingsObject { - private static final String NAMESPACE = "bot"; public static final Function PROTOCOL_VERSION_PARSER = version -> { var split = version.split("\\|"); @@ -40,7 +39,7 @@ public class BotSettings implements SettingsObject { return ProtocolVersion.getProtocol(VersionType.valueOf(split[0]), Integer.parseInt(split[1])); }; - + private static final String NAMESPACE = "bot"; public static final StringProperty ADDRESS = ImmutableStringProperty.builder() .namespace(NAMESPACE) diff --git a/server/src/main/java/com/soulfiremc/server/settings/property/ComboProperty.java b/server/src/main/java/com/soulfiremc/server/settings/property/ComboProperty.java index 51021b7e9..69462b31a 100644 --- a/server/src/main/java/com/soulfiremc/server/settings/property/ComboProperty.java +++ b/server/src/main/java/com/soulfiremc/server/settings/property/ComboProperty.java @@ -42,14 +42,6 @@ private static String capitalizeString(String str) { return str.substring(0, 1).toUpperCase(Locale.ROOT) + str.substring(1).toLowerCase(Locale.ROOT); } - public abstract String key(); - - public abstract String uiName(); - - public abstract String description(); - - public abstract List options(); - public static > String capitalizeEnum(T enumValue) { return String.join( " ", @@ -58,6 +50,14 @@ public static > String capitalizeEnum(T enumValue) { .toArray(String[]::new)); } + public abstract String key(); + + public abstract String uiName(); + + public abstract String description(); + + public abstract List options(); + public abstract String defaultValue(); @Value.Check diff --git a/server/src/main/java/com/soulfiremc/server/user/AuthSystem.java b/server/src/main/java/com/soulfiremc/server/user/AuthSystem.java index a2f1d7a2e..53d69253f 100644 --- a/server/src/main/java/com/soulfiremc/server/user/AuthSystem.java +++ b/server/src/main/java/com/soulfiremc/server/user/AuthSystem.java @@ -58,11 +58,13 @@ private UUID createRootUser() { var rootUser = new UserEntity(); rootUser.username("root"); rootUser.role(UserEntity.Role.ADMIN); + rootUser.email("root@soulfiremc.com"); s.persist(rootUser); return rootUser.id(); } else { currentRootUser.role(UserEntity.Role.ADMIN); + currentRootUser.email("root@soulfiremc.com"); s.merge(currentRootUser); return currentRootUser.id(); @@ -121,6 +123,12 @@ public String getUsername() { return userData.username(); } + @Override + public String getEmail() { + return userData.email(); + } + + @Override public UserEntity.Role getRole() { return userData.role(); } diff --git a/server/src/main/java/com/soulfiremc/server/user/SoulFireUser.java b/server/src/main/java/com/soulfiremc/server/user/SoulFireUser.java index 5f05d2af9..5d2fb9b21 100644 --- a/server/src/main/java/com/soulfiremc/server/user/SoulFireUser.java +++ b/server/src/main/java/com/soulfiremc/server/user/SoulFireUser.java @@ -26,6 +26,8 @@ public interface SoulFireUser extends ServerCommandSource { String getUsername(); + String getEmail(); + UserEntity.Role getRole(); @Override diff --git a/server/src/main/java/com/soulfiremc/server/util/MathHelper.java b/server/src/main/java/com/soulfiremc/server/util/MathHelper.java index c1ebbc958..34e0bb672 100644 --- a/server/src/main/java/com/soulfiremc/server/util/MathHelper.java +++ b/server/src/main/java/com/soulfiremc/server/util/MathHelper.java @@ -25,6 +25,26 @@ import java.util.stream.IntStream; public class MathHelper { + private static final float[] SIN = SFHelpers.make(new float[65536], fs -> { + for (var ix = 0; ix < fs.length; ix++) { + fs[ix] = (float) Math.sin((double) ix * Math.PI * 2.0 / 65536.0); + } + }); + private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{ + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; + private static final double FRAC_BIAS = Double.longBitsToDouble(4805340802404319232L); + private static final double[] ASIN_TAB = new double[257]; + private static final double[] COS_TAB = new double[257]; + + static { + for (var i = 0; i < 257; i++) { + var d = (double) i / 256.0; + var e = Math.asin(d); + COS_TAB[i] = Math.cos(e); + ASIN_TAB[i] = e; + } + } private MathHelper() {} public static boolean isOutsideTolerance(double a, double b, double tolerance) { @@ -56,27 +76,6 @@ public static int sumCapOverflow(IntStream stream) { return stream.reduce(0, MathHelper::sumCapOverflow); } - private static final float[] SIN = SFHelpers.make(new float[65536], fs -> { - for (var ix = 0; ix < fs.length; ix++) { - fs[ix] = (float) Math.sin((double) ix * Math.PI * 2.0 / 65536.0); - } - }); - private static final int[] MULTIPLY_DE_BRUIJN_BIT_POSITION = new int[]{ - 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 - }; - private static final double FRAC_BIAS = Double.longBitsToDouble(4805340802404319232L); - private static final double[] ASIN_TAB = new double[257]; - private static final double[] COS_TAB = new double[257]; - - static { - for (var i = 0; i < 257; i++) { - var d = (double) i / 256.0; - var e = Math.asin(d); - COS_TAB[i] = Math.cos(e); - ASIN_TAB[i] = e; - } - } - public static float sin(float value) { return SIN[(int) (value * 10430.378F) & 65535]; } diff --git a/server/src/main/java/com/soulfiremc/server/util/mcstructs/BlockHitResult.java b/server/src/main/java/com/soulfiremc/server/util/mcstructs/BlockHitResult.java index 66457933d..31badc9ce 100644 --- a/server/src/main/java/com/soulfiremc/server/util/mcstructs/BlockHitResult.java +++ b/server/src/main/java/com/soulfiremc/server/util/mcstructs/BlockHitResult.java @@ -27,10 +27,6 @@ public class BlockHitResult extends HitResult { private final boolean inside; private final boolean worldBorderHit; - public static BlockHitResult miss(Vector3d location, Direction direction, Vector3i pos) { - return new BlockHitResult(true, location, direction, pos, false, false); - } - public BlockHitResult(Vector3d arg, Direction arg2, Vector3i arg3, boolean bl) { this(false, arg, arg2, arg3, bl, false); } @@ -48,6 +44,10 @@ private BlockHitResult(boolean bl, Vector3d arg, Direction arg2, Vector3i arg3, this.worldBorderHit = bl3; } + public static BlockHitResult miss(Vector3d location, Direction direction, Vector3i pos) { + return new BlockHitResult(true, location, direction, pos, false, false); + } + public BlockHitResult withDirection(Direction newFace) { return new BlockHitResult(this.miss, this.location, newFace, this.blockPos, this.inside, this.worldBorderHit); } diff --git a/server/src/main/java/com/soulfiremc/server/util/mcstructs/Direction.java b/server/src/main/java/com/soulfiremc/server/util/mcstructs/Direction.java index b53913153..3cf473f89 100644 --- a/server/src/main/java/com/soulfiremc/server/util/mcstructs/Direction.java +++ b/server/src/main/java/com/soulfiremc/server/util/mcstructs/Direction.java @@ -39,6 +39,12 @@ public enum Direction { WEST(4, 5, 1, "west", Direction.AxisDirection.NEGATIVE, Direction.Axis.X, Vector3i.from(-1, 0, 0)), EAST(5, 4, 3, "east", Direction.AxisDirection.POSITIVE, Direction.Axis.X, Vector3i.from(1, 0, 0)); + private static final Direction[] VALUES = values(); + private static final Direction[] BY_3D_DATA = Arrays.stream(VALUES).sorted(Comparator.comparingInt(arg -> arg.data3d)).toArray(Direction[]::new); + private static final Direction[] BY_2D_DATA = Arrays.stream(VALUES) + .filter(arg -> arg.getAxis().isHorizontal()) + .sorted(Comparator.comparingInt(arg -> arg.data2d)) + .toArray(Direction[]::new); private final int data3d; private final int oppositeIndex; private final int data2d; @@ -46,12 +52,6 @@ public enum Direction { private final Direction.Axis axis; private final Direction.AxisDirection axisDirection; private final Vector3i normal; - private static final Direction[] VALUES = values(); - private static final Direction[] BY_3D_DATA = Arrays.stream(VALUES).sorted(Comparator.comparingInt(arg -> arg.data3d)).toArray(Direction[]::new); - private static final Direction[] BY_2D_DATA = Arrays.stream(VALUES) - .filter(arg -> arg.getAxis().isHorizontal()) - .sorted(Comparator.comparingInt(arg -> arg.data2d)) - .toArray(Direction[]::new); Direction( final int j, final int k, final int l, final String string2, final Direction.AxisDirection arg, final Direction.Axis arg2, final Vector3i arg3 @@ -83,6 +83,82 @@ public static float getYRot(Direction arg) { }; } + public static Direction from3DDataValue(int index) { + return BY_3D_DATA[MathHelper.abs(index % BY_3D_DATA.length)]; + } + + public static Direction from2DDataValue(int horizontalIndex) { + return BY_2D_DATA[MathHelper.abs(horizontalIndex % BY_2D_DATA.length)]; + } + + public static Direction fromYRot(double angle) { + return from2DDataValue(MathHelper.floor(angle / 90.0 + 0.5) & 3); + } + + public static Direction fromAxisAndDirection(Direction.Axis axis, Direction.AxisDirection axisDirection) { + return switch (axis) { + case X -> axisDirection == Direction.AxisDirection.POSITIVE ? EAST : WEST; + case Y -> axisDirection == Direction.AxisDirection.POSITIVE ? UP : DOWN; + case Z -> axisDirection == Direction.AxisDirection.POSITIVE ? SOUTH : NORTH; + }; + } + + public static Direction getApproximateNearest(double d, double e, double f) { + return getApproximateNearest((float) d, (float) e, (float) f); + } + + public static Direction getApproximateNearest(float f, float g, float h) { + var lv = NORTH; + var i = Float.MIN_VALUE; + + for (var lv2 : VALUES) { + var j = f * (float) lv2.normal.getX() + g * (float) lv2.normal.getY() + h * (float) lv2.normal.getZ(); + if (j > i) { + i = j; + lv = lv2; + } + } + + return lv; + } + + public static Direction getApproximateNearest(Vector3d arg) { + return getApproximateNearest(arg.getX(), arg.getY(), arg.getZ()); + } + + @Nullable + @Contract("_,_,_,!null->!null;_,_,_,_->_") + public static Direction getNearest(int i, int j, int k, @Nullable Direction arg) { + var l = Math.abs(i); + var m = Math.abs(j); + var n = Math.abs(k); + if (l > n && l > m) { + return i < 0 ? WEST : EAST; + } else if (n > l && n > m) { + return k < 0 ? NORTH : SOUTH; + } else if (m > l && m > n) { + return j < 0 ? DOWN : UP; + } else { + return arg; + } + } + + @Nullable + @Contract("_,!null->!null;_,_->_") + public static Direction getNearest(Vector3i arg, @Nullable Direction arg2) { + return getNearest(arg.getX(), arg.getY(), arg.getZ(), arg2); + } + + public static Direction get(Direction.AxisDirection axisDirection, Direction.Axis axis) { + for (var lv : VALUES) { + if (lv.getAxisDirection() == axisDirection && lv.getAxis() == axis) { + return lv; + } + } + + throw new IllegalArgumentException("No such direction: " + axisDirection + " " + axis); + } + public int get3DDataValue() { return this.data3d; } @@ -188,7 +264,7 @@ public int getStepZ() { } public Vector3f step() { - return Vector3f.from((float)this.getStepX(), (float)this.getStepY(), (float)this.getStepZ()); + return Vector3f.from((float) this.getStepX(), (float) this.getStepY(), (float) this.getStepZ()); } public String getName() { @@ -199,95 +275,19 @@ public Direction.Axis getAxis() { return this.axis; } - public static Direction from3DDataValue(int index) { - return BY_3D_DATA[MathHelper.abs(index % BY_3D_DATA.length)]; - } - - public static Direction from2DDataValue(int horizontalIndex) { - return BY_2D_DATA[MathHelper.abs(horizontalIndex % BY_2D_DATA.length)]; - } - - public static Direction fromYRot(double angle) { - return from2DDataValue(MathHelper.floor(angle / 90.0 + 0.5) & 3); - } - - public static Direction fromAxisAndDirection(Direction.Axis axis, Direction.AxisDirection axisDirection) { - return switch (axis) { - case X -> axisDirection == Direction.AxisDirection.POSITIVE ? EAST : WEST; - case Y -> axisDirection == Direction.AxisDirection.POSITIVE ? UP : DOWN; - case Z -> axisDirection == Direction.AxisDirection.POSITIVE ? SOUTH : NORTH; - }; - } - public float toYRot() { - return (float)((this.data2d & 3) * 90); - } - - public static Direction getApproximateNearest(double d, double e, double f) { - return getApproximateNearest((float)d, (float)e, (float)f); - } - - public static Direction getApproximateNearest(float f, float g, float h) { - var lv = NORTH; - var i = Float.MIN_VALUE; - - for (var lv2 : VALUES) { - var j = f * (float) lv2.normal.getX() + g * (float) lv2.normal.getY() + h * (float) lv2.normal.getZ(); - if (j > i) { - i = j; - lv = lv2; - } - } - - return lv; - } - - public static Direction getApproximateNearest(Vector3d arg) { - return getApproximateNearest(arg.getX(), arg.getY(), arg.getZ()); + return (float) ((this.data2d & 3) * 90); } public Vector3i offset(Vector3i arg) { return arg.add(this.normal); } - @Nullable - @Contract("_,_,_,!null->!null;_,_,_,_->_") - public static Direction getNearest(int i, int j, int k, @Nullable Direction arg) { - var l = Math.abs(i); - var m = Math.abs(j); - var n = Math.abs(k); - if (l > n && l > m) { - return i < 0 ? WEST : EAST; - } else if (n > l && n > m) { - return k < 0 ? NORTH : SOUTH; - } else if (m > l && m > n) { - return j < 0 ? DOWN : UP; - } else { - return arg; - } - } - - @Nullable - @Contract("_,!null->!null;_,_->_") - public static Direction getNearest(Vector3i arg, @Nullable Direction arg2) { - return getNearest(arg.getX(), arg.getY(), arg.getZ(), arg2); - } - @Override public String toString() { return this.name; } - public static Direction get(Direction.AxisDirection axisDirection, Direction.Axis axis) { - for (var lv : VALUES) { - if (lv.getAxisDirection() == axisDirection && lv.getAxis() == axis) { - return lv; - } - } - - throw new IllegalArgumentException("No such direction: " + axisDirection + " " + axis); - } - public Vector3i getUnitVector3i() { return this.normal; } @@ -296,7 +296,7 @@ public boolean isFacingAngle(float degrees) { var g = degrees * (float) (Math.PI / 180.0); var h = -MathHelper.sin(g); var i = MathHelper.cos(g); - return (float)this.normal.getX() * h + (float)this.normal.getZ() * i > 0.0F; + return (float) this.normal.getX() * h + (float) this.normal.getZ() * i > 0.0F; } public enum Axis implements Predicate { diff --git a/server/src/main/java/com/soulfiremc/server/util/mcstructs/VecDeltaCodec.java b/server/src/main/java/com/soulfiremc/server/util/mcstructs/VecDeltaCodec.java index 7a10f4e47..8f6179eca 100644 --- a/server/src/main/java/com/soulfiremc/server/util/mcstructs/VecDeltaCodec.java +++ b/server/src/main/java/com/soulfiremc/server/util/mcstructs/VecDeltaCodec.java @@ -24,20 +24,20 @@ @Getter @Setter public class VecDeltaCodec { - private Vector3d base = Vector3d.ZERO; + private Vector3d base = Vector3d.ZERO; - public Vector3d decode(double x, double y, double z) { - if (x == 0L && y == 0L && z == 0L) { - return this.base; - } else { - var decodedX = x == 0L ? this.base.getX() : this.base.getX() + x; - var decodedY = y == 0L ? this.base.getY() : this.base.getY() + y; - var decodedZ = z == 0L ? this.base.getZ() : this.base.getZ() + z; - return Vector3d.from(decodedX, decodedY, decodedZ); - } + public Vector3d decode(double x, double y, double z) { + if (x == 0L && y == 0L && z == 0L) { + return this.base; + } else { + var decodedX = x == 0L ? this.base.getX() : this.base.getX() + x; + var decodedY = y == 0L ? this.base.getY() : this.base.getY() + y; + var decodedZ = z == 0L ? this.base.getZ() : this.base.getZ() + z; + return Vector3d.from(decodedX, decodedY, decodedZ); } + } - public Vector3d delta(Vector3d value) { - return value.sub(this.base); - } + public Vector3d delta(Vector3d value) { + return value.sub(this.base); + } }