Skip to content

Commit 79e4559

Browse files
committed
Add punishment type registry
The registry associates types with their id and the new PunishmentFactory that creates a punishment from a Map of data.
1 parent 78a08b6 commit 79e4559

File tree

9 files changed

+279
-30
lines changed

9 files changed

+279
-30
lines changed

necrify-api/src/main/java/de/jvstvshd/necrify/api/Necrify.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@
2828
import de.jvstvshd.necrify.api.message.MessageProvider;
2929
import de.jvstvshd.necrify.api.punishment.Punishment;
3030
import de.jvstvshd.necrify.api.punishment.PunishmentManager;
31+
import de.jvstvshd.necrify.api.punishment.PunishmentType;
3132
import de.jvstvshd.necrify.api.punishment.util.PlayerResolver;
3233
import de.jvstvshd.necrify.api.user.UserManager;
3334
import org.jetbrains.annotations.ApiStatus;
3435
import org.jetbrains.annotations.NotNull;
3536

37+
import java.util.Map;
3638
import java.util.Optional;
3739
import java.util.UUID;
3840
import java.util.concurrent.CompletableFuture;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* This file is part of Necrify (formerly Velocity Punishment), which is licensed under the MIT license.
3+
*
4+
* Copyright (c) 2022-2024 JvstvsHD
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package de.jvstvshd.necrify.api.punishment;
26+
27+
import org.jetbrains.annotations.NotNull;
28+
29+
import java.util.Map;
30+
31+
/**
32+
* A factory to create punishments of a specific type.
33+
* @since 1.2.0
34+
*/
35+
@FunctionalInterface
36+
public interface PunishmentFactory {
37+
38+
/**
39+
* Creates a new punishment of the given type with the given data.
40+
* @param type the type of the punishment
41+
* @param data the data to create the punishment with
42+
* @return the created punishment
43+
*/
44+
@NotNull
45+
Punishment createPunishment(@NotNull PunishmentType type, @NotNull Map<String, Object> data);
46+
}

necrify-api/src/main/java/de/jvstvshd/necrify/api/punishment/PunishmentType.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,20 @@
2424

2525
package de.jvstvshd.necrify.api.punishment;
2626

