This commit is contained in:
itqop 2025-10-18 21:08:46 +03:00
parent a49affb44e
commit 215031ffff
4 changed files with 28 additions and 95 deletions

View File

@ -18,8 +18,11 @@ base {
java.toolchain.languageVersion = JavaLanguageVersion.of(21) java.toolchain.languageVersion = JavaLanguageVersion.of(21)
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
}
neoForge { neoForge {
// Specify the version of NeoForge to use.
version = project.neo_version version = project.neo_version
parchment { parchment {
@ -27,16 +30,9 @@ neoForge {
minecraftVersion = project.parchment_minecraft_version minecraftVersion = project.parchment_minecraft_version
} }
// This line is optional. Access Transformers are automatically detected
// accessTransformers.add('src/main/resources/META-INF/accesstransformer.cfg')
// Default run configurations.
// These can be tweaked, removed, or duplicated as needed.
runs { runs {
client { client {
client() client()
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
} }
@ -46,9 +42,6 @@ neoForge {
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
} }
// This run config launches GameTestServer and runs all registered gametests, then exits.
// By default, the server will crash when no gametests are provided.
// The gametest system is also enabled by default for other run configs under the /test command.
gameTestServer { gameTestServer {
type = "gameTestServer" type = "gameTestServer"
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
@ -56,73 +49,29 @@ neoForge {
data { data {
data() data()
// example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
// gameDirectory = project.file('run-data')
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
} }
// applies to all the run configs above
configureEach { configureEach {
// Recommended logging data for a userdev environment
// The markers can be added/remove as needed separated by commas.
// "SCAN": For mods scan.
// "REGISTRIES": For firing of registry events.
// "REGISTRYDUMP": For getting the contents of all registries.
systemProperty 'forge.logging.markers', 'REGISTRIES' systemProperty 'forge.logging.markers', 'REGISTRIES'
// Recommended logging level for the console
// You can set various levels here.
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
logLevel = org.slf4j.event.Level.DEBUG logLevel = org.slf4j.event.Level.DEBUG
systemProperty 'file.encoding', 'UTF-8'
} }
} }
mods { mods {
// define mod <-> source bindings
// these are used to tell the game which sources are for which mod
// mostly optional in a single mod project
// but multi mod projects should define one per mod
"${mod_id}" { "${mod_id}" {
sourceSet(sourceSets.main) sourceSet(sourceSets.main)
} }
} }
} }
// Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' } sourceSets.main.resources { srcDir 'src/generated/resources' }
dependencies { dependencies {
// Gson для работы с JSON
implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.google.code.gson:gson:2.10.1'
// Example mod dependency with JEI
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
// compileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}"
// compileOnly "mezz.jei:jei-${mc_version}-forge-api:${jei_version}"
// runtimeOnly "mezz.jei:jei-${mc_version}-forge:${jei_version}"
// Example mod dependency using a mod jar from ./libs with a flat dir repository
// This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar
// The group id is ignored when searching -- in this case, it is "blank"
// implementation "blank:coolmod-${mc_version}:${coolmod_version}"
// Example mod dependency using a file as dependency
// implementation files("libs/coolmod-${mc_version}-${coolmod_version}.jar")
// Example project dependency using a sister or child project:
// implementation project(":myproject")
// For more info:
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html
} }
// This block of code expands all declared replace properties in the specified resource targets.
// A missing property will result in an error. Properties are expanded using ${} Groovy notation.
var generateModMetadata = tasks.register("generateModMetadata", ProcessResources) { var generateModMetadata = tasks.register("generateModMetadata", ProcessResources) {
var replaceProperties = [ var replaceProperties = [
minecraft_version : minecraft_version, minecraft_version : minecraft_version,
@ -143,13 +92,9 @@ var generateModMetadata = tasks.register("generateModMetadata", ProcessResources
into "build/generated/sources/modMetadata" into "build/generated/sources/modMetadata"
} }
// Include the output of "generateModMetadata" as an input directory for the build
// this works with both building through Gradle and the IDE.
sourceSets.main.resources.srcDir generateModMetadata sourceSets.main.resources.srcDir generateModMetadata
// To avoid having to run "generateModMetadata" manually, make it run on every project reload
neoForge.ideSyncTask generateModMetadata neoForge.ideSyncTask generateModMetadata
// Example configuration to allow publishing using the maven-publish plugin
publishing { publishing {
publications { publications {
register('mavenJava', MavenPublication) { register('mavenJava', MavenPublication) {
@ -163,7 +108,6 @@ publishing {
} }
} }
// IDEA no longer automatically downloads sources/javadoc jars for dependencies, so we need to explicitly enable the behavior.
idea { idea {
module { module {
downloadSources = true downloadSources = true

View File

@ -53,14 +53,13 @@ public class WhitelistApiClient {
} }
public CompletableFuture<Boolean> addPlayer(String playerName, String reason) { public CompletableFuture<Boolean> addPlayer(String playerName, String reason) {
return addPlayer(playerName, null, null, null); return addPlayer(playerName, null, null);
} }
public CompletableFuture<Boolean> addPlayer(String playerName, String playerUuid, String addedBy, String addedAtIso) { public CompletableFuture<Boolean> addPlayer(String playerName, String addedBy, String addedAtIso) {
Objects.requireNonNull(playerName, "playerName"); Objects.requireNonNull(playerName, "playerName");
JsonObject body = new JsonObject(); JsonObject body = new JsonObject();
body.addProperty("player_name", playerName); body.addProperty("player_name", playerName);
if (playerUuid != null && !playerUuid.isBlank()) body.addProperty("player_uuid", playerUuid);
if (addedBy != null && !addedBy.isBlank()) body.addProperty("added_by", addedBy); if (addedBy != null && !addedBy.isBlank()) body.addProperty("added_by", addedBy);
if (addedAtIso != null && !addedAtIso.isBlank()) body.addProperty("added_at", addedAtIso); if (addedAtIso != null && !addedAtIso.isBlank()) body.addProperty("added_at", addedAtIso);
return makeRequest("POST", "/add", HttpRequest.BodyPublishers.ofString(GSON.toJson(body))) return makeRequest("POST", "/add", HttpRequest.BodyPublishers.ofString(GSON.toJson(body)))
@ -68,7 +67,6 @@ public class WhitelistApiClient {
} }
public CompletableFuture<WhitelistEntry> addPlayer(String playerName, public CompletableFuture<WhitelistEntry> addPlayer(String playerName,
String playerUuid,
String addedBy, String addedBy,
Instant addedAt, Instant addedAt,
Instant expiresAt, Instant expiresAt,
@ -77,7 +75,6 @@ public class WhitelistApiClient {
Objects.requireNonNull(playerName, "playerName"); Objects.requireNonNull(playerName, "playerName");
JsonObject body = new JsonObject(); JsonObject body = new JsonObject();
body.addProperty("player_name", playerName); body.addProperty("player_name", playerName);
if (playerUuid != null && !playerUuid.isBlank()) body.addProperty("player_uuid", playerUuid);
if (addedBy != null && !addedBy.isBlank()) body.addProperty("added_by", addedBy); if (addedBy != null && !addedBy.isBlank()) body.addProperty("added_by", addedBy);
if (addedAt != null) body.addProperty("added_at", addedAt.toString()); if (addedAt != null) body.addProperty("added_at", addedAt.toString());
if (expiresAt != null) body.addProperty("expires_at", expiresAt.toString()); if (expiresAt != null) body.addProperty("expires_at", expiresAt.toString());
@ -109,21 +106,18 @@ public class WhitelistApiClient {
body.addProperty("player_name", playerName); body.addProperty("player_name", playerName);
return makeRequest("POST", "/check", HttpRequest.BodyPublishers.ofString(GSON.toJson(body))) return makeRequest("POST", "/check", HttpRequest.BodyPublishers.ofString(GSON.toJson(body)))
.thenApply(response -> { .thenApply(response -> {
if (response == null) return new CheckResponse(false, false, null); if (response == null) return new CheckResponse(false, false);
try { try {
int code = response.statusCode(); int code = response.statusCode();
if (code < 200 || code >= 300) return new CheckResponse(false, false, null); if (code < 200 || code >= 300) return new CheckResponse(false, false);
JsonObject json = JsonParser.parseString(response.body()).getAsJsonObject(); JsonObject json = JsonParser.parseString(response.body()).getAsJsonObject();
boolean isWhitelisted = json.has("is_whitelisted") && json.get("is_whitelisted").getAsBoolean(); boolean isWhitelisted = json.has("is_whitelisted") && json.get("is_whitelisted").getAsBoolean();
String uuid = json.has("player_uuid") && !json.get("player_uuid").isJsonNull() return new CheckResponse(true, isWhitelisted);
? json.get("player_uuid").getAsString()
: null;
return new CheckResponse(true, isWhitelisted, uuid);
} catch (Exception e) { } catch (Exception e) {
return new CheckResponse(false, false, null); return new CheckResponse(false, false);
} }
}) })
.exceptionally(ex -> new CheckResponse(false, false, null)); .exceptionally(ex -> new CheckResponse(false, false));
} }
public CompletableFuture<WhitelistListResponse> listAll() { public CompletableFuture<WhitelistListResponse> listAll() {
@ -170,31 +164,26 @@ public class WhitelistApiClient {
public static final class CheckResponse { public static final class CheckResponse {
private final boolean success; private final boolean success;
private final boolean isWhitelisted; private final boolean isWhitelisted;
private final String playerUuid; public CheckResponse(boolean success, boolean isWhitelisted) {
public CheckResponse(boolean success, boolean isWhitelisted, String playerUuid) {
this.success = success; this.success = success;
this.isWhitelisted = isWhitelisted; this.isWhitelisted = isWhitelisted;
this.playerUuid = playerUuid;
} }
public boolean isSuccess() { return success; } public boolean isSuccess() { return success; }
public boolean isWhitelisted() { return isWhitelisted; } public boolean isWhitelisted() { return isWhitelisted; }
public String getPlayerUuid() { return playerUuid; }
} }
public static final class WhitelistEntry { public static final class WhitelistEntry {
public final String id; public final String id;
public final String playerName; public final String playerName;
public final String playerUuid;
public final String addedBy; public final String addedBy;
public final String addedAt; public final String addedAt;
public final String expiresAt; public final String expiresAt;
public final boolean isActive; public final boolean isActive;
public final String reason; public final String reason;
public WhitelistEntry(String id, String playerName, String playerUuid, String addedBy, String addedAt, String expiresAt, boolean isActive, String reason) { public WhitelistEntry(String id, String playerName, String addedBy, String addedAt, String expiresAt, boolean isActive, String reason) {
this.id = id; this.id = id;
this.playerName = playerName; this.playerName = playerName;
this.playerUuid = playerUuid;
this.addedBy = addedBy; this.addedBy = addedBy;
this.addedAt = addedAt; this.addedAt = addedAt;
this.expiresAt = expiresAt; this.expiresAt = expiresAt;
@ -205,13 +194,12 @@ public class WhitelistApiClient {
public static WhitelistEntry fromJson(JsonObject json) { public static WhitelistEntry fromJson(JsonObject json) {
String id = json.has("id") && !json.get("id").isJsonNull() ? json.get("id").getAsString() : null; String id = json.has("id") && !json.get("id").isJsonNull() ? json.get("id").getAsString() : null;
String pn = json.has("player_name") && !json.get("player_name").isJsonNull() ? json.get("player_name").getAsString() : null; String pn = json.has("player_name") && !json.get("player_name").isJsonNull() ? json.get("player_name").getAsString() : null;
String pu = json.has("player_uuid") && !json.get("player_uuid").isJsonNull() ? json.get("player_uuid").getAsString() : null;
String by = json.has("added_by") && !json.get("added_by").isJsonNull() ? json.get("added_by").getAsString() : null; String by = json.has("added_by") && !json.get("added_by").isJsonNull() ? json.get("added_by").getAsString() : null;
String at = json.has("added_at") && !json.get("added_at").isJsonNull() ? json.get("added_at").getAsString() : null; String at = json.has("added_at") && !json.get("added_at").isJsonNull() ? json.get("added_at").getAsString() : null;
String exp = json.has("expires_at") && !json.get("expires_at").isJsonNull() ? json.get("expires_at").getAsString() : null; String exp = json.has("expires_at") && !json.get("expires_at").isJsonNull() ? json.get("expires_at").getAsString() : null;
boolean active = json.has("is_active") && !json.get("is_active").isJsonNull() && json.get("is_active").getAsBoolean(); boolean active = json.has("is_active") && !json.get("is_active").isJsonNull() && json.get("is_active").getAsBoolean();
String rsn = json.has("reason") && !json.get("reason").isJsonNull() ? json.get("reason").getAsString() : null; String rsn = json.has("reason") && !json.get("reason").isJsonNull() ? json.get("reason").getAsString() : null;
return new WhitelistEntry(id, pn, pu, by, at, exp, active, rsn); return new WhitelistEntry(id, pn, by, at, exp, active, rsn);
} }
} }

View File

@ -87,12 +87,11 @@ public class WhitelistCommands {
String addedBy = getSourceName(ctx); String addedBy = getSourceName(ctx);
String addedAt = Instant.now().toString(); String addedAt = Instant.now().toString();
String uuid = resolveUuid(ctx.getSource().getServer(), player);
sendOnServer(ctx, Component.literal("Adding player to whitelist: " + player), false); sendOnServer(ctx, Component.literal("Adding player to whitelist: " + player), false);
CompletableFuture<WhitelistApiClient.WhitelistEntry> fut = CompletableFuture<WhitelistApiClient.WhitelistEntry> fut =
API.addPlayer(player, uuid, addedBy, Instant.parse(addedAt), null, true, reason); API.addPlayer(player, addedBy, Instant.parse(addedAt), null, true, reason);
fut.thenAccept(entry -> fut.thenAccept(entry ->
dispatchBack(ctx, () -> { dispatchBack(ctx, () -> {

View File

@ -6,6 +6,7 @@ import net.neoforged.neoforge.event.RegisterCommandsEvent;
import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent;
import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
@EventBusSubscriber(modid = Whitelist.MODID) @EventBusSubscriber(modid = Whitelist.MODID)
@ -20,21 +21,22 @@ public class WhitelistEventHandler {
public static void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) { public static void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
if (!Config.enableWhitelist) return; if (!Config.enableWhitelist) return;
if (!(event.getEntity() instanceof ServerPlayer sp)) return; if (!(event.getEntity() instanceof ServerPlayer sp)) return;
String name = sp.getGameProfile().getName(); String name = sp.getGameProfile().getName();
WhitelistApiClient.get().checkPlayer(name).thenAccept(resp -> { WhitelistApiClient.get().checkPlayer(name).thenAccept(resp -> {
if (resp != null && resp.isSuccess() && !resp.isWhitelisted()) { if (resp != null && resp.isSuccess() && !resp.isWhitelisted()) {
sp.server.execute(() -> { sp.server.execute(() -> {
Component msg = Component.literal("Вас нету в белом списке сервера.\n") Component link = Component.literal("https://hubmc.org/shop")
.append(
Component.literal("Для входа необходимо приобрести проходку на сайте ")
.append(
Component.literal("hubmc.org/shop")
.withStyle(style -> style .withStyle(style -> style
.withUnderlined(true) .withUnderlined(true)
.withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://hubmc.org/shop")) .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://hubmc.org/shop"))
) .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal("Открыть в браузере")))
)
); );
Component msg = Component.literal("Вас нету в белом списке сервера.\n")
.append(Component.literal("Для входа необходимо приобрести проходку на сайте "))
.append(link);
sp.connection.disconnect(msg); sp.connection.disconnect(msg);
}); });
} }