Compare commits
7 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 173bed6a10 | |||
| edf08fc750 | |||
| e743be7615 | |||
| ab0a01b12f | |||
| fcf4d43010 | |||
| 38c557fa12 | |||
| 2c91899055 |
10 changed files with 118 additions and 18 deletions
|
|
@ -7,6 +7,11 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.util.formatting.text.serializer.plain.PlainComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import net.kyori.adventure.text.serializer.json.JSONComponentSerializer;
|
||||||
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
@ -14,6 +19,7 @@ import org.bukkit.Server;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
|
@ -215,26 +221,52 @@ public class CoreProtectAPI extends Queue {
|
||||||
/**
|
/**
|
||||||
* Logs a chat message for a player.
|
* Logs a chat message for a player.
|
||||||
*
|
*
|
||||||
* @param player
|
* @param sender
|
||||||
* The player who sent the message
|
* The player who sent the message
|
||||||
* @param message
|
* @param message
|
||||||
* The chat message
|
* The chat message
|
||||||
* @return True if the message was logged
|
* @return True if the message was logged
|
||||||
*/
|
*/
|
||||||
public boolean logChat(Player player, String message) {
|
public boolean logChat(CommandSender sender, String message) {
|
||||||
|
Player player = null;
|
||||||
|
if (sender instanceof Player) {
|
||||||
|
player = (Player) sender;
|
||||||
if (!isEnabledForPlayer(player) || !Config.getConfig(player.getWorld()).PLAYER_MESSAGES) {
|
if (!isEnabledForPlayer(player) || !Config.getConfig(player.getWorld()).PLAYER_MESSAGES) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (message == null || message.isEmpty() || message.startsWith("/")) {
|
if (message == null || message.isEmpty() || message.startsWith("/")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
long timestamp = System.currentTimeMillis() / 1000L;
|
long timestamp = System.currentTimeMillis() / 1000L;
|
||||||
Queue.queuePlayerChat(player, message, timestamp);
|
if(player == null) Queue.queueChat(sender, message, timestamp);
|
||||||
|
else Queue.queuePlayerChat(player, message, timestamp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a componentized chat message for a player.
|
||||||
|
*
|
||||||
|
* @param sender
|
||||||
|
* The player who sent the message
|
||||||
|
* @param component
|
||||||
|
* The chat message
|
||||||
|
* @return True if the message was logged
|
||||||
|
*/
|
||||||
|
public boolean logChat(CommandSender sender, Component component) {
|
||||||
|
return logChat(sender, MiniMessage.miniMessage().serialize(component));
|
||||||
|
}
|
||||||
|
// API Stub
|
||||||
|
public boolean logChat(Player sender, String message) {
|
||||||
|
return logChat((CommandSender) sender, message);
|
||||||
|
}
|
||||||
|
// API Stub
|
||||||
|
public boolean logChat(Player sender, Component component) {
|
||||||
|
return logChat(sender, MiniMessage.miniMessage().serialize(component));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs a command executed by a player.
|
* Logs a command executed by a player.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,14 @@ public class CommandHandler implements CommandExecutor {
|
||||||
public boolean onCommand(CommandSender user, Command command, String commandLabel, String[] argumentArray) {
|
public boolean onCommand(CommandSender user, Command command, String commandLabel, String[] argumentArray) {
|
||||||
String commandName = command.getName().toLowerCase(Locale.ROOT);
|
String commandName = command.getName().toLowerCase(Locale.ROOT);
|
||||||
|
|
||||||
|
// Griefus begin
|
||||||
|
if (commandName.equals("coi") || commandName.equals("gusi")) {
|
||||||
|
boolean permission = user.hasPermission("coreprotect.inspect");
|
||||||
|
InspectCommand.runCommand(user, permission, argumentArray);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Griefus end
|
||||||
|
|
||||||
if (commandName.equals("core") || commandName.equals("coreprotect") || commandName.equals("co") || commandName.equals("griefus") || commandName.equals("gus")) {
|
if (commandName.equals("core") || commandName.equals("coreprotect") || commandName.equals("co") || commandName.equals("griefus") || commandName.equals("gus")) {
|
||||||
int resultc = argumentArray.length;
|
int resultc = argumentArray.length;
|
||||||
if (resultc > -1) {
|
if (resultc > -1) {
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,11 @@ public class StandardLookupThread implements Runnable {
|
||||||
String rbd = ((Integer.parseInt(data[8]) == 2 || Integer.parseInt(data[8]) == 3) ? Color.STRIKETHROUGH : "");
|
String rbd = ((Integer.parseInt(data[8]) == 2 || Integer.parseInt(data[8]) == 3) ? Color.STRIKETHROUGH : "");
|
||||||
String timeago = ChatUtils.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
|
String timeago = ChatUtils.getTimeSince(Integer.parseInt(time), unixtimestamp, true);
|
||||||
Material blockType = ItemUtils.itemFilter(MaterialUtils.getType(dtype), (Integer.parseInt(data[13]) == 0));
|
Material blockType = ItemUtils.itemFilter(MaterialUtils.getType(dtype), (Integer.parseInt(data[13]) == 0));
|
||||||
String dname = StringUtils.nameFilter(blockType.name().toLowerCase(Locale.ROOT), ddata);
|
|
||||||
|
// Griefus begin
|
||||||
|
//String dname = StringUtils.nameFilter(blockType.name().toLowerCase(Locale.ROOT), ddata);
|
||||||
|
String dname = MaterialUtils.asTranslatable(blockType);
|
||||||
|
// Griefus end
|
||||||
byte[] metadata = data[11] == null ? null : data[11].getBytes(StandardCharsets.ISO_8859_1);
|
byte[] metadata = data[11] == null ? null : data[11].getBytes(StandardCharsets.ISO_8859_1);
|
||||||
String tooltip = ItemUtils.getEnchantments(metadata, dtype, amount);
|
String tooltip = ItemUtils.getEnchantments(metadata, dtype, amount);
|
||||||
|
|
||||||
|
|
@ -362,13 +366,19 @@ public class StandardLookupThread implements Runnable {
|
||||||
isPlayer = true;
|
isPlayer = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dname = EntityUtils.getEntityType(dtype).name();
|
// Griefus begin
|
||||||
|
// dname = EntityUtils.getEntityType(dtype).name();
|
||||||
|
dname = EntityUtils.asTranslatable(EntityUtils.getEntityType(dtype));
|
||||||
|
// Griefus end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dname = MaterialUtils.getType(dtype).name().toLowerCase(Locale.ROOT);
|
// Griefus begin
|
||||||
dname = StringUtils.nameFilter(dname, ddata);
|
//dname = MaterialUtils.getType(dtype).name().toLowerCase(Locale.ROOT);
|
||||||
|
//dname = StringUtils.nameFilter(dname, ddata);
|
||||||
|
dname = MaterialUtils.asTranslatable(MaterialUtils.getType(dtype));
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if (dname.length() > 0 && !isPlayer) {
|
if (dname.length() > 0 && !isPlayer) {
|
||||||
dname = "minecraft:" + dname.toLowerCase(Locale.ROOT) + "";
|
dname = "minecraft:" + dname.toLowerCase(Locale.ROOT) + "";
|
||||||
}
|
}
|
||||||
|
|
@ -378,6 +388,8 @@ public class StandardLookupThread implements Runnable {
|
||||||
String[] blockNameSplit = dname.split(":");
|
String[] blockNameSplit = dname.split(":");
|
||||||
dname = blockNameSplit[1];
|
dname = blockNameSplit[1];
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
// Griefus end
|
||||||
|
|
||||||
// Functions.sendMessage(player2, timeago+" " + ChatColors.WHITE + "- " + ChatColors.DARK_AQUA+rbd+""+dplayer+" " + ChatColors.WHITE+rbd+""+a+" " + ChatColors.DARK_AQUA+rbd+"#"+dtype+ChatColors.WHITE + ". " + ChatColors.GREY + "(x"+x+"/y"+y+"/z"+z+")");
|
// Functions.sendMessage(player2, timeago+" " + ChatColors.WHITE + "- " + ChatColors.DARK_AQUA+rbd+""+dplayer+" " + ChatColors.WHITE+rbd+""+a+" " + ChatColors.DARK_AQUA+rbd+"#"+dtype+ChatColors.WHITE + ". " + ChatColors.GREY + "(x"+x+"/y"+y+"/z"+z+")");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import org.bukkit.block.data.Bisected;
|
||||||
import org.bukkit.block.data.Bisected.Half;
|
import org.bukkit.block.data.Bisected.Half;
|
||||||
import org.bukkit.block.data.type.Bed;
|
import org.bukkit.block.data.type.Bed;
|
||||||
import org.bukkit.block.data.type.Bed.Part;
|
import org.bukkit.block.data.type.Bed.Part;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
@ -303,6 +304,14 @@ public class Queue {
|
||||||
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, new Object[] { timestamp, player.getLocation().clone() });
|
queueStandardData(consumerId, currentConsumer, new String[] { player.getName(), null }, new Object[] { timestamp, player.getLocation().clone() });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static void queueChat(CommandSender sender, String message, long timestamp) {
|
||||||
|
int currentConsumer = Consumer.currentConsumer;
|
||||||
|
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||||
|
addConsumer(currentConsumer, new Object[] { consumerId, Process.PLAYER_CHAT, null, 0, null, 0, 0, null });
|
||||||
|
Consumer.consumerStrings.get(currentConsumer).put(consumerId, message);
|
||||||
|
queueStandardData(consumerId, currentConsumer, new String[] { sender.getName(), null }, new Object[] { timestamp, null });
|
||||||
|
}
|
||||||
|
|
||||||
protected static void queuePlayerCommand(Player player, String message, long timestamp) {
|
protected static void queuePlayerCommand(Player player, String message, long timestamp) {
|
||||||
int currentConsumer = Consumer.currentConsumer;
|
int currentConsumer = Consumer.currentConsumer;
|
||||||
int consumerId = Consumer.newConsumerId(currentConsumer);
|
int consumerId = Consumer.newConsumerId(currentConsumer);
|
||||||
|
|
|
||||||
|
|
@ -109,24 +109,30 @@ public class BlockLookup {
|
||||||
|
|
||||||
String target;
|
String target;
|
||||||
if (resultAction == 3) {
|
if (resultAction == 3) {
|
||||||
target = EntityUtils.getEntityType(resultType).name();
|
// Griefus begin
|
||||||
|
//target = EntityUtils.getEntityType(resultType).name();
|
||||||
|
target = EntityUtils.asTranslatable(EntityUtils.getEntityType(resultType));
|
||||||
|
// Griefus end
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Material resultMaterial = MaterialUtils.getType(resultType);
|
Material resultMaterial = MaterialUtils.getType(resultType);
|
||||||
if (resultMaterial == null) {
|
if (resultMaterial == null) {
|
||||||
resultMaterial = Material.AIR;
|
resultMaterial = Material.AIR;
|
||||||
}
|
}
|
||||||
target = StringUtils.nameFilter(resultMaterial.name().toLowerCase(Locale.ROOT), resultData);
|
// Griefus begin
|
||||||
target = "minecraft:" + target.toLowerCase(Locale.ROOT);
|
//target = StringUtils.nameFilter(resultMaterial.name().toLowerCase(Locale.ROOT), resultData);
|
||||||
|
//target = "minecraft:" + target.toLowerCase(Locale.ROOT);
|
||||||
|
target = MaterialUtils.asTranslatable(resultMaterial);
|
||||||
}
|
}
|
||||||
if (target.length() > 0) {
|
/*if (target.length() > 0) {
|
||||||
target = "" + target + "";
|
target = "" + target + "";
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Hide "minecraft:" for now.
|
// Hide "minecraft:" for now. - do not!!
|
||||||
if (target.startsWith("minecraft:")) {
|
/*if (target.startsWith("minecraft:")) {
|
||||||
target = target.split(":")[1];
|
target = target.split(":")[1];
|
||||||
}
|
} */
|
||||||
|
// Griefus end
|
||||||
|
|
||||||
resultTextBuilder.append(timeAgo + " " + tag + " ").append(Phrase.build(phrase, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, Color.DARK_AQUA + rbFormat + target + Color.WHITE, selector)).append("\n");
|
resultTextBuilder.append(timeAgo + " " + tag + " ").append(Phrase.build(phrase, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, Color.DARK_AQUA + rbFormat + target + Color.WHITE, selector)).append("\n");
|
||||||
PluginChannelListener.getInstance().sendData(commandSender, resultTime, phrase, selector, resultUser, target, -1, x, y, z, worldId, rbFormat, false, tag.contains("+"));
|
PluginChannelListener.getInstance().sendData(commandSender, resultTime, phrase, selector, resultUser, target, -1, x, y, z, worldId, rbFormat, false, tag.contains("+"));
|
||||||
|
|
@ -150,7 +156,10 @@ public class BlockLookup {
|
||||||
// resultText = Color.WHITE + "No block data found at " + Color.ITALIC + "x" + x + "/y" + y + "/z" + z + ".";
|
// resultText = Color.WHITE + "No block data found at " + Color.ITALIC + "x" + x + "/y" + y + "/z" + z + ".";
|
||||||
resultText = Phrase.build(Phrase.NO_DATA_LOCATION, Selector.FIRST);
|
resultText = Phrase.build(Phrase.NO_DATA_LOCATION, Selector.FIRST);
|
||||||
if (!blockName.equals("air") && !blockName.equals("cave_air")) {
|
if (!blockName.equals("air") && !blockName.equals("cave_air")) {
|
||||||
resultText = Phrase.build(Phrase.NO_DATA, Color.ITALIC + block.getType().name().toLowerCase(Locale.ROOT) + Color.WHITE) + "\n";
|
// Griefus begin
|
||||||
|
//resultText = Phrase.build(Phrase.NO_DATA, Color.ITALIC + block.getType().name().toLowerCase(Locale.ROOT) + Color.WHITE) + "\n";
|
||||||
|
resultText = Phrase.build(Phrase.NO_DATA, Color.ITALIC + MaterialUtils.asTranslatable(block.getType()) + Color.WHITE) + "\n";
|
||||||
|
// Griefus end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,9 @@ public class ChestTransactionLookup {
|
||||||
if (resultMaterial == null) {
|
if (resultMaterial == null) {
|
||||||
resultMaterial = Material.AIR;
|
resultMaterial = Material.AIR;
|
||||||
}
|
}
|
||||||
|
// Griefus begin
|
||||||
|
String target = MaterialUtils.asTranslatable(resultMaterial);
|
||||||
|
/*
|
||||||
String target = resultMaterial.name().toLowerCase(Locale.ROOT);
|
String target = resultMaterial.name().toLowerCase(Locale.ROOT);
|
||||||
target = StringUtils.nameFilter(target, resultData);
|
target = StringUtils.nameFilter(target, resultData);
|
||||||
if (target.length() > 0) {
|
if (target.length() > 0) {
|
||||||
|
|
@ -122,6 +125,8 @@ public class ChestTransactionLookup {
|
||||||
if (target.startsWith("minecraft:")) {
|
if (target.startsWith("minecraft:")) {
|
||||||
target = target.split(":")[1];
|
target = target.split(":")[1];
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
// Griefus end
|
||||||
|
|
||||||
result.add(new StringBuilder(timeAgo + " " + tag + " " + Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, "x" + resultAmount, ChatUtils.createTooltip(Color.DARK_AQUA + rbFormat + target, tooltip) + Color.WHITE, selector)).toString());
|
result.add(new StringBuilder(timeAgo + " " + tag + " " + Phrase.build(Phrase.LOOKUP_CONTAINER, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, "x" + resultAmount, ChatUtils.createTooltip(Color.DARK_AQUA + rbFormat + target, tooltip) + Color.WHITE, selector)).toString());
|
||||||
PluginChannelListener.getInstance().sendData(commandSender, resultTime, Phrase.LOOKUP_CONTAINER, selector, resultUser, target, resultAmount, x, y, z, worldId, rbFormat, true, tag.contains("+"));
|
PluginChannelListener.getInstance().sendData(commandSender, resultTime, Phrase.LOOKUP_CONTAINER, selector, resultUser, target, resultAmount, x, y, z, worldId, rbFormat, true, tag.contains("+"));
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,9 @@ public class InteractionLookup {
|
||||||
if (resultMaterial == null) {
|
if (resultMaterial == null) {
|
||||||
resultMaterial = Material.AIR;
|
resultMaterial = Material.AIR;
|
||||||
}
|
}
|
||||||
|
// Griefus begin
|
||||||
|
String target = MaterialUtils.asTranslatable(resultMaterial);
|
||||||
|
/*
|
||||||
String target = resultMaterial.name().toLowerCase(Locale.ROOT);
|
String target = resultMaterial.name().toLowerCase(Locale.ROOT);
|
||||||
target = StringUtils.nameFilter(target, resultData);
|
target = StringUtils.nameFilter(target, resultData);
|
||||||
if (target.length() > 0) {
|
if (target.length() > 0) {
|
||||||
|
|
@ -110,6 +113,8 @@ public class InteractionLookup {
|
||||||
if (target.startsWith("minecraft:")) {
|
if (target.startsWith("minecraft:")) {
|
||||||
target = target.split(":")[1];
|
target = target.split(":")[1];
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
// Griefus end
|
||||||
|
|
||||||
resultBuilder.append(timeAgo + " " + Color.WHITE + "- ").append(Phrase.build(Phrase.LOOKUP_INTERACTION, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, Color.DARK_AQUA + rbFormat + target + Color.WHITE, Selector.FIRST)).append("\n");
|
resultBuilder.append(timeAgo + " " + Color.WHITE + "- ").append(Phrase.build(Phrase.LOOKUP_INTERACTION, Color.DARK_AQUA + rbFormat + resultUser + Color.WHITE + rbFormat, Color.DARK_AQUA + rbFormat + target + Color.WHITE, Selector.FIRST)).append("\n");
|
||||||
PluginChannelListener.getInstance().sendData(commandSender, resultTime, Phrase.LOOKUP_INTERACTION, Selector.FIRST, resultUser, target, -1, x, y, z, worldId, rbFormat, false, false);
|
PluginChannelListener.getInstance().sendData(commandSender, resultTime, Phrase.LOOKUP_INTERACTION, Selector.FIRST, resultUser, target, -1, x, y, z, worldId, rbFormat, false, false);
|
||||||
|
|
|
||||||
|
|
@ -137,4 +137,8 @@ public class EntityUtils extends Queue {
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String asTranslatable(EntityType type){
|
||||||
|
return "<lang:" + type.translationKey() + ">";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package net.coreprotect.utility;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
||||||
import net.coreprotect.config.ConfigHandler;
|
import net.coreprotect.config.ConfigHandler;
|
||||||
|
|
@ -213,4 +214,9 @@ public class MaterialUtils extends Queue {
|
||||||
return isInventory ? 2 : 1;
|
return isInventory ? 2 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Griefus
|
||||||
|
public static String asTranslatable(Material material) {
|
||||||
|
return "<lang:" + material.translationKey() + ">";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,16 @@ commands:
|
||||||
permission: coreprotect.griefus
|
permission: coreprotect.griefus
|
||||||
permission-message: §3Griefus §f- You do not have permission to do that.
|
permission-message: §3Griefus §f- You do not have permission to do that.
|
||||||
usage: /<command> <params>
|
usage: /<command> <params>
|
||||||
|
coi:
|
||||||
|
description: Inspector mode shortcut
|
||||||
|
permission: coreprotect.inspect
|
||||||
|
permission-message: §3Griefus §f- You do not have permission to do that.
|
||||||
|
usage: /<command> <params>
|
||||||
|
gusi:
|
||||||
|
description: Inspector mode shortcut
|
||||||
|
permission: coreprotect.inspect
|
||||||
|
permission-message: §3Griefus §f- You do not have permission to do that.
|
||||||
|
usage: /<command> <params>
|
||||||
permissions:
|
permissions:
|
||||||
coreprotect.*:
|
coreprotect.*:
|
||||||
description: Gives access to all Griefus actions and commands
|
description: Gives access to all Griefus actions and commands
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue