Skip to content

Commit 538a6da

Browse files
authored
Merge pull request #133 from TheNextLvl-net/feat/group-clone
Added group clone command
2 parents 9237caa + bb8728a commit 538a6da

11 files changed

Lines changed: 178 additions & 20 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package net.thenextlvl.perworlds;
2+
3+
import org.jetbrains.annotations.ApiStatus;
4+
import org.jetbrains.annotations.Contract;
5+
6+
/**
7+
* Represents an object that can be copied from another object.
8+
*
9+
* @since 1.4.0
10+
*/
11+
@ApiStatus.NonExtendable
12+
public interface Copyable<T> {
13+
/**
14+
* Copies the state of the given object into this object.
15+
*
16+
* @param other the object to copy from
17+
* @return this object with applied state of the given object
18+
* @since 1.4.0
19+
*/
20+
@Contract(value = "_ -> this", mutates = "this")
21+
T copyFrom(T other);
22+
}

api/src/main/java/net/thenextlvl/perworlds/GroupData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
*/
2222
@NullMarked
2323
@ApiStatus.NonExtendable
24-
public interface GroupData {
24+
public interface GroupData extends Copyable<GroupData> {
2525
/**
2626
* Iterates over each {@link GameRule} associated with the group and applies the given action.
2727
*

api/src/main/java/net/thenextlvl/perworlds/GroupSettings.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* @since 0.1.0
1515
*/
1616
@ApiStatus.NonExtendable
17-
public interface GroupSettings {
17+
public interface GroupSettings extends Copyable<GroupSettings> {
1818
/**
1919
* Determines whether the associated group is enabled.
2020
*

build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ paper {
9090
children = listOf(
9191
"perworlds.command.group.add",
9292
"perworlds.command.group.auto",
93+
"perworlds.command.group.clone",
9394
"perworlds.command.group.create",
9495
"perworlds.command.group.delete",
9596
"perworlds.command.group.info",
@@ -106,6 +107,7 @@ paper {
106107
register("perworlds.command.group") { children = listOf("perworlds.command") }
107108
register("perworlds.command.group.add") { children = listOf("perworlds.command.group") }
108109
register("perworlds.command.group.auto") { children = listOf("perworlds.command.group") }
110+
register("perworlds.command.group.clone") { children = listOf("perworlds.command.group") }
109111
register("perworlds.command.group.create") { children = listOf("perworlds.command.group") }
110112
register("perworlds.command.group.delete") { children = listOf("perworlds.command.group") }
111113
register("perworlds.command.group.info") { children = listOf("perworlds.command.group") }
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package net.thenextlvl.perworlds.command;
2+
3+
import com.mojang.brigadier.Command;
4+
import com.mojang.brigadier.arguments.StringArgumentType;
5+
import com.mojang.brigadier.builder.ArgumentBuilder;
6+
import com.mojang.brigadier.context.CommandContext;
7+
import io.papermc.paper.command.brigadier.CommandSourceStack;
8+
import io.papermc.paper.command.brigadier.Commands;
9+
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
10+
import net.thenextlvl.perworlds.PerWorldsPlugin;
11+
import net.thenextlvl.perworlds.WorldGroup;
12+
import net.thenextlvl.perworlds.command.brigadier.SimpleCommand;
13+
import org.jspecify.annotations.NullMarked;
14+
15+
import static net.thenextlvl.perworlds.command.WorldCommand.groupArgument;
16+
17+
@NullMarked
18+
final class GroupCloneCommand extends SimpleCommand {
19+
private GroupCloneCommand(final PerWorldsPlugin plugin) {
20+
super(plugin, "clone", "perworlds.command.group.clone");
21+
}
22+
23+
public static ArgumentBuilder<CommandSourceStack, ?> create(final PerWorldsPlugin plugin) {
24+
final var command = new GroupCloneCommand(plugin);
25+
final var name = Commands.argument("name", StringArgumentType.string());
26+
return command.create().then(groupArgument(plugin, true).then(name.executes(command)));
27+
}
28+
29+
@Override
30+
public int run(final CommandContext<CommandSourceStack> context) {
31+
final var sender = context.getSource().getSender();
32+
final var group = context.getArgument("group", WorldGroup.class);
33+
final var name = context.getArgument("name", String.class);
34+
final var success = !plugin.groupProvider().hasGroup(name);
35+
if (success) plugin.groupProvider().createGroup(name, data -> {
36+
data.copyFrom(group.getGroupData());
37+
}, groupSettings -> {
38+
groupSettings.copyFrom(group.getSettings());
39+
});
40+
final var message = success ? "group.cloned" : "group.exists";
41+
plugin.bundle().sendMessage(sender, message,
42+
Placeholder.unparsed("group", group.getName()),
43+
Placeholder.unparsed("name", name));
44+
return success ? Command.SINGLE_SUCCESS : 0;
45+
}
46+
}

src/main/java/net/thenextlvl/perworlds/command/GroupCommand.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ private GroupCommand(final PerWorldsPlugin plugin) {
1818
return command.create()
1919
.then(GroupAddCommand.create(plugin))
2020
.then(GroupAutoCommand.create(plugin))
21+
.then(GroupCloneCommand.create(plugin))
2122
.then(GroupCreateCommand.create(plugin))
2223
.then(GroupDeleteCommand.create(plugin))
2324
.then(GroupHelpCommand.create(plugin))

src/main/java/net/thenextlvl/perworlds/group/PaperGroupData.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,21 @@ public long getTime() {
157157
public void setTime(final long time) {
158158
this.time = time;
159159
}
160+
161+
@Override
162+
public GroupData copyFrom(final GroupData other) {
163+
this.gameRules.clear();
164+
other.forEachGameRule(gameRules::put);
165+
this.defaultGameMode = other.getDefaultGameMode().orElse(null);
166+
this.worldBorder = other.getWorldBorder();
167+
this.difficulty = other.getDifficulty();
168+
this.hardcore = other.getHardcore();
169+
this.raining = other.isRaining();
170+
this.thundering = other.isThundering();
171+
this.clearWeatherDuration = other.clearWeatherDuration();
172+
this.rainDuration = other.getRainDuration();
173+
this.thunderDuration = other.getThunderDuration();
174+
this.time = other.getTime();
175+
return this;
176+
}
160177
}

src/main/java/net/thenextlvl/perworlds/group/PaperGroupSettings.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,4 +531,57 @@ public boolean wardenSpawnTracker() {
531531
public void wardenSpawnTracker(final boolean enabled) {
532532
this.wardenSpawnTracker = enabled;
533533
}
534+
535+
@Override
536+
public GroupSettings copyFrom(final GroupSettings other) {
537+
this.absorption = other.absorption();
538+
this.advancementMessages = other.advancementMessages();
539+
this.advancements = other.advancements();
540+
this.arrowsInBody = other.arrowsInBody();
541+
this.attributes = other.attributes();
542+
this.beeStingersInBody = other.beeStingersInBody();
543+
this.chat = other.chat();
544+
this.deathMessages = other.deathMessages();
545+
this.difficulty = other.difficulty();
546+
this.enabled = other.enabled();
547+
this.endCredits = other.endCredits();
548+
this.enderChest = other.enderChest();
549+
this.exhaustion = other.exhaustion();
550+
this.experience = other.experience();
551+
this.fallDistance = other.fallDistance();
552+
this.fireTicks = other.fireTicks();
553+
this.flySpeed = other.flySpeed();
554+
this.flyState = other.flyState();
555+
this.foodLevel = other.foodLevel();
556+
this.freezeTicks = other.freezeTicks();
557+
this.gameMode = other.gameMode();
558+
this.gameRules = other.gameRules();
559+
this.gliding = other.gliding();
560+
this.health = other.health();
561+
this.hotbarSlot = other.hotbarSlot();
562+
this.inventory = other.inventory();
563+
this.invulnerable = other.invulnerable();
564+
this.joinMessages = other.joinMessages();
565+
this.lastDeathLocation = other.lastDeathLocation();
566+
this.lastLocation = other.lastLocation();
567+
this.lockFreezeTicks = other.lockFreezeTicks();
568+
this.portalCooldown = other.portalCooldown();
569+
this.potionEffects = other.potionEffects();
570+
this.quitMessages = other.quitMessages();
571+
this.recipes = other.recipes();
572+
this.remainingAir = other.remainingAir();
573+
this.respawnLocation = other.respawnLocation();
574+
this.saturation = other.saturation();
575+
this.score = other.score();
576+
this.statistics = other.statistics();
577+
this.tabList = other.tabList();
578+
this.time = other.time();
579+
this.velocity = other.velocity();
580+
this.visualFire = other.visualFire();
581+
this.walkSpeed = other.walkSpeed();
582+
this.wardenSpawnTracker = other.wardenSpawnTracker();
583+
this.weather = other.weather();
584+
this.worldBorder = other.worldBorder();
585+
return this;
586+
}
534587
}

src/main/resources/per-worlds.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ group.auto.created=<gray><prefix> Created new group <green><group></green></gray
33
group.auto.done=<gray><prefix> Automatically grouped <green><worlds></green> worlds into <green><groups></green> groups</gray>
44
group.auto.failed=<gray><prefix> Failed to add world <green><world></green> to group <green><group></green></gray>
55
group.auto.skipped=<gray><prefix> Skipped world <green><world></green> from auto grouping</gray>
6+
group.cloned=<gray><prefix> Cloned the group <green><group></green> to <green><name></green></gray>
67
group.created=<gray><prefix> Created a new group called <green><name></green></gray>
78
group.delete.failed=<gray><prefix> Failed to delete the group <green><group></green></gray>
89
group.deleted=<gray><prefix> Deleted the group <green><group></green></gray>

src/main/resources/per-worlds_german.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ group.auto.created=<gray><prefix> Gruppe <green><group></green> wurde erstellt</
33
group.auto.done=<gray><prefix> <green><worlds></green> Welten wurden automatisch in <green><groups></green> Gruppen gruppiert</gray>
44
group.auto.failed=<gray><prefix> Welt <green><world></green> konnte nicht zur Gruppe <green><group></green> hinzugefügt werden</gray>
55
group.auto.skipped=<gray><prefix> Welt <green><world></green> wurde bei der automatischen Gruppierung übersprungen</gray>
6+
group.cloned=<gray><prefix> Die Gruppe <green><group></green> wurde zu <green><name></green> geklont</gray>
67
group.created=<gray><prefix> Neue Gruppe namens <green><name></green> wurde erstellt</gray>
78
group.delete.failed=<gray><prefix> Die Gruppe <green><group></green> konnte nicht gelöscht werden</gray>
89
group.deleted=<gray><prefix> Die Gruppe <green><group></green> wurde gelöscht</gray>

0 commit comments

Comments
 (0)