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)
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
}
neoForge {
// Specify the version of NeoForge to use.
version = project.neo_version
parchment {
@ -27,16 +30,9 @@ neoForge {
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 {
client {
client()
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
}
@ -46,9 +42,6 @@ neoForge {
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 {
type = "gameTestServer"
systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id
@ -56,73 +49,29 @@ neoForge {
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()
}
// applies to all the run configs above
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'
// 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
systemProperty 'file.encoding', 'UTF-8'
}
}
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}" {
sourceSet(sourceSets.main)
}
}
}
// Include resources generated by data generators.
sourceSets.main.resources { srcDir 'src/generated/resources' }
dependencies {
// Gson для работы с JSON
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 replaceProperties = [
minecraft_version : minecraft_version,
@ -143,13 +92,9 @@ var generateModMetadata = tasks.register("generateModMetadata", ProcessResources
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
// To avoid having to run "generateModMetadata" manually, make it run on every project reload
neoForge.ideSyncTask generateModMetadata
// Example configuration to allow publishing using the maven-publish plugin
publishing {
publications {
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 {
module {
downloadSources = true

View File

@ -53,14 +53,13 @@ public class WhitelistApiClient {
}
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");
JsonObject body = new JsonObject();
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 (addedAtIso != null && !addedAtIso.isBlank()) body.addProperty("added_at", addedAtIso);
return makeRequest("POST", "/add", HttpRequest.BodyPublishers.ofString(GSON.toJson(body)))
@ -68,7 +67,6 @@ public class WhitelistApiClient {
}
public CompletableFuture<WhitelistEntry> addPlayer(String playerName,
String playerUuid,
String addedBy,
Instant addedAt,
Instant expiresAt,
@ -77,7 +75,6 @@ public class WhitelistApiClient {
Objects.requireNonNull(playerName, "playerName");
JsonObject body = new JsonObject();
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 (addedAt != null) body.addProperty("added_at", addedAt.toString());
if (expiresAt != null) body.addProperty("expires_at", expiresAt.toString());
@ -109,21 +106,18 @@ public class WhitelistApiClient {
body.addProperty("player_name", playerName);
return makeRequest("POST", "/check", HttpRequest.BodyPublishers.ofString(GSON.toJson(body)))
.thenApply(response -> {
if (response == null) return new CheckResponse(false, false, null);
if (response == null) return new CheckResponse(false, false);
try {
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();
boolean isWhitelisted = json.has("is_whitelisted") && json.get("is_whitelisted").getAsBoolean();
String uuid = json.has("player_uuid") && !json.get("player_uuid").isJsonNull()
? json.get("player_uuid").getAsString()
: null;
return new CheckResponse(true, isWhitelisted, uuid);
return new CheckResponse(true, isWhitelisted);
} 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() {
@ -170,31 +164,26 @@ public class WhitelistApiClient {
public static final class CheckResponse {
private final boolean success;
private final boolean isWhitelisted;
private final String playerUuid;
public CheckResponse(boolean success, boolean isWhitelisted, String playerUuid) {
public CheckResponse(boolean success, boolean isWhitelisted) {
this.success = success;
this.isWhitelisted = isWhitelisted;
this.playerUuid = playerUuid;
}
public boolean isSuccess() { return success; }
public boolean isWhitelisted() { return isWhitelisted; }
public String getPlayerUuid() { return playerUuid; }
}
public static final class WhitelistEntry {
public final String id;
public final String playerName;
public final String playerUuid;
public final String addedBy;
public final String addedAt;
public final String expiresAt;
public final boolean isActive;
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.playerName = playerName;
this.playerUuid = playerUuid;
this.addedBy = addedBy;
this.addedAt = addedAt;
this.expiresAt = expiresAt;
@ -205,13 +194,12 @@ public class WhitelistApiClient {
public static WhitelistEntry fromJson(JsonObject json) {
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 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 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;
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;
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 addedAt = Instant.now().toString();
String uuid = resolveUuid(ctx.getSource().getServer(), player);
sendOnServer(ctx, Component.literal("Adding player to whitelist: " + player), false);
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 ->
dispatchBack(ctx, () -> {

View File

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