com.jagrosh.discordipc.entities.RichPresence Maven / Gradle / Ivy
Show all versions of DiscordIPC Show documentation
/*
* Copyright 2017 John Grosh ([email protected]).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jagrosh.discordipc.entities;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import java.util.Objects;
/**
* An encapsulation of all data needed to properly construct a JSON RichPresence payload.
*
* These can be built using {@link RichPresence.Builder}.
*
* @author John Grosh ([email protected])
*/
public class RichPresence {
private static final int MIN_ALLOWED_BUTTONS = 1;
private static final int MAX_ALLOWED_BUTTONS = 2;
private final ActivityType activityType;
private final String state;
private final String details;
private final long startTimestamp;
private final long endTimestamp;
private final String largeImageKey;
private final String largeImageText;
private final String smallImageKey;
private final String smallImageText;
private final String partyId;
private final int partySize;
private final int partyMax;
private final PartyPrivacy partyPrivacy;
private final String matchSecret;
private final String joinSecret;
private final String spectateSecret;
private final JsonArray buttons;
private final boolean instance;
public RichPresence(ActivityType activityType, String state, String details, long startTimestamp, long endTimestamp,
String largeImageKey, String largeImageText, String smallImageKey, String smallImageText,
String partyId, int partySize, int partyMax, PartyPrivacy partyPrivacy, String matchSecret, String joinSecret,
String spectateSecret, JsonArray buttons, boolean instance) {
this.activityType = activityType;
this.state = state;
this.details = details;
this.startTimestamp = startTimestamp;
this.endTimestamp = endTimestamp;
this.largeImageKey = largeImageKey;
this.largeImageText = largeImageText;
this.smallImageKey = smallImageKey;
this.smallImageText = smallImageText;
this.partyId = partyId;
this.partySize = partySize;
this.partyMax = partyMax;
this.partyPrivacy = partyPrivacy;
this.matchSecret = matchSecret;
this.joinSecret = joinSecret;
this.spectateSecret = spectateSecret;
this.buttons = buttons;
this.instance = instance;
}
/**
* Constructs a {@link JsonObject} representing a payload to send to discord
* to update a user's Rich Presence.
*
*
This is purely internal, and should not ever need to be called outside
* the library.
*
* @return A JSONObject payload for updating a user's Rich Presence.
*/
public JsonObject toJson() {
JsonObject timestamps = new JsonObject(),
assets = new JsonObject(),
party = new JsonObject(),
secrets = new JsonObject(),
finalObject = new JsonObject();
if (startTimestamp > 0) {
timestamps.addProperty("start", startTimestamp);
if (endTimestamp > startTimestamp) {
timestamps.addProperty("end", endTimestamp);
}
}
if (largeImageKey != null && !largeImageKey.isEmpty()) {
assets.addProperty("large_image", largeImageKey);
if (largeImageText != null && !largeImageText.isEmpty()) {
assets.addProperty("large_text", largeImageText);
}
}
if (smallImageKey != null && !smallImageKey.isEmpty()) {
assets.addProperty("small_image", smallImageKey);
if (smallImageText != null && !smallImageText.isEmpty()) {
assets.addProperty("small_text", smallImageText);
}
}
if ((partyId != null && !partyId.isEmpty()) ||
(partySize > 0 && partyMax > 0)) {
if (partyId != null && !partyId.isEmpty()) {
party.addProperty("id", partyId);
}
JsonArray partyData = new JsonArray();
if (partySize > 0) {
partyData.add(new JsonPrimitive(partySize));
if (partyMax >= partySize) {
partyData.add(new JsonPrimitive(partyMax));
}
}
party.add("size", partyData);
party.add("privacy", new JsonPrimitive(partyPrivacy.ordinal()));
}
if (joinSecret != null && !joinSecret.isEmpty()) {
secrets.addProperty("join", joinSecret);
}
if (spectateSecret != null && !spectateSecret.isEmpty()) {
secrets.addProperty("spectate", spectateSecret);
}
if (matchSecret != null && !matchSecret.isEmpty()) {
secrets.addProperty("match", matchSecret);
}
finalObject.addProperty("type", activityType.ordinal());
if (state != null && !state.isEmpty()) {
finalObject.addProperty("state", state);
}
if (details != null && !details.isEmpty()) {
finalObject.addProperty("details", details);
}
if (timestamps.has("start")) {
finalObject.add("timestamps", timestamps);
}
if (assets.has("large_image")) {
finalObject.add("assets", assets);
}
if (party.has("id")) {
finalObject.add("party", party);
}
if (secrets.has("join") || secrets.has("spectate") || secrets.has("match")) {
finalObject.add("secrets", secrets);
}
if (buttons != null && !buttons.isJsonNull() && buttons.size() >= MIN_ALLOWED_BUTTONS && buttons.size() <= MAX_ALLOWED_BUTTONS) {
finalObject.add("buttons", buttons);
}
finalObject.addProperty("instance", instance);
return finalObject;
}
public String toDecodedJson(String encoding) {
try {
return new String(toJson().toString().getBytes(encoding));
} catch (Exception ex) {
return toJson().toString();
}
}
@Override
public boolean equals(Object o) {
if (!(o instanceof RichPresence))
return false;
RichPresence oPresence = (RichPresence) o;
return this == oPresence || (
Objects.equals(activityType, oPresence.activityType) &&
Objects.equals(state, oPresence.state) &&
Objects.equals(details, oPresence.details) &&
Objects.equals(startTimestamp, oPresence.startTimestamp) &&
Objects.equals(endTimestamp, oPresence.endTimestamp) &&
Objects.equals(largeImageKey, oPresence.largeImageKey) &&
Objects.equals(largeImageText, oPresence.largeImageText) &&
Objects.equals(smallImageKey, oPresence.smallImageKey) &&
Objects.equals(smallImageText, oPresence.smallImageText) &&
Objects.equals(partyId, oPresence.partyId) &&
Objects.equals(partySize, oPresence.partySize) &&
Objects.equals(partyMax, oPresence.partyMax) &&
Objects.equals(partyPrivacy, oPresence.partyPrivacy) &&
Objects.equals(matchSecret, oPresence.matchSecret) &&
Objects.equals(joinSecret, oPresence.joinSecret) &&
Objects.equals(spectateSecret, oPresence.spectateSecret) &&
Objects.equals(buttons, oPresence.buttons) &&
Objects.equals(instance, oPresence.instance)
);
}
@Override
public int hashCode() {
return Objects.hash(
activityType,
state, details,
startTimestamp, endTimestamp,
largeImageKey, largeImageText,
smallImageKey, smallImageText,
partyId, partySize, partyMax, partyPrivacy,
matchSecret, joinSecret, spectateSecret,
buttons, instance
);
}
/**
* A chain builder for a {@link RichPresence} object.
*
*
An accurate description of each field and it's functions can be found
* here
*/
public static class Builder {
private ActivityType activityType;
private String state;
private String details;
private long startTimestamp;
private long endTimestamp;
private String largeImageKey;
private String largeImageText;
private String smallImageKey;
private String smallImageText;
private String partyId;
private int partySize;
private int partyMax;
private PartyPrivacy partyPrivacy;
private String matchSecret;
private String joinSecret;
private String spectateSecret;
private JsonArray buttons;
private boolean instance;
/**
* Builds the {@link RichPresence} from the current state of this builder.
*
* @return The RichPresence built.
*/
public RichPresence build() {
return new RichPresence(activityType, state, details, startTimestamp, endTimestamp,
largeImageKey, largeImageText, smallImageKey, smallImageText,
partyId, partySize, partyMax, partyPrivacy, matchSecret, joinSecret,
spectateSecret, buttons, instance);
}
/**
* Sets the activity type for the player's current activity
*
* @param activityType The new activity type
* @return This Builder.
*/
public Builder setActivityType(ActivityType activityType) {
this.activityType = activityType;
return this;
}
/**
* Sets the state of the user's current party.
*
* @param state The state of the user's current party.
* @return This Builder.
*/
public Builder setState(String state) {
this.state = state;
return this;
}
/**
* Sets details of what the player is currently doing.
*
* @param details The details of what the player is currently doing.
* @return This Builder.
*/
public Builder setDetails(String details) {
this.details = details;
return this;
}
/**
* Sets the time that the player started a match or activity.
*
* @param startTimestamp The time the player started a match or activity.
* @return This Builder.
*/
public Builder setStartTimestamp(long startTimestamp) {
this.startTimestamp = startTimestamp;
return this;
}
/**
* Sets the time that the player's current activity will end.
*
* @param endTimestamp The time the player's activity will end.
* @return This Builder.
*/
public Builder setEndTimestamp(long endTimestamp) {
this.endTimestamp = endTimestamp;
return this;
}
/**
* Sets the key of the uploaded image for the large profile artwork, as well as
* the text tooltip shown when a cursor hovers over it.
*
*
These can be configured in the applications
* page on the discord website.
*
* @param largeImageKey A key to an image to display.
* @param largeImageText Text displayed when a cursor hovers over the large image.
* @return This Builder.
*/
public Builder setLargeImage(String largeImageKey, String largeImageText) {
this.largeImageKey = largeImageKey;
this.largeImageText = largeImageText;
return this;
}
/**
* Sets the key of the uploaded image for the large profile artwork.
*
*
These can be configured in the applications
* page on the discord website.
*
* @param largeImageKey A key to an image to display.
* @return This Builder.
*/
public Builder setLargeImage(String largeImageKey) {
return setLargeImage(largeImageKey, null);
}
/**
* Sets the key of the uploaded image for the small profile artwork, as well as
* the text tooltip shown when a cursor hovers over it.
*
*
These can be configured in the applications
* page on the discord website.
*
* @param smallImageKey A key to an image to display.
* @param smallImageText Text displayed when a cursor hovers over the small image.
* @return This Builder.
*/
public Builder setSmallImage(String smallImageKey, String smallImageText) {
this.smallImageKey = smallImageKey;
this.smallImageText = smallImageText;
return this;
}
/**
* Sets the key of the uploaded image for the small profile artwork.
*
*
These can be configured in the applications
* page on the discord website.
*
* @param smallImageKey A key to an image to display.
* @return This Builder.
*/
public Builder setSmallImage(String smallImageKey) {
return setSmallImage(smallImageKey, null);
}
/**
* Sets party configurations for a team, lobby, or other form of group.
*
*
The {@code partyId} is ID of the player's party.
*
The {@code partySize} is the current size of the player's party.
*
The {@code partyMax} is the maximum number of player's allowed in the party.
*
* @param partyId The ID of the player's party.
* @param partySize The current size of the player's party.
* @param partyMax The maximum number of player's allowed in the party.
* @param partyPrivacy The privacy level for the player's party.
* @return This Builder.
*/
public Builder setParty(String partyId, int partySize, int partyMax, PartyPrivacy partyPrivacy) {
this.partyId = partyId;
this.partySize = partySize;
this.partyMax = partyMax;
this.partyPrivacy = partyPrivacy;
return this;
}
/**
* Sets the unique hashed string for Spectate and Join.
*
* @param matchSecret The unique hashed string for Spectate and Join.
* @return This Builder.
*/
public Builder setMatchSecret(String matchSecret) {
this.matchSecret = matchSecret;
return this;
}
/**
* Sets the unique hashed string for chat invitations and Ask to Join.
*
* @param joinSecret The unique hashed string for chat invitations and Ask to Join.
* @return This Builder.
*/
public Builder setJoinSecret(String joinSecret) {
this.joinSecret = joinSecret;
return this;
}
/**
* Sets the unique hashed string for Spectate button.
*
* @param spectateSecret The unique hashed string for Spectate button.
* @return This Builder.
*/
public Builder setSpectateSecret(String spectateSecret) {
this.spectateSecret = spectateSecret;
return this;
}
/**
* Sets the button array to be used within the RichPresence
*
Must be a format of {'label': "...", 'url': "..."} with a max length of 2
*
* @param buttons The new array of button objects to use
* @return This Builder.
*/
public Builder setButtons(JsonArray buttons) {
this.buttons = buttons;
return this;
}
/**
* Marks the {@link #setMatchSecret(String) matchSecret} as a game
* session with a specific beginning and end.
*
* @param instance Whether the {@code matchSecret} is a game
* with a specific beginning and end.
* @return This Builder.
*/
public Builder setInstance(boolean instance) {
this.instance = instance;
return this;
}
}
}