Skip to content

Commit b208ad9

Browse files
authored
GH-875 Add set slot command. (#899)
* Add server capacity command. * Fix. * Follow review feedback.
1 parent 2953feb commit b208ad9

File tree

10 files changed

+234
-0
lines changed

10 files changed

+234
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.eternalcode.core.feature.setslot;
2+
3+
import com.eternalcode.annotations.scan.command.DescriptionDocs;
4+
import com.eternalcode.core.injector.annotations.Inject;
5+
import com.eternalcode.core.notice.NoticeService;
6+
import com.eternalcode.core.viewer.Viewer;
7+
import dev.rollczi.litecommands.annotations.argument.Arg;
8+
import dev.rollczi.litecommands.annotations.async.Async;
9+
import dev.rollczi.litecommands.annotations.command.Command;
10+
import dev.rollczi.litecommands.annotations.context.Context;
11+
import dev.rollczi.litecommands.annotations.execute.Execute;
12+
import dev.rollczi.litecommands.annotations.permission.Permission;
13+
14+
@Command(name = "setslot")
15+
@Permission("eternalcore.setslot")
16+
public class SetSlotCommand {
17+
18+
private final SetSlotService setSlotService;
19+
private final NoticeService noticeService;
20+
21+
@Inject
22+
public SetSlotCommand(
23+
SetSlotService setSlotService,
24+
NoticeService noticeService
25+
) {
26+
this.setSlotService = setSlotService;
27+
this.noticeService = noticeService;
28+
}
29+
30+
@Execute
31+
@Async
32+
@DescriptionDocs(description = "Set the max players on the server")
33+
public void execute(@Context Viewer viewer, @Arg int slots) {
34+
if (slots <= 0) {
35+
this.noticeService.create()
36+
.notice(notice -> notice.argument().numberBiggerThanOrEqualZero())
37+
.viewer(viewer)
38+
.send();
39+
return;
40+
}
41+
42+
this.setSlotService.setCapacity(slots);
43+
this.noticeService.create()
44+
.notice(notice -> notice.setSlot().slotSaved())
45+
.placeholder("{SLOTS}", String.valueOf(slots))
46+
.viewer(viewer)
47+
.send();
48+
}
49+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.eternalcode.core.feature.setslot;
2+
3+
import com.eternalcode.core.injector.annotations.Inject;
4+
import com.eternalcode.core.injector.annotations.component.Service;
5+
import java.io.File;
6+
import java.io.FileInputStream;
7+
import java.io.FileOutputStream;
8+
import java.io.IOException;
9+
import java.io.InputStream;
10+
import java.io.OutputStream;
11+
import java.util.Properties;
12+
import java.util.logging.Level;
13+
import org.bukkit.Server;
14+
15+
@Service
16+
public class SetSlotSaver {
17+
18+
private static final String MAX_PLAYERS_PROPERTY = "max-players";
19+
private final Server server;
20+
21+
@Inject
22+
public SetSlotSaver(Server server) {
23+
this.server = server;
24+
}
25+
26+
public void save() {
27+
File propertiesFile = new File("server.properties");
28+
Properties properties = new Properties();
29+
30+
try (InputStream is = new FileInputStream(propertiesFile)) {
31+
properties.load(is);
32+
33+
String maxPlayers = Integer.toString(this.server.getMaxPlayers());
34+
if (maxPlayers.equals(properties.getProperty(MAX_PLAYERS_PROPERTY))) {
35+
return;
36+
}
37+
38+
this.server.getLogger().info("Saving max players to server.properties...");
39+
properties.setProperty(MAX_PLAYERS_PROPERTY, maxPlayers);
40+
41+
try (OutputStream os = new FileOutputStream(propertiesFile)) {
42+
properties.store(os, "Minecraft server properties");
43+
}
44+
}
45+
catch (IOException exception) {
46+
this.server.getLogger()
47+
.log(Level.SEVERE, "An error occurred while updating the server properties", exception);
48+
}
49+
}
50+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.eternalcode.core.feature.setslot;
2+
3+
import com.eternalcode.core.injector.annotations.Inject;
4+
import com.eternalcode.core.injector.annotations.component.Service;
5+
import com.eternalcode.core.util.ReflectUtil;
6+
import java.lang.reflect.Field;
7+
import java.lang.reflect.Method;
8+
import org.bukkit.Server;
9+
import org.bukkit.plugin.Plugin;
10+
11+
@Service
12+
public class SetSlotService {
13+
14+
private final Plugin plugin;
15+
private Field maxPlayersField;
16+
private final SetSlotSaver setSlotSaver;
17+
18+
@Inject
19+
public SetSlotService(Plugin plugin, SetSlotSaver setSlotSaver) {
20+
this.plugin = plugin;
21+
this.setSlotSaver = setSlotSaver;
22+
}
23+
24+
public void setCapacity(int slots) {
25+
Object playerList = getPlayerList();
26+
27+
if (this.maxPlayersField == null) {
28+
this.maxPlayersField = findMaxPlayersField(playerList);
29+
}
30+
31+
this.setMaxPlayers(playerList, slots);
32+
this.setSlotSaver.save();
33+
}
34+
35+
private Object getPlayerList() {
36+
Server server = this.plugin.getServer();
37+
Method serverGetHandle = ReflectUtil.getDeclaredMethod(server.getClass(), "getHandle");
38+
39+
return ReflectUtil.invokeMethod(serverGetHandle, server);
40+
}
41+
42+
private Field findMaxPlayersField(Object playerList) {
43+
Class<?> playerListClass = playerList.getClass().getSuperclass();
44+
45+
for (Field field : playerListClass.getDeclaredFields()) {
46+
if (field.getType() == int.class) {
47+
field.setAccessible(true);
48+
try {
49+
if (field.getInt(playerList) == this.plugin.getServer().getMaxPlayers()) {
50+
return field;
51+
}
52+
}
53+
catch (IllegalAccessException exception) {
54+
throw new IllegalStateException("Error accessing field value for maxPlayers", exception);
55+
}
56+
}
57+
}
58+
59+
throw new IllegalStateException("Unable to find maxPlayers field in " + playerListClass.getName());
60+
}
61+
62+
private void setMaxPlayers(Object playerList, int slots) {
63+
try {
64+
this.maxPlayersField.setInt(playerList, slots);
65+
}
66+
catch (IllegalAccessException exception) {
67+
throw new IllegalStateException("Failed to set maxPlayers field", exception);
68+
}
69+
}
70+
}
71+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.eternalcode.core.feature.setslot.messages;
2+
3+
import com.eternalcode.multification.notice.Notice;
4+
import lombok.Getter;
5+
import lombok.experimental.Accessors;
6+
import net.dzikoysk.cdn.entity.Contextual;
7+
8+
@Getter
9+
@Accessors(fluent = true)
10+
@Contextual
11+
public class ENSetSlotMessages implements SetSlotMessages {
12+
public Notice slotSaved = Notice.chat("<green>► <white>Server slots have been set to <green>{SLOTS} <white>and saved!");
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.eternalcode.core.feature.setslot.messages;
2+
3+
import com.eternalcode.multification.notice.Notice;
4+
import lombok.Getter;
5+
import lombok.experimental.Accessors;
6+
import net.dzikoysk.cdn.entity.Contextual;
7+
8+
@Getter
9+
@Accessors(fluent = true)
10+
@Contextual
11+
public class PLSetSlotMessages implements SetSlotMessages {
12+
public Notice slotSaved = Notice.chat("<green>► <white>Sloty serwera zostały ustawione na <green>{SLOTS} <white>i zapisane!");
13+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.eternalcode.core.feature.setslot.messages;
2+
3+
import com.eternalcode.multification.notice.Notice;
4+
5+
public interface SetSlotMessages {
6+
Notice slotSaved();
7+
}

eternalcore-core/src/main/java/com/eternalcode/core/translation/Translation.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.eternalcode.core.configuration.contextual.ConfigItem;
44
import com.eternalcode.core.feature.language.Language;
5+
import com.eternalcode.core.feature.setslot.messages.SetSlotMessages;
56
import com.eternalcode.core.feature.warp.WarpInventoryItem;
67
import com.eternalcode.multification.notice.Notice;
78
import org.bukkit.Material;
@@ -446,6 +447,8 @@ interface ContainerSection {
446447
Notice genericContainerOpenedFor();
447448
}
448449

450+
SetSlotMessages setSlot();
451+
449452
AutoMessageSection autoMessage();
450453

451454
interface AutoMessageSection {

eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/ENTranslation.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.eternalcode.core.configuration.contextual.ConfigItem;
44
import com.eternalcode.core.feature.language.Language;
5+
import com.eternalcode.core.feature.setslot.messages.ENSetSlotMessages;
56
import com.eternalcode.core.feature.warp.WarpInventoryItem;
67
import com.eternalcode.core.translation.AbstractTranslation;
78
import com.eternalcode.multification.bukkit.notice.BukkitNotice;
@@ -845,6 +846,9 @@ public static class ENLanguageSection implements LanguageSection {
845846
);
846847
}
847848

849+
@Description({" ", "# Set's max players on the server, the messages for the /setslot command"})
850+
public ENSetSlotMessages setSlot = new ENSetSlotMessages();
851+
848852
@Description({" ", "# Auto message"})
849853
public ENAutoMessageSection autoMessage = new ENAutoMessageSection();
850854

eternalcore-core/src/main/java/com/eternalcode/core/translation/implementation/PLTranslation.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.eternalcode.core.configuration.contextual.ConfigItem;
44
import com.eternalcode.core.feature.language.Language;
5+
import com.eternalcode.core.feature.setslot.messages.PLSetSlotMessages;
56
import com.eternalcode.core.feature.warp.WarpInventoryItem;
67
import com.eternalcode.core.translation.AbstractTranslation;
78
import com.eternalcode.multification.bukkit.notice.BukkitNotice;
@@ -869,6 +870,9 @@ public static class PLLanguageSection implements LanguageSection {
869870
);
870871
}
871872

873+
@Description({" ", "# Ta sekcja odpowiada za wiadomości dotyczące pojemnosci serwera"})
874+
public PLSetSlotMessages setSlot = new PLSetSlotMessages();
875+
872876
@Description({" ", "# Automatyczne wiadomości "})
873877
public PLAutoMessageSection autoMessage = new PLAutoMessageSection();
874878

eternalcore-core/src/main/java/com/eternalcode/core/util/ReflectUtil.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
import java.io.IOException;
77
import java.lang.reflect.Field;
8+
import java.lang.reflect.InvocationTargetException;
9+
import java.lang.reflect.Method;
810
import java.util.ArrayList;
911
import java.util.Collections;
1012
import java.util.LinkedHashSet;
@@ -94,4 +96,22 @@ public static <T> T getFieldValue(Field declaredField, Object object) {
9496
throw new RuntimeException(exception);
9597
}
9698
}
99+
100+
public static Method getDeclaredMethod(Class<?> clazz, String methodName) {
101+
try {
102+
return clazz.getDeclaredMethod(methodName);
103+
}
104+
catch (NoSuchMethodException exception) {
105+
throw new IllegalArgumentException("Method " + methodName + " not found in class " + clazz.getName(), exception);
106+
}
107+
}
108+
109+
public static Object invokeMethod(Method method, Object target, Object... args) {
110+
try {
111+
return method.invoke(target, args);
112+
}
113+
catch (IllegalAccessException | InvocationTargetException e) {
114+
throw new IllegalStateException("Failed to invoke method " + method.getName(), e);
115+
}
116+
}
97117
}

0 commit comments

Comments
 (0)