Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/minions #21

Merged
merged 10 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ build/
### NixOS ###
.envrc
.env

worlds/
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<dependency>
<groupId>com.github.Minestom</groupId>
<artifactId>Minestom</artifactId>
<version>f1d5940855</version>
<version>8ea7760e6a</version>
</dependency>

<dependency>
Expand Down
17 changes: 10 additions & 7 deletions src/main/java/com/slampvp/factory/FactoryServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.slampvp.factory.command.FactoryCommand;
import com.slampvp.factory.common.menu.MenuListener;
import com.slampvp.factory.database.DatabaseManager;
import com.slampvp.factory.minion.MinionManager;
import com.slampvp.factory.player.PlayerListener;
import com.slampvp.factory.plot.PlotGenerator;
import com.slampvp.factory.plot.PlotManager;
Expand All @@ -21,18 +22,14 @@
import java.util.Set;
import java.util.stream.Stream;


public final class FactoryServer {
public static final Logger LOGGER = LoggerFactory.getLogger(FactoryServer.class);

public static void main(String[] args) {
long start = System.currentTimeMillis();
MinecraftServer minecraftServer = MinecraftServer.init();
MojangAuth.init();

MinecraftServer.getSchedulerManager().buildShutdownTask(() -> {
DatabaseManager.getInstance().close();
});

InstanceManager instanceManager = MinecraftServer.getInstanceManager();
InstanceContainer instanceContainer = instanceManager.createInstanceContainer();

Expand All @@ -44,14 +41,21 @@ public static void main(String[] args) {
new PlayerListener(instanceContainer);
new MenuListener();

PlotManager.getInstance().init();
DatabaseManager.getInstance().init();
PlotManager.getInstance().init();
MinionManager.getInstance().init();

streamPackage("com.slampvp.factory.command", FactoryCommand.class).forEach(c ->
MinecraftServer.getCommandManager().register(c)
);

MinecraftServer.getSchedulerManager().buildShutdownTask(() -> {
DatabaseManager.getInstance().close();
instanceContainer.saveChunksToStorage();
});

minecraftServer.start("0.0.0.0", 25565);
LOGGER.info("Server started in {}ms.", System.currentTimeMillis() - start);
}

public static <T> Stream<T> streamPackage(String packageName, Class<T> clazz) {
Expand Down Expand Up @@ -87,5 +91,4 @@ public static <T> Stream<T> streamPackage(String packageName, Class<T> clazz) {
})
.filter(java.util.Objects::nonNull);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.slampvp.factory.command.minion;

import com.slampvp.factory.command.Command;
import com.slampvp.factory.command.FactoryCommand;
import com.slampvp.factory.minion.models.Minion;
import com.slampvp.factory.player.Rank;

@Command(description = "Minion command.", usage = "/minion", minimumRank = Rank.ADMIN, playerOnly = false)
public class MinionCommand extends FactoryCommand {
public MinionCommand() {
super("minion");
}

@Override
public void init() {
addSyntax(((sender, context) -> {
Minion.all().forEach(minion -> {
sender.sendMessage(minion.toString());
});
}));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.slampvp.factory.command.minion.sub;

import com.slampvp.factory.command.Command;
import com.slampvp.factory.command.FactoryCommand;
import com.slampvp.factory.common.Locale;
import com.slampvp.factory.common.StringUtil;
import com.slampvp.factory.minion.models.Minion;
import com.slampvp.factory.minion.models.Minions;
import com.slampvp.factory.player.Rank;
import net.minestom.server.command.builder.arguments.ArgumentString;
import net.minestom.server.command.builder.arguments.ArgumentType;
import net.minestom.server.command.builder.arguments.minecraft.ArgumentEntity;
import net.minestom.server.command.builder.arguments.number.ArgumentInteger;
import net.minestom.server.command.builder.arguments.number.ArgumentNumber;
import net.minestom.server.command.builder.suggestion.SuggestionEntry;
import net.minestom.server.entity.Player;

import java.util.ArrayList;
import java.util.Optional;

@Command(
description = "Give a minion to a player.",
usage = "/minion give <player> <minion> [amount]",
minimumRank = Rank.ADMIN,
playerOnly = false
)
public class GiveCommand extends FactoryCommand {
public GiveCommand() {
super("give");
}

@Override
public void init() {
ArgumentEntity argumentPlayer = ArgumentType.Entity("player").singleEntity(true).onlyPlayers(true);
ArgumentString argumentMinion = ArgumentType.String("minion");
ArgumentNumber<Integer> argumentAmount = ArgumentType.Integer("amount").min(1);

argumentMinion.setSuggestionCallback((sender, context, suggestion) -> {
String arg = suggestion.getInput().substring(suggestion.getStart() - 1, suggestion.getStart() + suggestion.getLength() - 1);
StringUtil.copyPartialMatches(arg, Minion.all().stream().map(Minion::id).toList(), new ArrayList<>()).forEach(string -> {
suggestion.addEntry(new SuggestionEntry(string));
});
});

addSyntax((sender, context) -> {
Player target = context.get(argumentPlayer).findFirstPlayer(sender);

if (target == null) {
sender.sendMessage(Locale.Command.INVALID_PLAYER);
return;
}

Optional<Minion> optionalMinion = Minion.byId(context.get(argumentMinion));

if (optionalMinion.isEmpty()) {
sender.sendMessage(Locale.Minion.INVALID_ID);
return;
}

Minion minion = optionalMinion.get();

target.getInventory().addItemStack(minion.getItem());
}, argumentPlayer, argumentMinion);

addSyntax((sender, context) -> {
Player target = context.get(argumentPlayer).findFirstPlayer(sender);

if (target == null) {
sender.sendMessage(Locale.Command.INVALID_PLAYER);
return;
}

Optional<Minion> optionalMinion = Minion.byId(context.get(argumentMinion));

if (optionalMinion.isEmpty()) {
sender.sendMessage(Locale.Minion.INVALID_ID);
return;
}

int amount = context.get(argumentAmount);

Minion minion = optionalMinion.get();

for (int i = 0; i < amount; i++) {
target.getInventory().addItemStack(minion.getItem());
}
}, argumentPlayer, argumentMinion, argumentAmount);
}
}
17 changes: 17 additions & 0 deletions src/main/java/com/slampvp/factory/common/ItemStackUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.slampvp.factory.common;

import net.minestom.server.entity.PlayerSkin;
import net.minestom.server.item.ItemComponent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.item.component.HeadProfile;
import org.jetbrains.annotations.NotNull;

public class ItemStackUtil {
public static @NotNull ItemStack.Builder texturedHead(String texture) {
ItemStack.Builder skull = ItemStack.builder(Material.PLAYER_HEAD);
HeadProfile profile = new HeadProfile(new PlayerSkin(texture, null));
skull.set(ItemComponent.PROFILE, profile);
return skull;
}
}
15 changes: 15 additions & 0 deletions src/main/java/com/slampvp/factory/common/Locale.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,19 @@ interface Plot {
Component.text("You've successfully merged your plots!").color(NamedTextColor.GREEN)
);
}

/**
* Minion-related messages.
*/
interface Minion {
TextComponent PREFIX = Component.text()
.append(Component.text("[").color(NamedTextColor.RED).decorate(TextDecoration.BOLD))
.append(Component.text("Minion").color(NamedTextColor.BLUE).decorate(TextDecoration.BOLD))
.append(Component.text("] ").color(NamedTextColor.RED).decorate(TextDecoration.BOLD))
.build();

TextComponent INVALID_ID = PREFIX.append(
Component.text("Cannot find a minion with specified id!").color(NamedTextColor.RED)
);
}
}
23 changes: 23 additions & 0 deletions src/main/java/com/slampvp/factory/common/StringUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.slampvp.factory.common;

import java.util.Collection;

public class StringUtil {
public static <T extends Collection<? super String>> T copyPartialMatches(String token, Iterable<String> originals, T collection)
throws UnsupportedOperationException, IllegalArgumentException {
if (token.length() == 1 && Integer.toHexString(token.charAt(0) | 0x10000).substring(1).equals("0000")) {
token = "";
}

for (String string : originals) {
if (startsWithIgnoreCase(string, token)) {
collection.add(string);
}
}
return collection;
}

private static boolean startsWithIgnoreCase(String string, String prefix) throws IllegalArgumentException, NullPointerException {
return string.length() >= prefix.length() && string.regionMatches(true, 0, prefix, 0, prefix.length());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.slampvp.factory.database;

import net.minestom.server.coordinate.BlockVec;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
Expand All @@ -17,17 +18,34 @@ public static String pointToString(Point point) {
return null;
}

public static BlockVec stringToBlockVec(String string) {
Float[] array = parseString(string);
if (array.length == 0) {
return null;
}
return new BlockVec(array[0], array[1], array[2]);
}

public static Vec stringToVec(String string) {
Float[] array = parseString(string);
if (array.length == 0) {
return null;
}
return new Vec(array[0], array[1], array[2]);
}

public static Pos stringToPos(String string) {
Float[] array = parseString(string);
if (array.length == 0) {
return null;
}
return new Pos(array[0], array[1], array[2], array[3], array[4]);
}

private static Float @NotNull [] parseString(@NotNull String string) {
private static Float @NotNull [] parseString(String string) {
if (string == null) {
return new Float[0];
}
return Arrays.stream(string
.substring(1, string.length() - 1)
.split(","))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public CompletableFuture<Long> executeUpdate(String query, SQLConsumer<PreparedS

return Long.valueOf(-1);
} catch (SQLException e) {
FactoryServer.LOGGER.error(e.getMessage());
throw new RuntimeException(e);
}
}, executor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ CONSTRAINT fk_plot FOREIGN KEY (plot_id) REFERENCES plots (id) ON DELETE CASCADE
);
CREATE UNIQUE INDEX IF NOT EXISTS index_plot_flags_on_all ON plot_flags (plot_id, target, flags);
CREATE INDEX IF NOT EXISTS index_plot_flags_on_plot_id ON plot_flags (plot_id);
CREATE TABLE IF NOT EXISTS minions
(
id SERIAL,
minion_id TEXT NOT NULL,
owner VARCHAR(36) NOT NULL,
time_active BIGINT NOT NULL,
amount_generated BIGINT NOT NULL,
position VEC NOT NULL,
chest_position VEC,
PRIMARY KEY (id)
);
CREATE INDEX IF NOT EXISTS index_minions_on_owner ON minions (owner);
END
$$;
""";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.slampvp.factory.database.queries;

import org.intellij.lang.annotations.Language;

public final class MinionQueries {
public static final class Insert {
@Language("PostgreSQL")
public static final String MINION = """
INSERT INTO minions (minion_id, owner, time_active, amount_generated, position, chest_position)
VALUES (?,?,?,?,?,?);
""";
}

public static final class Select {
@Language("PostgreSQL")
public static final String BY_OWNER = "SELECT * FROM minions WHERE owner = ?";
}

public static final class Delete {
@Language("PostgreSQL")
public static final String BY_ID = "DELETE FROM plots WHERE id = ?";
}
}
37 changes: 37 additions & 0 deletions src/main/java/com/slampvp/factory/minion/MinionListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.slampvp.factory.minion;

import com.slampvp.factory.minion.models.Minion;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player;
import net.minestom.server.event.GlobalEventHandler;
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
import net.minestom.server.item.ItemStack;
import net.minestom.server.tag.Tag;

import java.util.Optional;

public class MinionListener {
public MinionListener() {
GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
MinionManager minionManager = MinionManager.getInstance();

globalEventHandler.addListener(PlayerBlockPlaceEvent.class, event -> {
Player player = event.getPlayer();
ItemStack itemInHand = player.getItemInHand(event.getHand());

String minionId = itemInHand.getTag(Tag.String("minion"));
if (minionId == null) {
return;
}

Optional<Minion> optionalMinion = Minion.byId(minionId);
if (optionalMinion.isEmpty()) {
return;
}

event.setCancelled(true);
player.setItemInMainHand(itemInHand.withAmount(itemInHand.amount() - 1));
minionManager.addMinion(player, event.getBlockPosition().asVec(), optionalMinion.get());
});
}
}
Loading
Loading