how to add more than one prefix - JDA - java

I would like to know how could I add more than one prefix to my discord bot?
This is my current prefix listener code, the prefix is being pulled from a .env
final long guildId = event.getGuild().getIdLong();
String prefix = Config.get("PREFIX");
String raw = event.getMessage().getContentRaw();
if (raw.startsWith(prefix)) {
manager.handle(event, prefix);
}
Currently my bot's prefix is based on mention <#!ID>, but this type of mention doesn't work on mobile discord (mobile discord uses only <#ID> for mention, without the "!"), so I would like to add both variants to be used on my bot.
I was told I could use regex for that but I have no clue how it works and how to apply it to my code.

Just define a second prefix and check, if the message starts with one of them.
final long guildId = event.getGuild().getIdLong();
String prefix1 = Config.get("PREFIX1");
String prefix2 = Config.get("PREFIX2");
String raw = event.getMessage().getContentRaw();
if (raw.startsWith(prefix1) || raw.startsWith(prefix2) {
//...
}

Related

How do I get an object from a String

I am working on a project, where users can write other users mails. The mail-class looks currently like this:
public class Mail
{
/*
* Fields
*/
private final String _content;
private final String _sender;
private final String _date;
private final String _topic;
/**
* Constructor of the Mail-class.
*
* #param mail The mail as a string representation.
*/
public Mail(String mail)
{
_content = ...;
_sender = ...;
_date = ...;
_topic = ...;
}
// And all the getters.
#Override
public String toString()
{
// Make the reperentation as a String
}
Now, the problem is, that I need to save all the mails into a .yml userdata file. For me, the simplest way to do this is to firstly convert every mail to a String and then save all mails into a List<String> mails which will be written directly into the .yml where I can access and read the list of String with ease. Now, once I start the server, all mails should be converted back into the object-representation. The question is, how can I save the mail-Object as a String and load it, that I can operate using those mail objects.
My first ideas were something like this sender#date#topic#content and then splitting the String via String.split("#");. But when I do this, I need to ban the # character for the content and the topic. The date and the username will never contain #. I don't want to ban any character. Unfortunately I have nothing found on my researches so far on how to solve this task.
The best thing to do is use XML or JSON to markup the object and convert it to a string for you. There are tons of libraries you can use to do that. They all operate in roughly the same manner: add an annotations to your fields and class.

HttpServer Request get date range from query string

I am new to Java and Vertx and I have a query string with the following format:
GET /examples/1/data?date_1[gt]=2021-09-28&date_1[lt]=2021-10-28
Here I have this date_1 parameter which is within a certain range. I have been using HttpServerRequest class to extract simple parameters like integers but not sure how to proceed with these kind of range parameters.
With the simple parameters, I can do something like:
String param = request.getParam(paramName);
paramAsInteger = Integer.valueOf(paramAsString);
However, confused as to how to deal with the gt and lt options and the fact that we have same parameter twice.
You say that you have difficulties parsing out these tokens. Here's how you can handle this.
The first thing to understand is that the parameter name is NOT "date1"
There are actually two parameters here
2.1. "date_1[gt]" with a value of "2021-09-28"
2.2. "date_1[lt]" with a value of "2021-10-28"
This is because in the URI parameter definition everything before the "=" sign is the parameter name and everything after is the parameter value.
You can just do
String dateAsString = request.getParam("date1[gt]");
paramAsInteger = toDate(dateAsString)
To implement the toDate() function read this simple article how to convert a string object into a data object using a standard library
(link)
Vert.x will treat these parameters as two separate ones. So RoutingContext#queryParam("date_1[gt]") will only give you the value for [gt]. If you want the value for [lt] you need to get that separately.
That being said, you can move this tedious logic into an extra handler and store the values in the RoutingContext. Something like this might be easier:
private void extractDates(RoutingContext ctx) {
var startDate = ctx.queryParam("date_1[gt]");
var endDate = ctx.queryParam("date_1[lt]");
var parsedStartDate = DateTimeFormatter.ISO_LOCAL_DATE.parse(startDate.get(0));
var parsedEndDate = DateTimeFormatter.ISO_LOCAL_DATE.parse(endDate.get(0));
// things we put in the context here can be retrieved by later handlers
ctx.put("startDate", parsedStartDate);
ctx.put("endDate", parsedEndDate);
ctx.next();
}
Then, in your actual handler you can access the two dates as follows:
router.get("/date")
.handler(this::extractDates)
.handler(ctx -> {
var responseBody = ctx.get("startDate") + " - " + ctx.get("endDate");
ctx.end(responseBody);
});
This allows you to keep your actual business logic concise.

How to extract a String from a changing template in Java?

I have a question regarding best practices considering Java regular expressions/Strings manipulation.
I have a changing String template, let's say this time it looks like this:
/get/{id}/person
I have another String that matches this pattern eg.
/get/1234ewq/person
Keep in mind that the pattern could change anytime, slashes could disappear etc.
I would like to extract the difference between the two of them i.e. the result of the processing would be 1234ewq.
I know I could iterate over them char by char and compare, but, if it is possible, I wanted to find some smart approach to it with regular expressions.
What would be the best Java approach?
Thank you.
For you to answer your question with a regex approach I built a small example class which should hint you into a direction you could go with this (see below).
The problem with this approach is that you dynamically create a regular expression that depends on your template strings. This means that you have to somehow verify that your templates do not interfere with the regex compilation and matching process itself.
Also atm if you would use the same placeholder multiple times within a template the resulting HashMap only contains the value for the last placeholder mapping of that kind.
Normally this is the expected behaviour but this depends on your strategy of filling your templates.
For template processing in general you could have a look at the mustache library.
Also as Uli Sotschok mentioned, you probably would be better of with using something like google-diff-match-patch.
public class StringExtractionFromTemplate {
public static void main(String[] args) {
String template = "/get/{id}/person";
String filledTemplate = "/get/1234ewq/person";
System.out.println(diffTemplateInsertion(template, filledTemplate).get("id"));
}
private static HashMap<String, String> diffTemplateInsertion(String template, String filledTemplate){
//language=RegExp
String placeHolderPattern = "\\{(.+)}";
HashMap<String, String> templateTranslation = new HashMap<>();
String regexedTemplate = template.replaceAll(placeHolderPattern, "(.+)");
Pattern pattern = Pattern.compile(regexedTemplate);
Matcher templateMatcher = pattern.matcher(template);
Matcher filledTemplateMatcher = pattern.matcher(filledTemplate);
while (templateMatcher.find() && filledTemplateMatcher.find()) {
if(templateMatcher.groupCount() == filledTemplateMatcher.groupCount()){
for (int i = 1; i <= templateMatcher.groupCount(); i++) {
templateTranslation.put(
templateMatcher.group(i).replaceAll(placeHolderPattern,"$1"),
filledTemplateMatcher.group(i)
);
}
}
}
return templateTranslation;
}
}

Parse a query string parameter to java object

I have query string like that:
ObjectGUId=1abcde&ObjectType=2&ObjectTitle=maximumoflife&Content=racroi&TimeStamp=2012-11-05T17:20:06.056
And I have Java Object:
LogObject{
private String ObjectGUId;
private String ObjectType;
private String ObjectTitle;
private String Content;
private String TimeStamp;
}
So i want to parse this query string to this java Object.
I've searched and read many question but not gotten correct answer yet.
Show me what can solve this problem.
Inspired by #bruno.braga, here's a way using Apache http-components. You leverage all the parsing corner cases:
List<NameValuePair> params =
URLEncodedUtils.parse("http://example.com/?" + queryString, Charset.forName("UTF-8"));
That'll give you a List of NameValuePair objects that should be easy to work with.
If you do not really need to push the querystring into your own class (you might want that though), instead of parsing it manually, you could use the URLDecoder, as #Sonrobby has commented:
String qString = "ObjectGUId=1abcde&ObjectType=2&ObjectTitle=maximumoflife";
Uri uri = Uri.parse(URLDecoder.decode("http://dummy/?" + qString, "UTF-8"));
if (uri != null) {
for(String key: uri.getQueryParameterNames()) {
System.out.println("key=[" + key + "], value=[" + uri.getQueryParameter(key) + "]");
}
}
The "dummy" looks dirty but it is required if what you only have is the querystring values (qString). If you have the complete URL, just pass it directly to the URLDecoder, and you are done.
Etiquette
You really should be much more specific about what you have tried and why it didn't work.
A proper code sample of your LogObject would really be very helpful here.
Ideally, you would provide a SSCCE so others could easily test your problem themselves.
Answer
You can extract the name:value pairs like this:
String toParse = "ObjectGUId=1abcde&ObjectType=2&ObjectTitle=maximumoflife&Content=racroi&TimeStamp=2012-11-05T17:20:06.056";
String[] fields = toParse.split("&");
String[] kv;
HashMap<String, String> things = new HashMap<String, String>();
for (int i = 0; i < fields.length; ++i)
{
t = fields[i].split("=");
if (2 == kv.length)
{
things.put(kv[0], kv[1]);
}
}
I have chosen to put them into a HashMap, but you could just as easily look at the name part (kv[0]) and choose to do something with it. For example:
if kv[0].equals("ObjectGUId")
{
logObject.setGUId(kv[1]); // example mutator/setter method
}
else if //...
However, all your fields in LogObject are private and you haven't shown us any methods, so I hope you have some way of setting them from outside... bear in mind you will need to store the pairs in a data structure of some kind (as I have done with a HashMap) if you intend to intialise a LogObject with all the fields rather than setting the fields after a constructor call.
Speaking of SSCCEs, I made one for this answer.

Add arbitrary word to URL?

So I'm trying to take the source of the gv4me app, and modify it. I have this filter I have to get around, and the way to get past it is to put a certain keyword(lets say it's "foobar") in whatever URL you're trying to access. So I've got the source compiled and such, but I can't figure out how to add this word in properly. So far, adding it to the post doesn't work. These are the URLs that gv4me uses:
private static final String rnrURL = "https://www.google.com/voice/m/i/voicemail?p=1000";
private static final String clientLoginURL = "https://www.google.com/accounts/ClientLogin";
private final String callURL = "https://www.google.com/voice/call/connect";
private static final String markReadURL = "https://www.google.com/voice/m/mark?p=1&label=unread&id=";
private static final String getMsgsURL = "https://www.google.com/voice/inbox/recent/unread";
private static final String textURL = "https://www.google.com/voice/sms/send";
private static final String replyURL = "https://www.google.com/voice/m/sendsms";
I need to modify each of these URLs so they have "foobar" in them, but still link to the same page. Is this possible?
EDIT: Also, if you search for HandlerUI on google, you'll find a plethora of applications(closed and open source) modified to include a user interface for automatically modifying all connection attempts of said applications. However, the creator is fairly difficult to locate, so I was wondering if anyone knew how to do this?
EDIT2: It seems that adding a query string variable doesn't seem to work. What I think would most likely work, is to somehow replace www.google.com with foobar.freednsredirectservice.com. Does anyone know of anything similar to this? Something that would allow foobar.freednsredirectservice.com/voice to still work?
Try adding a query string parameter. This may not, but usually will work.
For example:
http://www.example.com/ -> http://www.example.com/?foobar
http://www.example.com/page?existing=value -> http://www.example.com/page?foobar&existing=value
Your question is unclear as to where the foobar should go, but let's assume it's after the host name, ie
"https://www.google.com/voice/sms/send" --> "https://www.google.com/foobar/voice/sms/send"
Use this:
String url = "https://www.google.com/voice/sms/send";
url = url.replaceFirst("(?<=[^:/]/)", "foobar/");
System.out.println(url); // https://www.google.com/foobar/voice/sms/send
If the foobar replaces the hostname, ie
"https://www.google.com/voice/sms/send" --> "https://foobar/voice/sms/send" use this:
Use this:
String url = "https://www.google.com/voice/sms/send";
url = url.replaceAll("//.*?/", "//foobar/");
System.out.println(url); // https://foobar/voice/sms/send
I would say no because then it would be a link is an adress and a different adress leads to a different place. What you could do is something like this:
String[] url = new String[2];
url[0] = "http://www.yoururl.com/";// Accual url
url[1] = url[0].replaceFirst("(?<=[^:/]/)", "foobar/");// For other purpose such as diplay

Categories