diff --git a/minecord-bot/src/main/java/com/tisawesomeness/minecord/mc/external/MojangAPI.java b/minecord-bot/src/main/java/com/tisawesomeness/minecord/mc/external/MojangAPI.java
index 31cb8c76..de755d87 100644
--- a/minecord-bot/src/main/java/com/tisawesomeness/minecord/mc/external/MojangAPI.java
+++ b/minecord-bot/src/main/java/com/tisawesomeness/minecord/mc/external/MojangAPI.java
@@ -1,22 +1,21 @@
package com.tisawesomeness.minecord.mc.external;
import com.tisawesomeness.minecord.mc.player.Profile;
+import com.tisawesomeness.minecord.mc.player.ProfileAction;
import com.tisawesomeness.minecord.mc.player.SkinType;
import com.tisawesomeness.minecord.mc.player.Username;
import com.tisawesomeness.minecord.util.URLs;
import com.tisawesomeness.minecord.util.UUIDs;
-
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
+import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-import java.util.Optional;
-import java.util.UUID;
+import java.util.*;
/**
* A wrapper for the Mojang API. See the docs
@@ -110,7 +109,10 @@ public Optional getProfile(@NonNull UUID uuid) throws IOException {
}
}
- return Optional.of(new Profile(username, legacy, demo, skinType, skinUrl, capeUrl));
+ JSONArray profileActionsArr = json.optJSONArray("profileActions");
+ Set profileActions = parseProfileActions(profileActionsArr);
+
+ return Optional.of(new Profile(username, legacy, demo, skinType, skinUrl, capeUrl, profileActions));
}
private static SkinType getSkinType(@NonNull JSONObject skinObj) {
@@ -127,4 +129,16 @@ private static String decodeBase64(@NonNull String base64String) {
return new String(Base64.getDecoder().decode(base64String), StandardCharsets.UTF_8);
}
+ private static Set parseProfileActions(JSONArray arr) {
+ if (arr == null) {
+ return Collections.emptySet();
+ }
+ Set profileActions = EnumSet.noneOf(ProfileAction.class);
+ for (int i = 0; i < arr.length(); i++) {
+ String actionStr = arr.getString(i);
+ ProfileAction.from(actionStr.toUpperCase(Locale.ROOT)).ifPresent(profileActions::add);
+ }
+ return profileActions;
+ }
+
}
diff --git a/minecord-bot/src/main/java/com/tisawesomeness/minecord/mc/player/Profile.java b/minecord-bot/src/main/java/com/tisawesomeness/minecord/mc/player/Profile.java
index d17336c2..d73d46b2 100644
--- a/minecord-bot/src/main/java/com/tisawesomeness/minecord/mc/player/Profile.java
+++ b/minecord-bot/src/main/java/com/tisawesomeness/minecord/mc/player/Profile.java
@@ -1,16 +1,20 @@
package com.tisawesomeness.minecord.mc.player;
+import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.Value;
import javax.annotation.Nullable;
import java.net.URL;
+import java.util.Collections;
import java.util.Optional;
+import java.util.Set;
/**
* Provides additional account information about a player.
*/
@Value
+@AllArgsConstructor
public class Profile {
/**
* The player's current username
@@ -30,6 +34,12 @@ public class Profile {
SkinType skinType;
@Nullable URL skinUrl;
@Nullable URL capeUrl;
+ Set profileActions;
+
+ public Profile(@NonNull Username username, boolean legacy, boolean demo, SkinType skinType, @Nullable URL skinUrl,
+ @Nullable URL capeUrl) {
+ this(username, legacy, demo, skinType, skinUrl, capeUrl, Collections.emptySet());
+ }
/**
* @return The skin URL, or empty if the player has no custom skin
diff --git a/minecord-bot/src/main/java/com/tisawesomeness/minecord/mc/player/ProfileAction.java b/minecord-bot/src/main/java/com/tisawesomeness/minecord/mc/player/ProfileAction.java
new file mode 100644
index 00000000..5ef356f3
--- /dev/null
+++ b/minecord-bot/src/main/java/com/tisawesomeness/minecord/mc/player/ProfileAction.java
@@ -0,0 +1,20 @@
+package com.tisawesomeness.minecord.mc.player;
+
+import lombok.NonNull;
+
+import java.util.Optional;
+
+/** A moderation action taken against a profile */
+public enum ProfileAction {
+ FORCED_NAME_CHANGE,
+ USING_BANNED_SKIN;
+
+ public static Optional from(@NonNull String str) {
+ for (ProfileAction action : values()) {
+ if (action.toString().equals(str)) {
+ return Optional.of(action);
+ }
+ }
+ return Optional.empty();
+ }
+}
diff --git a/minecord-bot/src/test/java/com/tisawesomeness/minecord/mc/external/MojangAPITest.java b/minecord-bot/src/test/java/com/tisawesomeness/minecord/mc/external/MojangAPITest.java
index 0c078fc1..af148f4a 100644
--- a/minecord-bot/src/test/java/com/tisawesomeness/minecord/mc/external/MojangAPITest.java
+++ b/minecord-bot/src/test/java/com/tisawesomeness/minecord/mc/external/MojangAPITest.java
@@ -1,12 +1,13 @@
package com.tisawesomeness.minecord.mc.external;
+import com.tisawesomeness.minecord.common.util.IO;
import com.tisawesomeness.minecord.mc.player.Profile;
+import com.tisawesomeness.minecord.mc.player.ProfileAction;
import com.tisawesomeness.minecord.mc.player.SkinType;
import com.tisawesomeness.minecord.mc.player.Username;
import com.tisawesomeness.minecord.testutil.mc.MockMojangAPI;
import com.tisawesomeness.minecord.util.URLs;
import com.tisawesomeness.minecord.util.UUIDs;
-
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.jupiter.api.DisplayName;
@@ -15,9 +16,7 @@
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
-import java.util.Base64;
-import java.util.Optional;
-import java.util.UUID;
+import java.util.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -29,6 +28,7 @@ public class MojangAPITest {
private static final Username NON_ASCII_USERNAME = new Username("ooθoo");
private static final UUID TESTING_UUID = UUID.fromString("f6489b79-7a9f-49e2-980e-265a05dbc3af");
private static final UUID FAKE_UUID = UUID.fromString("f6489b79-7a9f-49e2-980e-265a05dbc3ae");
+ private static final String PROFILE_ACTIONS_RESPONSE = IO.loadResource("profileActionsTestResponse.json", MojangAPITest.class);
@Test
@DisplayName("Username-->uuid endpoint is parsed correctly")
@@ -126,4 +126,15 @@ public void testNonExistentProfile() throws IOException {
assertThat(api.getProfile(FAKE_UUID)).isEmpty();
}
+ @Test
+ @DisplayName("Profile actions are correctly parsed")
+ public void testProfileActions() throws IOException {
+ MockMojangAPI api = new MockMojangAPI();
+ api.mapProfile(TESTING_UUID, PROFILE_ACTIONS_RESPONSE);
+ URL skinUrl = URLs.createUrl("https://textures.minecraft.net/texture/3196c893f1a6131ad5ba78fec26185bc424f408419e237f7b15f8a3bc69a90a0");
+ Set profileActions = EnumSet.of(ProfileAction.FORCED_NAME_CHANGE, ProfileAction.USING_BANNED_SKIN);
+ Profile profile = new Profile(TESTING_USERNAME, false, false, SkinType.STEVE, skinUrl, null, profileActions);
+ assertThat(api.getProfile(TESTING_UUID)).contains(profile);
+ }
+
}
diff --git a/minecord-bot/src/test/resources/profileActionsTestResponse.json b/minecord-bot/src/test/resources/profileActionsTestResponse.json
new file mode 100644
index 00000000..38c03a1e
--- /dev/null
+++ b/minecord-bot/src/test/resources/profileActionsTestResponse.json
@@ -0,0 +1,14 @@
+{
+ "id": "f6489b797a9f49e2980e265a05dbc3af",
+ "name": "Tis_awesomeness",
+ "properties": [
+ {
+ "name": "textures",
+ "value": "ewogICJ0aW1lc3RhbXAiIDogMTY5NDMwNTYxNTUyMiwKICAicHJvZmlsZUlkIiA6ICJmNjQ4OWI3OTdhOWY0OWUyOTgwZTI2NWEwNWRiYzNhZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJUaXNfYXdlc29tZW5lc3MiLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMzE5NmM4OTNmMWE2MTMxYWQ1YmE3OGZlYzI2MTg1YmM0MjRmNDA4NDE5ZTIzN2Y3YjE1ZjhhM2JjNjlhOTBhMCIKICAgIH0KICB9Cn0="
+ }
+ ],
+ "profileActions": [
+ "FORCED_NAME_CHANGE",
+ "USING_BANNED_SKIN"
+ ]
+}
\ No newline at end of file