27+
import de.jvstvshd.necrify.api.Necrify;
28+
29+
import java.util.Map;
30+
31+
/**
32+
* Represents a type of punishment.
33+
* @since 1.0.0
34+
*/
2735
public interface PunishmentType {
2836

37+
/**
38+
* Gets the name of the punishment type.
39+
* @return the name of the punishment type.
40+
*/
2941
String getName();
3042

3143
/**
@@ -54,4 +66,18 @@ default boolean isMute() {
5466
default boolean isBan() {
5567
return this == StandardPunishmentType.TEMPORARY_BAN || this == StandardPunishmentType.PERMANENT_BAN;
5668
}
69+
70+
/**
71+
* Returns this value as an instance of {@link StandardPunishmentType} if it is a standard punishment type or throws otherwise.
72+
* @return the standard punishment type.
73+
* @throws IllegalStateException if the punishment type is not a standard punishment type.
74+
* @since 1.2.0
75+
*/
76+
default StandardPunishmentType standard() {
77+
if (this instanceof StandardPunishmentType) {
78+
return (StandardPunishmentType) this;
79+
} else {
80+
throw new IllegalStateException("Punishment type is not a standard punishment type.");
81+
}
82+
}
5783
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* This file is part of Necrify (formerly Velocity Punishment), which is licensed under the MIT license.
3+
*
4+
* Copyright (c) 2022-2024 JvstvsHD
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package de.jvstvshd.necrify.api.punishment;
26+
27+
import org.jetbrains.annotations.NotNull;
28+
29+
import java.util.HashMap;
30+
import java.util.Map;
31+
import java.util.function.Function;
32+
33+
/**
34+
* A central registry for {@link PunishmentType}s. This class is used to register and retrieve punishment types by their integer IDs.
35+
* @since 1.2.0
36+
*/
37+
public final class PunishmentTypeRegistry {
38+
39+
private static final Map<Integer, PunishmentType> types = new HashMap<>();
40+
private static final Map<PunishmentType, PunishmentFactory> punishmentFactories = new HashMap<>();
41+
42+
/**
43+
* Registers a new {@link PunishmentType} with the given ID and factory to create punishments of this type.
44+
* @param type the type to register
45+
* @param factory the factory to create punishments of this type
46+
*/
47+
public static void registerType(PunishmentType type, PunishmentFactory factory) {
48+
types.put(type.getId(), type);
49+
punishmentFactories.put(type, factory);
50+
}
51+
52+
/**
53+
* Retrieves a {@link PunishmentType} by its ID.
54+
* @param id the ID of the type
55+
* @return the type or null if not found
56+
*/
57+
public static PunishmentType getType(int id) {
58+
return types.get(id);
59+
}
60+
61+
/**
62+
* Creates a new punishment of the given type with the given data.
63+
* @param type the type of the punishment
64+
* @param data the data to create the punishment with
65+
* @return the created punishment
66+
* @throws IllegalStateException if no factory is registered for the given type
67+
* @throws IllegalArgumentException if the data is invalid or incomplete
68+
*/
69+
@NotNull
70+
public static Punishment createPunishment(@NotNull PunishmentType type, @NotNull Map<String, Object> data) {
71+
PunishmentFactory factory = punishmentFactories.get(type);
72+
if (factory == null) {
73+
throw new IllegalStateException("No factory registered for punishment type: " + type.getName());
74+
}
75+
return factory.createPunishment(type, data);
76+
}
77+
78+
/**
79+
* Creates a new punishment of the given type with the given data.
80+
* @param id the ID of the type
81+
* @param data the data to create the punishment with
82+
* @return the created punishment
83+
* @throws IllegalArgumentException if no punishment type is found for the given ID
84+
* @throws IllegalStateException if no factory is registered for the found type
85+
*/
86+
@NotNull
87+
public static Punishment createPunishment(int id, @NotNull Map<String, Object> data) {
88+
PunishmentType type = getType(id);
89+
if (type == null) {
90+
throw new IllegalArgumentException("No punishment type found for ID: " + id);
91+
}
92+
return createPunishment(type, data);
93+
}
94+
95+
private PunishmentTypeRegistry() {
96+
throw new UnsupportedOperationException("This class cannot be instantiated.");
97+
}
98+
}

necrify-api/src/main/java/de/jvstvshd/necrify/api/punishment/StandardPunishmentType.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,18 @@
2424

2525
package de.jvstvshd.necrify.api.punishment;
2626

27-
import java.util.HashMap;
27+
import de.jvstvshd.necrify.api.Necrify;
28+
import de.jvstvshd.necrify.api.duration.PunishmentDuration;
29+
import net.kyori.adventure.text.Component;
30+
import net.kyori.adventure.text.minimessage.MiniMessage;
31+
32+
import java.sql.Timestamp;
2833
import java.util.Map;
34+
import java.util.UUID;
2935

36+
/**
37+
* A collection of standard punishment types which are also used by the default implementation of the punishment system.
38+
*/
3039
public enum StandardPunishmentType implements PunishmentType {
3140

3241
TEMPORARY_BAN(false, "BAN", 1),
@@ -35,14 +44,6 @@ public enum StandardPunishmentType implements PunishmentType {
3544
PERMANENT_MUTE(true, "PERMANENT_MUTE", 4),
3645
KICK(false, "KICK", 5);
3746

38-
private final static Map<Integer, StandardPunishmentType> BY_ID = new HashMap<>();
39-
40-
static {
41-
for (StandardPunishmentType type : values()) {
42-
BY_ID.put(type.id, type);
43-
}
44-
}
45-
4647
private final boolean isPermanent;
4748
private final String typeString;
4849
private final int id;
@@ -62,10 +63,6 @@ public String getName() {
6263
return typeString;
6364
}
6465

65-
public static StandardPunishmentType getById(int id) {
66-
return BY_ID.get(id);
67-
}
68-
6966
@Override
7067
public int getId() {
7168
return id;

necrify-common/src/main/java/de/jvstvshd/necrify/common/AbstractNecrifyPlugin.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,15 @@
2727
import de.jvstvshd.necrify.api.Necrify;
2828
import de.jvstvshd.necrify.api.duration.PunishmentDuration;
2929
import de.jvstvshd.necrify.api.punishment.Punishment;
30+
import de.jvstvshd.necrify.api.punishment.PunishmentType;
31+
import de.jvstvshd.necrify.api.punishment.PunishmentTypeRegistry;
3032
import de.jvstvshd.necrify.api.punishment.StandardPunishmentType;
3133
import de.jvstvshd.necrify.api.user.NecrifyUser;
3234
import de.jvstvshd.necrify.common.commands.*;
35+
import de.jvstvshd.necrify.common.punishment.NecrifyBan;
3336
import de.jvstvshd.necrify.common.punishment.NecrifyKick;
37+
import de.jvstvshd.necrify.common.punishment.NecrifyPunishmentFactory;
38+
import de.jvstvshd.necrify.common.punishment.PunishmentBuilder;
3439
import net.kyori.adventure.text.Component;
3540
import net.kyori.adventure.text.format.NamedTextColor;
3641
import net.kyori.adventure.text.minimessage.MiniMessage;
@@ -46,10 +51,7 @@
4651
import org.jetbrains.annotations.NotNull;
4752
import org.slf4j.Logger;
4853

49-
import java.util.ArrayList;
50-
import java.util.Arrays;
51-
import java.util.Set;
52-
import java.util.UUID;
54+
import java.util.*;
5355
import java.util.concurrent.ExecutorService;
5456

5557
public abstract class AbstractNecrifyPlugin implements Necrify {
@@ -70,6 +72,17 @@ public AbstractNecrifyPlugin(ExecutorService executorService) {
7072
return getExecutor();
7173
}
7274

75+
/**
76+
* Registers the punishment types of the plugin to the {@link PunishmentTypeRegistry}. This method should be called
77+
* before any user-input is processed, as the registry is used to determine the type of punishment that should be created.
78+
*/
79+
public final void registerRegistries() {
80+
var registry = new NecrifyPunishmentFactory(this);
81+
for (StandardPunishmentType type : StandardPunishmentType.values()) {
82+
PunishmentTypeRegistry.registerType(type, registry);
83+
}
84+
}
85+
7386
/**
7487
* Registers commands for the plugin via the {@link AnnotationParser} from the cloud framework. It is possible to only
7588
* register the commands of the /necrify root, but also the top-level ones (e.g. /ban, /kick, etc.).
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* This file is part of Necrify (formerly Velocity Punishment), which is licensed under the MIT license.
3+
*
4+
* Copyright (c) 2022-2024 JvstvsHD
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package de.jvstvshd.necrify.common.punishment;
26+
27+
import de.jvstvshd.necrify.api.duration.PunishmentDuration;
28+
import de.jvstvshd.necrify.api.punishment.Punishment;
29+
import de.jvstvshd.necrify.api.punishment.PunishmentFactory;
30+
import de.jvstvshd.necrify.api.punishment.PunishmentType;
31+
import de.jvstvshd.necrify.api.user.NecrifyUser;
32+
import de.jvstvshd.necrify.common.AbstractNecrifyPlugin;
33+
import net.kyori.adventure.text.Component;
34+
import org.jetbrains.annotations.NotNull;
35+
36+
import java.util.Map;
37+
import java.util.UUID;
38+
39+
public class NecrifyPunishmentFactory implements PunishmentFactory {
40+
41+
private final AbstractNecrifyPlugin plugin;
42+
43+
public NecrifyPunishmentFactory(AbstractNecrifyPlugin plugin) {
44+
this.plugin = plugin;
45+
}
46+
47+
@Override
48+
public @NotNull Punishment createPunishment(@NotNull PunishmentType type, @NotNull Map<String, Object> data) {
49+
final PunishmentDuration duration = (PunishmentDuration) data.get("duration");
50+
final Component reason = (Component) data.get("reason");
51+
final UUID punishmentUuid = (UUID) data.get("punishmentUuid");
52+
final NecrifyUser user = (NecrifyUser) data.get("user");
53+
var builder = PunishmentBuilder.newBuilder(plugin)
54+
.withDuration(duration)
55+
.withReason(reason)
56+
.withUser(user)
57+
.withPunishmentUuid(punishmentUuid);
58+
Punishment punishment;
59+
switch (type.standard()) {
60+
case TEMPORARY_BAN, PERMANENT_BAN -> punishment = builder.buildBan();
61+
case TEMPORARY_MUTE, PERMANENT_MUTE -> punishment = builder.buildMute();
62+
case KICK -> punishment = builder.buildKick();
63+
default -> throw new UnsupportedOperationException("unhandled punishment type: " + type.getName());
64+
}
65+
return punishment;
66+
}
67+
}

necrify-velocity/src/main/java/de/jvstvshd/necrify/velocity/NecrifyVelocityPlugin.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ public void onProxyInitialization(ProxyInitializeEvent event) {
169169
dataSource = createDataSource();
170170
QueryConfiguration.setDefault(QueryConfiguration.builder(dataSource).setExceptionHandler(e -> logger.error("An error occurred during a database request", e)).build());
171171
punishmentManager = new DefaultPunishmentManager(server, dataSource, this);
172+
registerRegistries();
172173
this.userManager = new VelocityUserManager(getExecutor(), server, Caffeine.newBuilder().maximumSize(100).expireAfterWrite(Duration.ofMinutes(10)).build(), Caffeine.newBuilder().maximumSize(100).expireAfterWrite(Duration.ofMinutes(10)).build(), this);
173174
try {
174175
updateDatabase();

0 commit comments

Comments
 (0)