General fixes. Works.

Formatted source files.
Fixed command-line arguments processing.
Added ability to specify logging levels by name (ALL, FINE, FINER...)

Generally fixed unnoticed problems in Configuration and Priestess
classes. Stopped spuriously committing configuration file path to
preferences store, changed some Priestess methods to use her own
tokenizer, and fixed a null check in setCultableChannels method.
This commit is contained in:
Sandy Mossgrave 2023-05-07 19:56:57 +00:00
parent 7d97078e43
commit f2eec77df0
14 changed files with 1508 additions and 1504 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
/priestessconfig.txt
/priestessconfig.txtbkup
/target/
dependency-reduced-pom.xml

View File

@ -26,8 +26,8 @@ public class Command {
private static final Logger log = Logger.getLogger(Priestess.class.getName());
public static void replyTo(Message m, String s){
if(m != null){
public static void replyTo(Message m, String s) {
if (m != null) {
m.getChannel().block().createMessage(s).withMessageReference(m.getId()).block();
} else {
log.log(Level.INFO, s);
@ -35,10 +35,10 @@ public class Command {
}
static void tryAll(String commandline, Message m, int permissionLevel) {
for(String s: commands.keySet()){
if(commandline.startsWith(s)){
for (String s : commands.keySet()) {
if (commandline.startsWith(s)) {
log.log(Level.INFO, "Matched command " + s);
switch(commands.get(s).tryExecuteCommand(commandline, permissionLevel, m)){
switch (commands.get(s).tryExecuteCommand(commandline, permissionLevel, m)) {
case SUCCESS:
return;
case BADPERM:
@ -65,11 +65,11 @@ public class Command {
* @param a
* @return
*/
public CommandStatus tryExecuteCommand(String commandline, int permissionLevel, Message m){
if(!commandline.startsWith(this.name)){
public CommandStatus tryExecuteCommand(String commandline, int permissionLevel, Message m) {
if (!commandline.startsWith(this.name)) {
return NOMATCH;
}
if(permissionLevel < this.permissionLevel){
if (permissionLevel < this.permissionLevel) {
return BADPERM;
}
String payload = commandline.substring(this.namelen).trim();
@ -77,16 +77,16 @@ public class Command {
return SUCCESS;
}
public Command setCallback(Callback c){
public Command setCallback(Callback c) {
this.callback = c;
return this;
}
Command(String name, int permissionLevel){
Command(String name, int permissionLevel) {
this.name = name;
this.namelen = name.length();
this.permissionLevel = permissionLevel;
this.callback = new Callback(){
this.callback = new Callback() {
@Override
public Publisher<Mono> apply(CommandArgs t) {
t.replyWith(String.format("Callback for function %s not registered", name));
@ -96,13 +96,14 @@ public class Command {
};
}
public static void registerCommand(Command c){
public static void registerCommand(Command c) {
commands.put(c.name, c);
}
/*= "use emoji";
public static final String REPLYTO_COMMAND = "reply to";
public static final String SENDTO_COMMAND = "send to";*/
/*
* = "use emoji"; public static final String REPLYTO_COMMAND = "reply to";
* public static final String SENDTO_COMMAND = "send to";
*/
/**
* @return the name
@ -111,9 +112,9 @@ public class Command {
return name;
}
public static Command commandThatJustRepliesWith(String name, String reply){
public static Command commandThatJustRepliesWith(String name, String reply) {
Command c = new Command(name, 1);
c.setCallback(new Callback(){
c.setCallback(new Callback() {
@Override
public Publisher<Mono> apply(CommandArgs t) {

View File

@ -37,7 +37,7 @@ public class CommandArgs {
return payload;
}
public void replyWith(String s){
public void replyWith(String s) {
Command.replyTo(m, s);
}

View File

@ -9,8 +9,5 @@ package com.tinyplantnews.priestess;
* @author atomb
*/
public enum CommandStatus {
NOMATCH,
SUCCESS,
FAILURE,
BADPERM;
NOMATCH, SUCCESS, FAILURE, BADPERM;
}

View File

@ -30,8 +30,10 @@ import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
/**
* "Ms Merry," you may say, "You literally import the Preferences class, and yet
* you insist on writing your own configuration store. Why?" "Iunno," I reply.
*
* @author twi
* @author sandy
*/
public class Configuration {
@ -67,9 +69,9 @@ public class Configuration {
if (Files.exists(Paths.get(DEFAULT_CONFIG_FILE_NAME), LinkOption.NOFOLLOW_LINKS)) {
return DEFAULT_CONFIG_FILE_NAME;
}
//JDialog jd = new JDialog();
//jd.add(new JLabel("Choose where to put Priestess Working Directory"));
//jd.setVisible(true);
// JDialog jd = new JDialog();
// jd.add(new JLabel("Choose where to put Priestess Working Directory"));
// jd.setVisible(true);
JOptionPane.showConfirmDialog(null, "Select where cult files will be stored.");
JFileChooser jfc = new JFileChooser("Config File for Discord Cult Priestess");
jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
@ -80,15 +82,9 @@ public class Configuration {
if (rv == JFileChooser.APPROVE_OPTION) {
File f = jfc.getSelectedFile();
if (f.isDirectory() && f.canRead() && f.canWrite()) {
prefs.put(CONFIG_FILE_KEY, f.getAbsolutePath());
try {
prefs.flush();
} catch (BackingStoreException e) {
log.log(Level.WARNING, "Backing store exception while committing configuration file path to persistent storage {0}", e.getMessage());
}
return f.getAbsolutePath();
}
} else if(rv == JFileChooser.CANCEL_OPTION) {
} else if (rv == JFileChooser.CANCEL_OPTION) {
return "";
}
@ -104,13 +100,14 @@ public class Configuration {
}
try {
if (Files.isDirectory(Paths.get(CONFIG_FILE_LOCATION), LinkOption.NOFOLLOW_LINKS)) {
CONFIG_FILE_LOCATION = CONFIG_FILE_LOCATION + System.getProperty("file.separator") + DEFAULT_CONFIG_FILE_NAME;
CONFIG_FILE_LOCATION = CONFIG_FILE_LOCATION + System.getProperty("file.separator")
+ DEFAULT_CONFIG_FILE_NAME;
}
BufferedReader br = new BufferedReader(new FileReader(Paths.get(CONFIG_FILE_LOCATION).toFile()));
br.lines().forEach((s) -> {
String key = s.substring(0, s.indexOf(delimiter));
if (s.length() == s.indexOf(delimiter) + delimiter.length()) {
System.out.println("read empty value for key (" + key + ") from configuration file");
log.log(Level.FINE, "read empty value for key (" + key + ") from configuration file");
configuration.put(key, "");
} else {
String value = s.substring(s.indexOf(delimiter) + delimiter.length());
@ -119,7 +116,8 @@ public class Configuration {
});
} catch (FileNotFoundException ex) {
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, "Error loading configuration file from (" + CONFIG_FILE_LOCATION + ") {0}", ex);
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE,
"Error loading configuration file from (" + CONFIG_FILE_LOCATION + ") {0}", ex);
}
}
@ -137,6 +135,14 @@ public class Configuration {
CONFIG_FILE_LOCATION = aCONFIG_FILE_LOCATION;
if (persistent) {
props.setProperty(CONFIG_FILE_KEY, CONFIG_FILE_LOCATION);
prefs.put(CONFIG_FILE_KEY, CONFIG_FILE_LOCATION);
try {
prefs.flush();
} catch (BackingStoreException e) {
log.log(Level.WARNING,
"Backing store exception while committing configuration file path to persistent storage {0}",
e.getMessage());
}
}
}
@ -161,18 +167,20 @@ public class Configuration {
try {
Files.copy(Paths.get(CONFIG_FILE_LOCATION), Paths.get(CONFIG_FILE_LOCATION + "bkup"));
} catch (IOException ioe) {
if(ioe instanceof NoSuchFileException) {
if (ioe instanceof NoSuchFileException) {
log.log(Level.FINE, "No existing configuration file--not creating backup");
} else {
log.log(Level.WARNING, "Exception encountered while trying to create configuration file backup: {0}", ioe);
log.log(Level.WARNING,
"Exception encountered while trying to create configuration file backup: {0}", ioe);
}
}
} catch (IOException ex) {
Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
System.err.println("Making backup configuration file failed. Exiting without committing configuration to file");
System.err.println(
"Making backup configuration file failed. Exiting without committing configuration to file");
return;
}
try ( BufferedWriter br = new BufferedWriter(new FileWriter(Paths.get(CONFIG_FILE_LOCATION).toFile(), false))) {
try (BufferedWriter br = new BufferedWriter(new FileWriter(Paths.get(CONFIG_FILE_LOCATION).toFile(), false))) {
configuration.forEach((key, value) -> {
try {
br.append(key + delimiter + value + "\n");

View File

@ -23,12 +23,11 @@ class GuildProfile {
g = g1;
}
private HashMap<String, Snowflake> customemojis = new HashMap<>();
private HashMap<String, Snowflake> approvingcustomemojis = new HashMap<>();
//Just so it's seekable, for the random approving emoji methods.
// Just so it's seekable, for the random approving emoji methods.
private ArrayList<String> approvingcustomemojinames = new ArrayList<>();
/**
@ -71,11 +70,7 @@ class GuildProfile {
}
public GuildEmoji getEmojiByNumber(int i) {
return g.getGuildEmojiById(
approvingcustomemojis.get(approvingcustomemojinames
.get(i)
)
).block();
return g.getGuildEmojiById(approvingcustomemojis.get(approvingcustomemojinames.get(i))).block();
}
}

View File

@ -59,9 +59,9 @@ public class InstantiableConfiguration {
if (Files.exists(Paths.get(DEFAULT_CONFIG_FILE_NAME), LinkOption.NOFOLLOW_LINKS)) {
return DEFAULT_CONFIG_FILE_NAME;
}
//JDialog jd = new JDialog();
//jd.add(new JLabel("Choose where to put Priestess Working Directory"));
//jd.setVisible(true);
// JDialog jd = new JDialog();
// jd.add(new JLabel("Choose where to put Priestess Working Directory"));
// jd.setVisible(true);
JOptionPane.showConfirmDialog(null, "Select where cult files will be stored.");
JFileChooser jfc = new JFileChooser("Config File for Discord Cult Priestess");
jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
@ -89,7 +89,8 @@ public class InstantiableConfiguration {
}
try {
if (Files.isDirectory(Paths.get(CONFIG_FILE_LOCATION), LinkOption.NOFOLLOW_LINKS)) {
CONFIG_FILE_LOCATION = CONFIG_FILE_LOCATION + System.getProperty("file.separator") + DEFAULT_CONFIG_FILE_NAME;
CONFIG_FILE_LOCATION = CONFIG_FILE_LOCATION + System.getProperty("file.separator")
+ DEFAULT_CONFIG_FILE_NAME;
}
BufferedReader br = new BufferedReader(new FileReader(Paths.get(CONFIG_FILE_LOCATION).toFile()));
br.lines().forEach((s) -> {
@ -104,7 +105,8 @@ public class InstantiableConfiguration {
});
} catch (FileNotFoundException ex) {
Logger.getLogger(InstantiableConfiguration.class.getName()).log(Level.SEVERE, "Error loading configuration file from (" + CONFIG_FILE_LOCATION + ") {0}", ex);
Logger.getLogger(InstantiableConfiguration.class.getName()).log(Level.SEVERE,
"Error loading configuration file from (" + CONFIG_FILE_LOCATION + ") {0}", ex);
}
}
@ -146,14 +148,16 @@ public class InstantiableConfiguration {
try {
Files.copy(Paths.get(CONFIG_FILE_LOCATION), Paths.get(CONFIG_FILE_LOCATION + "bkup"));
} catch (IOException ioe) {
log.log(Level.WARNING, "Exception encountered while trying to create confirguation file backup: {0}", ioe);
log.log(Level.WARNING, "Exception encountered while trying to create confirguation file backup: {0}",
ioe);
}
} catch (IOException ex) {
Logger.getLogger(InstantiableConfiguration.class.getName()).log(Level.SEVERE, null, ex);
System.err.println("Making backup configuration file failed. Exiting without committing configuration to file");
System.err.println(
"Making backup configuration file failed. Exiting without committing configuration to file");
return;
}
try ( BufferedWriter br = new BufferedWriter(new FileWriter(Paths.get(CONFIG_FILE_LOCATION).toFile(), false))) {
try (BufferedWriter br = new BufferedWriter(new FileWriter(Paths.get(CONFIG_FILE_LOCATION).toFile(), false))) {
configuration.forEach((key, value) -> {
try {
br.append(key + delimiter + value + "\n");

View File

@ -45,6 +45,7 @@ public class JKRSONTag {
public void setVal(String val) {
this.val = val;
}
private String key;
private String val;

View File

@ -17,6 +17,14 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
* OH IT STORES THE PROPHECIES
*
* The configuration file (priestessconfig.txt) contains a key, 'messages', for which the value is a path to the messages store.
* The messages store contains prophecies that are given every few bean goose invocations.
* This class first loads the file, scans it and generates a list of indices for the messages it contains.
*
* This class could definitely use a cache of the message starts--a special block at the beginning/end of the file with a list of message starts/ends,
* but I'm not up to writing that today - 7 May 2023
*
* @author atomb
*/
@ -32,8 +40,10 @@ public class MessageStore {
Thread t;
private boolean messagesCached = false;
private long loadStart = Long.MAX_VALUE;
public MessageStore(File f1) throws FileNotFoundException, IOException {
loadStart = System.nanoTime();
f = new RandomAccessFile(f1.getPath(), "r");
System.out.println("Message store is " + f.length() + " bytes long");
fr = f.getChannel();
@ -102,7 +112,7 @@ public class MessageStore {
log.setLevel(Level.FINE);
log.log(Level.INFO, "Attempting to characterize message store");
try {
ArrayList<Integer> messagestartsal = new ArrayList<>(); //contains index of every '{'
ArrayList<Integer> messagestartsal = new ArrayList<>(); // contains index of every '{'
char c;
int a = 0;
int i = 0;
@ -131,7 +141,10 @@ public class MessageStore {
System.out.println("Found invocation message at position " + i);
}
messagesCached = true;
}
long loadEnd = System.nanoTime();
long tdiff = loadEnd - loadStart;
log.log(Level.FINE, "Prophecies loaded in {0} ms", tdiff);
}
}
}

View File

@ -1,4 +1,6 @@
/*
:q:q
qqqqqqqq:qdf
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Project/Maven2/JavaApp/src/main/java/${packagePath}/${mainClassName}.java to edit this template
*/
@ -52,8 +54,9 @@ public class Priestess {
private static void trySetDebugLevel(String level) {
try {
debug_level = Integer.parseInt(level);
log.setLevel(new CustomLoggingLevel(debug_level));
Level new_debug_level = Level.parse(level);
log.setLevel(new_debug_level);
debug_level = new_debug_level.intValue();
log.log(Level.INFO, "Logging level set to {0}", level);
} catch (NumberFormatException nfe) {
log.log(Level.WARNING, "Invalid custom logging level ({0})", level);
@ -96,14 +99,7 @@ public class Priestess {
private static boolean allChannelsCultable = false;
private String[] approvingEmojis = {
"U+1F44D",
"U+270C",
"U+1F525",
"U+2764",
"U+1F496",
"U+1F63B"
};
private String[] approvingEmojis = { "U+1F44D", "U+270C", "U+1F525", "U+2764", "U+1F496", "U+1F63B" };
private int invocationsThisSession = 0;
@ -117,21 +113,28 @@ public class Priestess {
if (args[i].startsWith("--")) {
System.out.println("Command-line switch (" + args[i] + ") detected.");
switch (args[i].substring(2)) {
String yarg = args[i].substring(2, args[i].indexOf('='));
switch (yarg) {
case "config-file":
Configuration.setCONFIG_FILE_LOCATION(yarg, false);
i++;
Configuration.setCONFIG_FILE_LOCATION(args[i], false);
break;
case "config-file-persistent":
Configuration.setCONFIG_FILE_LOCATION(yarg, true);
i++;
Configuration.setCONFIG_FILE_LOCATION(args[i], true);
break;
case "debug-level":
String newlevel = args[i].substring(args[i].indexOf('=')+1);
Configuration.setConfigurationParameter(DEBUG_LEVEL, newlevel);
trySetDebugLevel(newlevel);
i++;
Configuration.setConfigurationParameter(DEBUG_LEVEL, args[i]);
trySetDebugLevel(args[i]);
break;
//There is precisely no reason for me to include this.
case "debug":
Configuration.setConfigurationParameter(DEBUG_LEVEL, Level.ALL.toString());
trySetDebugLevel(yarg);
i++;
break;
// There is precisely no reason for me to include this.
case "windows-lineendings":
NEWLINE = "\r\n";
break;
@ -140,7 +143,7 @@ public class Priestess {
log.log(Level.INFO, "Listening to all channels in joined guilds.");
break;
default:
log.log(Level.INFO, "Unknown command-line argument: {0}", yarg);
}
}
}
@ -153,7 +156,8 @@ public class Priestess {
}
private void registerEmoji(Guild g, Snowflake emojiFlake, String emojiName) {
System.out.println(String.format("\nCustom Emoji Detected: \nServer:\t%s\nFlake:\t%s\nName:\t%s", g, emojiFlake, emojiName));
System.out.println(String.format("\nCustom Emoji Detected: \nServer:\t%s\nFlake:\t%s\nName:\t%s", g, emojiFlake,
emojiName));
if (!guildemojimaps.containsKey(g)) {
guildemojimaps.put(g, new GuildProfile(g));
}
@ -187,7 +191,7 @@ public class Priestess {
String commandline = cdr(magicPhrase, c);
System.out.println("Attempting to run command (" + commandline + ") with permission level " + permissionLevel);
Command.tryAll(commandline, m, permissionLevel); //System.out.println("payload " + payload);
Command.tryAll(commandline, m, permissionLevel); // System.out.println("payload " + payload);
return Mono.empty();
}
@ -201,10 +205,8 @@ public class Priestess {
Guild g = m.getGuild().block();
GuildProfile gp = guildemojimaps.get(g);
if (gp == null) {
log.log(Level.INFO,
"Message from unregistered guild, "
+ "not registering now.");
//register guild?
log.log(Level.INFO, "Message from unregistered guild, " + "not registering now.");
// register guild?
return Mono.empty();
}
@ -218,15 +220,16 @@ public class Priestess {
};
Function<MessageCreateEvent, Publisher<Mono>> directmessagehandler = (var t) -> {
//System.out.println("ya boi");
// System.out.println("ya boi");
Message m = t.getMessage();
String c = m.getContent();
log.log(Level.FINE, "processing direct message {0}", c);
log.log(Level.FINE, "User snowflake for message {0} is {1}", new Object[]{c, m.getAuthor().get().getId().asString()});
log.log(Level.FINE, "User snowflake for message {0} is {1}",
new Object[] { c, m.getAuthor().get().getId().asString() });
if (c.equalsIgnoreCase(magicPhrase)) {
//System.out.println("approved");
// System.out.println("approved");
m.addReaction(ReactionEmoji.codepoints(randomApprovingEmoji())).subscribe();
} else if (c.startsWith(magicPhrase)) {
return dispatchCommand(t, m, c);
@ -249,7 +252,7 @@ public class Priestess {
log.log(Level.INFO, String.format("Starting Priestess normally"));
}
setup();
if(botToken.isBlank()) {
if (botToken.isBlank()) {
log.log(Level.SEVERE, "bot token is null. aborting.");
return;
}
@ -272,27 +275,23 @@ public class Priestess {
guildnames.put(g.getName(), g);
}
return Mono.empty();
}
).subscribe();
}).subscribe();
dc.getGuilds().flatMap((g)
-> g.getChannels().flatMap((channel) -> {
dc.getGuilds().flatMap((g) -> g.getChannels().flatMap((channel) -> {
log.log(Level.INFO, "Checking cultability of channel {0}", channel.getName());
if (channel.getName().equals(cultChannelName)) {
System.out.println("Channel " + channel.getName() + " in " + g.getName() + " is cultable");
log.log(Level.INFO, "Channel " + channel.getName() + " in " + g.getName() + " is cultable");
cultableChannelIDs.add(channel.getId());
}
return Mono.empty();
})
).subscribe();
})).subscribe();
dc.getGuilds().flatMap(g -> g.getEmojis()).flatMap(g2 -> {
//system.out.println("emoji");
// system.out.println("emoji");
registerEmoji(g2.getGuild().block(), g2.getId(), g2.getName());
return Mono.empty();
}
).subscribe();
}).subscribe();
dc.on(ConnectEvent.class, event -> {
@ -312,12 +311,10 @@ public class Priestess {
flywheel.put("System.in listener", t);
dc.on(MessageCreateEvent.class).filter(event -> !event.getMessage().getAuthor().get().isBot())
.filter(g -> !g.getGuild().blockOptional().isEmpty()).flatMap(guildedmessagehandler)
.subscribe();
.filter(g -> !g.getGuild().blockOptional().isEmpty()).flatMap(guildedmessagehandler).subscribe();
dc.on(MessageCreateEvent.class).filter(event -> !event.getMessage().getAuthor().get().isBot())
.filter(g -> g.getGuild().blockOptional().isEmpty()).flatMap(directmessagehandler)
.blockLast();
.filter(g -> g.getGuild().blockOptional().isEmpty()).flatMap(directmessagehandler).blockLast();
}
private int invocationsBeforeThisSession = 0;
@ -348,7 +345,8 @@ public class Priestess {
ms = setupMessageStore();
long free0 = Runtime.getRuntime().freeMemory();
log.log(Level.FINE, "Initialization complete. approx. {0} bytes free in memory.\n Attempting garbage collection.", free0);
log.log(Level.FINE,
"Initialization complete. approx. {0} bytes free in memory.\n Attempting garbage collection.", free0);
Runtime.getRuntime().gc();
long free1 = Runtime.getRuntime().freeMemory();
long freediff = free1 - free0;
@ -384,7 +382,8 @@ public class Priestess {
private void invokeDeity(Guild g, Message m) {
int ae_custom = guildemojimaps.get(g).approvingEmojiCount();
int emojicount = approvingEmojis.length + ae_custom;
//System.out.println(approvingEmojis.length + " default, " + ae_custom + " custom approving emojis.");
// System.out.println(approvingEmojis.length + " default, " + ae_custom + "
// custom approving emojis.");
int which = (int) (Math.random() * emojicount);
if (which < approvingEmojis.length) {
m.addReaction(ReactionEmoji.codepoints(randomApprovingEmoji())).subscribe();
@ -446,8 +445,7 @@ public class Priestess {
private void dispatchMilestone(int i, Guild g, Message m) {
if ((i % 5) == 0) {
MessageCreateSpec mcs = MessageCreateSpec.create()
.withMessageReference(m.getId())
MessageCreateSpec mcs = MessageCreateSpec.create().withMessageReference(m.getId())
.withContent(randomMessage());
m.getChannel().block().createMessage(mcs).subscribe();
}
@ -475,9 +473,11 @@ public class Priestess {
for (String token : tokens) {
String sflake = token.substring(0, token.indexOf(subtokenDelimiter));
String perm = token.substring(token.indexOf(subtokenDelimiter) + subtokenDelimiter.length(), token.length());
String perm = token.substring(token.indexOf(subtokenDelimiter) + subtokenDelimiter.length(),
token.length());
System.out.println("Adding snowflake (" + sflake + ") to whitelist with permission level (" + perm + ").");
System.out.println(
"Adding snowflake (" + sflake + ") to whitelist with permission level (" + perm + ").");
Snowflake a = Snowflake.of(sflake);
@ -486,6 +486,9 @@ public class Priestess {
}
}
/*
*
*/
private MessageStore setupMessageStore() {
String mesglist = Configuration.getConfigurationParameter(MESSAGES);
File f = Paths.get(mesglist).toFile();
@ -494,7 +497,7 @@ public class Priestess {
return ms1;
} catch (IOException e) {
if (!f.exists()) {
log.log(Level.WARNING, "Message store file does not exist.");
} else {
log.log(Level.SEVERE, e.getMessage());
}
@ -554,7 +557,8 @@ public class Priestess {
StringBuilder s = new StringBuilder();
boolean inQuote = false;
for (char c : payload.toCharArray()) {
//log.log(Level.FINE, String.format("c: %c, inQuote: %s", c, (inQuote ? "yes" : "no")));
// log.log(Level.FINE, String.format("c: %c, inQuote: %s", c, (inQuote ? "yes" :
// "no")));
if (!inQuote && c == '\"') {
inQuote = true;
tryPush(a, s);
@ -581,24 +585,25 @@ public class Priestess {
/**
* I wanted the replacement string to be {xxxx} without the dollar sign, but
* unit tests failed when the help/usage was nothing but {xxxx}. Instead of
* investigating, I gave up and added a dollar sign to make it something
* like Python's f-strings. Or JS' backtick-strings, I can never remember
* which is which.
* investigating, I gave up and added a dollar sign to make it something like
* Python's f-strings. Or JS' backtick-strings, I can never remember which is
* which.
*/
public static class Callback implements Function<CommandArgs, Publisher<Mono>> {
final Logger log = Logger.getLogger(Callback.class.getName());
String[] usages = {"Undefined command usage"};
String[] usages = { "Undefined command usage" };
String help = "${usage}";
@Override
public Publisher<Mono> apply(CommandArgs t) {
throw new UnsupportedOperationException("Not supported yet."); // Generated from nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
throw new UnsupportedOperationException("Not supported yet."); // Generated from
// nbfs://nbhost/SystemFileSystem/Templates/Classes/Code/GeneratedMethodBody
}
public String getHelp(String commandName) {
String s = getUsage(commandName);
return help/*.replaceAll("\\$\\{usage\\}", s)*/.replaceAll("\\$\\{commandname\\}", commandName);
return help/* .replaceAll("\\$\\{usage\\}", s) */.replaceAll("\\$\\{commandname\\}", commandName);
}
public String getUsage(String commandName) {
@ -619,12 +624,7 @@ public class Priestess {
public final Callback registerEmojiCommand = new Callback() {
String usage = "{commandname} EMOJI";
String help
= "register emoji for use in basic invocations."
+ ""
+ ""
+ ""
+ "";
String help = "register emoji for use in basic invocations." + "" + "" + "" + "";
@Override
public Publisher<Mono> apply(CommandArgs o) {
@ -688,7 +688,7 @@ public class Priestess {
@Override
public Publisher<Mono> apply(CommandArgs o) {
String pay2 = cdr("set", o.getPayload());
String[] paytokens = pay2.split(" ");
String[] paytokens = tokenize(pay2);
if (paytokens.length == 2) {
log.log(Level.INFO, "setting configuration parameter " + paytokens[0] + " to " + paytokens[1]);
Configuration.setConfigurationParameter(paytokens[0], paytokens[1]);
@ -740,7 +740,7 @@ public class Priestess {
return t.getName().equals(tokens[1]);
}
}).blockFirst();
if (g != null) {
if (c != null) {
if (tokens.length == 3) {
if (isAffirmative(tokens[2])) {
cultableChannelIDs.add(c.getId());
@ -805,15 +805,12 @@ public class Priestess {
return Mono.empty();
}
Guild a = resolveGuildByNameOrId(arglist[0]);
//guildnames.get(arglist[0]);
// guildnames.get(arglist[0]);
/*
for (Object a0 : guildnames.entrySet().toArray()) {
Map.Entry<String, Guild> a3 = (Map.Entry<String, Guild>) a0;
Guild a1 = (Guild) a3.getValue();
if (a1.getId().asString().equals(arglist[0])) {
a = a1;
}
}*/
* for (Object a0 : guildnames.entrySet().toArray()) { Map.Entry<String, Guild>
* a3 = (Map.Entry<String, Guild>) a0; Guild a1 = (Guild) a3.getValue(); if
* (a1.getId().asString().equals(arglist[0])) { a = a1; } }
*/
if (a == null) {
o.replyWith("Could not find guild");
@ -856,7 +853,8 @@ public class Priestess {
Command.registerCommand(new Command("send to", 1).setCallback(sendToCommand));
Command.registerCommand(new Command("cult", 9000).setCallback(setCultableChannelsCommand));
Command.registerCommand(new Command("perm", 0).setCallback(permissionLevelCommand));
Command.registerCommand(Command.commandThatJustRepliesWith("is minecraft online", "i dunno log on and find out smfh"));
Command.registerCommand(
Command.commandThatJustRepliesWith("is minecraft online", "i dunno log on and find out smfh"));
}

View File

@ -34,34 +34,26 @@ public class PriestessTest {
@org.junit.jupiter.api.Test
public void testMain() {
System.out.println("main");
String[] args = {"testsuite"};
String[] args = { "testsuite" };
Priestess.main(args);
}
@org.junit.jupiter.api.Test
public void testCallbackHelpTexts(){
public void testCallbackHelpTexts() {
assertEquals("boi", "son".replaceAll("son", "boi"));
Priestess p = new Priestess();
p.shutdownCommand.help = "ha boi";
testCallbackHelpText(p.shutdownCommand,
"shut down",
"ha boi");
testCallbackHelpText(p.shutdownCommand, "shut down", "ha boi");
p.shutdownCommand.help = "${commandname}";
testCallbackHelpText(p.shutdownCommand,
"shut down",
"shut down");
testCallbackHelpText(p.shutdownCommand, "shut down", "shut down");
p.shutdownCommand.help = "${commandname} turns off the entire internet";
testCallbackHelpText(p.shutdownCommand,
"shut down",
"shut down turns off the entire internet");
testCallbackHelpText(p.shutdownCommand, "shut down", "shut down turns off the entire internet");
}
private void testCallbackHelpText(Priestess.Callback c, String name, String expHelp){
private void testCallbackHelpText(Priestess.Callback c, String name, String expHelp) {
String help = c.getHelp(name);
Assertions.assertEquals(expHelp, help);
}
@ -71,25 +63,19 @@ public class PriestessTest {
*/
@Test
public void testTokenize() {
testTokenize1("a",
new String[]{"a"});
testTokenize1("a, b",
new String[]{"a,", "b"});
testTokenize1("ya boi",
new String[]{"ya", "boi"});
//Should handle these trivially. Single quotes not special.
testTokenize1("'''' ''' ' '''",
new String[]{"''''", "'''", "'", "'''"});
testTokenize1("*^@^$/><::;''",
new String[]{"*^@^$/><::;''"});
testTokenize1("*^@^$/> <::;''",
new String[]{"*^@^$/>", "<::;''"});
testTokenize1("this is not quoted, \"this is\"",
new String[]{"this", "is", "not", "quoted,", "this is"});
testTokenize1("this is not quoted, \"this is",
null);
/*testTokenize1("this is not quoted, \\\"this is",
new String[]{"this", "is", "not", "quoted,", "\"this is"});*/
testTokenize1("a", new String[] { "a" });
testTokenize1("a, b", new String[] { "a,", "b" });
testTokenize1("ya boi", new String[] { "ya", "boi" });
// Should handle these trivially. Single quotes not special.
testTokenize1("'''' ''' ' '''", new String[] { "''''", "'''", "'", "'''" });
testTokenize1("*^@^$/><::;''", new String[] { "*^@^$/><::;''" });
testTokenize1("*^@^$/> <::;''", new String[] { "*^@^$/>", "<::;''" });
testTokenize1("this is not quoted, \"this is\"", new String[] { "this", "is", "not", "quoted,", "this is" });
testTokenize1("this is not quoted, \"this is", null);
/*
* testTokenize1("this is not quoted, \\\"this is", new String[]{"this", "is",
* "not", "quoted,", "\"this is"});
*/
}
private void testTokenize1(String payload, String[] expResult) {