Skip to content

Commit

Permalink
fold in pechkin
Browse files Browse the repository at this point in the history
  • Loading branch information
BasiqueEvangelist committed Aug 6, 2024
1 parent ba9c260 commit 0aa2c22
Show file tree
Hide file tree
Showing 20 changed files with 1,012 additions and 0 deletions.
15 changes: 15 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ configurations {

loom {
accessWidenerPath = file("src/main/resources/pingspam.accesswidener")

runs {
clientTester1 {
client()
ideConfigGenerated true
name = "Client (Tester 1)"
programArgs("--username", "Tester1")
}
clientTester2 {
client()
ideConfigGenerated true
name = "Client (Tester 2)"
programArgs("--username", "Tester2")
}
}
}

repositories {
Expand Down
52 changes: 52 additions & 0 deletions src/main/java/me/basiqueevangelist/pechkin/ConfigManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package me.basiqueevangelist.pechkin;


import blue.endless.jankson.Jankson;
import blue.endless.jankson.api.SyntaxError;
import net.fabricmc.loader.api.FabricLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class ConfigManager {
private static final Jankson JANKSON = Jankson.builder().build();
private static final Logger LOGGER = LoggerFactory.getLogger("Pechkin/ConfigManager");

private PechkinConfig config = new PechkinConfig();

public ConfigManager() {
load();
}

public PechkinConfig getConfig() {
return config;
}

public void load() {
Path confPath = FabricLoader.getInstance().getConfigDir().resolve("pechkin.json5");
if (Files.exists(confPath)) {
try {
config = JANKSON.fromJson(JANKSON.load(confPath.toFile()), PechkinConfig.class);
} catch (IOException | SyntaxError e) {
LOGGER.error("Could not load config file!", e);
}
} else {
save();
}
}

public void save() {
Path confPath = FabricLoader.getInstance().getConfigDir().resolve("pechkin.json5");
try {
try (BufferedWriter bw = Files.newBufferedWriter(confPath)) {
bw.write(JANKSON.toJson(config).toJson(true, true));
}
} catch (IOException e) {
LOGGER.error("Could not load config file!", e);
}
}
}
36 changes: 36 additions & 0 deletions src/main/java/me/basiqueevangelist/pechkin/Pechkin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package me.basiqueevangelist.pechkin;

import me.basiqueevangelist.onedatastore.api.Component;
import me.basiqueevangelist.onedatastore.api.PlayerDataEntry;
import me.basiqueevangelist.pechkin.command.*;
import me.basiqueevangelist.pechkin.data.PechkinPlayerData;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.Identifier;

import java.lang.ref.WeakReference;

public class Pechkin implements ModInitializer {
public static final ConfigManager CONFIG = new ConfigManager();
public static WeakReference<MinecraftServer> server;

public static final Component<PechkinPlayerData, PlayerDataEntry> PLAYER_DATA = Component.registerPlayer(new Identifier("pechkin", "player_data"), PechkinPlayerData::new);

@Override
public void onInitialize() {
ServerLifecycleEvents.SERVER_STARTING.register(s -> {
server = new WeakReference<>(s);
});

CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
SendCommand.register(dispatcher);
ListCommand.register(dispatcher);
DeleteCommand.register(dispatcher);
IgnoreCommand.register(dispatcher);
ClearCommand.register(dispatcher);
ReloadCommand.register(dispatcher);
});
}
}
17 changes: 17 additions & 0 deletions src/main/java/me/basiqueevangelist/pechkin/PechkinConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package me.basiqueevangelist.pechkin;

import blue.endless.jankson.Comment;

public class PechkinConfig {
@Comment("The maximum amount of messages a player's inbox can have.")
public int maxInboxMessages = 100;

@Comment("The amount of players that will be stored in the player's correspondents list. Used for command suggestions.")
public int maxCorrespondents = 10;

@Comment("The maximum amount of time debt a player's leaky bucket can have.")
public int maxTimeDebt = 120;

@Comment("The cost of sending a single message.")
public int sendCost = 30;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package me.basiqueevangelist.pechkin.command;

import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import me.basiqueevangelist.onedatastore.api.DataStore;
import me.basiqueevangelist.pechkin.Pechkin;
import me.basiqueevangelist.pechkin.data.PechkinPlayerData;
import me.basiqueevangelist.pechkin.util.CommandUtil;
import me.basiqueevangelist.pingspam.utils.NameUtil;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.minecraft.command.argument.GameProfileArgumentType;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.*;
import net.minecraft.util.Formatting;

import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal;

public final class ClearCommand {
private ClearCommand() {

}

public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
dispatcher.register(literal("mail")
.then(literal("clear")
.executes(ClearCommand::clear)
.then(argument("player", GameProfileArgumentType.gameProfile())
.requires(Permissions.require("pechkin.clear.other", 2))
.suggests(CommandUtil::suggestPlayersExceptSelf)
.executes(ClearCommand::clearOther))));
}

private static int clear(CommandContext<ServerCommandSource> ctx) throws CommandSyntaxException {
ServerCommandSource src = ctx.getSource();
ServerPlayerEntity player = src.getPlayer();
PechkinPlayerData data = DataStore.getFor(src.getServer()).getPlayer(player.getUuid(), Pechkin.PLAYER_DATA);

Text sent = Text.literal("Deleted " + data.messages().size() + " message" + (data.messages().size() == 1 ? "" : "s") + " from your inbox.")
.formatted(Formatting.GREEN);

data.messages().clear();

src.sendFeedback(() -> sent, false);

return 1;
}

private static int clearOther(CommandContext<ServerCommandSource> ctx) throws CommandSyntaxException {
ServerCommandSource src = ctx.getSource();
GameProfile player = CommandUtil.getOnePlayer(ctx, "player");
PechkinPlayerData data = DataStore.getFor(src.getServer()).getPlayer(player.getId(), Pechkin.PLAYER_DATA);

Text sent = Text.literal("Deleted " + data.messages().size() + " message" + (data.messages().size() == 1 ? "" : "s") + " from ")
.append(Text.literal(NameUtil.getNameFromUUID(player.getId())).formatted(Formatting.AQUA))
.append("'s inbox.")
.formatted(Formatting.GREEN);

data.messages().clear();

src.sendFeedback(() -> sent, true);

return 1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package me.basiqueevangelist.pechkin.command;

import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import me.basiqueevangelist.onedatastore.api.DataStore;
import me.basiqueevangelist.pechkin.Pechkin;
import me.basiqueevangelist.pechkin.data.PechkinPlayerData;
import me.basiqueevangelist.pechkin.hack.StateTracker;
import me.basiqueevangelist.pechkin.util.CommandUtil;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.minecraft.command.argument.GameProfileArgumentType;
import net.minecraft.command.argument.UuidArgumentType;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;

import java.util.UUID;

import static net.minecraft.server.command.CommandManager.argument;
import static net.minecraft.server.command.CommandManager.literal;

public final class DeleteCommand {
private static final SimpleCommandExceptionType MESSAGE_DOESNT_EXIST = new SimpleCommandExceptionType(Text.literal("No such message"));

private DeleteCommand() {

}

public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
dispatcher.register(literal("mail")
.then(literal("internal")
.requires(x -> !StateTracker.IS_IN_COMMAND_TREE_CREATION)
.then(literal("delete_list")
.then(argument("message", UuidArgumentType.uuid())
.executes(DeleteCommand::deleteList)))
.then(literal("delete_list_other")
.requires(Permissions.require("pechkin.list.other", 2))
.requires(Permissions.require("pechkin.delete.other", 2))
.then(argument("player", GameProfileArgumentType.gameProfile())
.then(argument("message", UuidArgumentType.uuid())
.executes(DeleteCommand::deleteListOther))))
.then(literal("delete_silent")
.then(argument("message", UuidArgumentType.uuid())
.executes(DeleteCommand::deleteSilent)))));
}

private static int deleteSilent(CommandContext<ServerCommandSource> ctx) throws CommandSyntaxException {
ServerCommandSource src = ctx.getSource();
ServerPlayerEntity player = src.getPlayer();
UUID messageId = UuidArgumentType.getUuid(ctx, "message");
PechkinPlayerData data = DataStore.getFor(src.getServer()).getPlayer(player.getUuid(), Pechkin.PLAYER_DATA);

data.messages().removeIf(x -> x.messageId().equals(messageId));

return 1;
}

private static int deleteList(CommandContext<ServerCommandSource> ctx) throws CommandSyntaxException {
ServerCommandSource src = ctx.getSource();
ServerPlayerEntity player = src.getPlayer();
UUID messageId = UuidArgumentType.getUuid(ctx, "message");
PechkinPlayerData data = DataStore.getFor(src.getServer()).getPlayer(player.getUuid(), Pechkin.PLAYER_DATA);

if (!data.messages().removeIf(x -> x.messageId().equals(messageId))) {
throw MESSAGE_DOESNT_EXIST.create();
}

src.sendFeedback(() -> Text.literal("\n\n"), false);

// Resend the list, since this command will only be invoked via list anyway 🚎
ListCommand.list(ctx);

return 1;
}

private static int deleteListOther(CommandContext<ServerCommandSource> ctx) throws CommandSyntaxException {
ServerCommandSource src = ctx.getSource();
UUID messageId = UuidArgumentType.getUuid(ctx, "message");
GameProfile player = CommandUtil.getOnePlayer(ctx, "player");
PechkinPlayerData data = DataStore.getFor(src.getServer()).getPlayer(player.getId(), Pechkin.PLAYER_DATA);

if (!data.messages().removeIf(x -> x.messageId().equals(messageId))) {
throw MESSAGE_DOESNT_EXIST.create();
}

src.sendFeedback(() -> Text.literal("\n\n"), false);

// Resend the list, since this command will only be invoked via list anyway 🚎
ListCommand.listOther(ctx);

return 1;
}
}
Loading

0 comments on commit 0aa2c22

Please sign in to comment.