diff --git a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java index d5ab123..3d23c8e 100644 --- a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java +++ b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java @@ -44,7 +44,7 @@ import java.util.Set; import java.util.stream.Stream; import moe.yushi.authlibinjector.httpd.DefaultURLRedirector; import moe.yushi.authlibinjector.httpd.LegacySkinAPIFilter; -import moe.yushi.authlibinjector.httpd.PrivilegesFilter; +import moe.yushi.authlibinjector.httpd.AntiFeaturesFilter; import moe.yushi.authlibinjector.httpd.QueryProfileFilter; import moe.yushi.authlibinjector.httpd.QueryUUIDsFilter; import moe.yushi.authlibinjector.httpd.URLFilter; @@ -241,11 +241,7 @@ public final class AuthlibInjector { log(INFO, "Disabled Mojang namespace"); } - boolean polyfillPrivilegesApi = !Boolean.TRUE.equals(config.getMeta().get("feature.privileges_api")); - if (polyfillPrivilegesApi) { - log(INFO, "Polyfill privileges API"); - filters.add(new PrivilegesFilter()); - } + filters.add(new AntiFeaturesFilter()); return filters; } diff --git a/src/main/java/moe/yushi/authlibinjector/httpd/AntiFeaturesFilter.java b/src/main/java/moe/yushi/authlibinjector/httpd/AntiFeaturesFilter.java new file mode 100644 index 0000000..c551b5f --- /dev/null +++ b/src/main/java/moe/yushi/authlibinjector/httpd/AntiFeaturesFilter.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2021 Haowei Wen and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package moe.yushi.authlibinjector.httpd; + +import static moe.yushi.authlibinjector.util.IOUtils.CONTENT_TYPE_JSON; +import static moe.yushi.authlibinjector.util.IOUtils.CONTENT_TYPE_TEXT; +import java.io.IOException; +import java.util.Optional; +import moe.yushi.authlibinjector.internal.fi.iki.elonen.IHTTPSession; +import moe.yushi.authlibinjector.internal.fi.iki.elonen.Response; +import moe.yushi.authlibinjector.internal.fi.iki.elonen.Status; + +/** + * Disables Mojang's anti-features. + */ +public class AntiFeaturesFilter implements URLFilter { + + private static final String RESPONSE_PRIVILEGES = "{\"privileges\":{\"onlineChat\":{\"enabled\":true},\"multiplayerServer\":{\"enabled\":true},\"multiplayerRealms\":{\"enabled\":true},\"telemetry\":{\"enabled\":false}}}"; + private static final String RESPONSE_PLAYER_ATTRIBUTES = "{\"privileges\":{\"multiplayerRealms\":{\"enabled\":true},\"multiplayerServer\":{\"enabled\":true},\"onlineChat\":{\"enabled\":true},\"telemetry\":{\"enabled\":false}},\"profanityFilterPreferences\":{\"profanityFilterOn\":false}}"; + private static final String RESPONSE_PRIVACY_BLOCKLIST = "{\"blockedProfiles\":[]}"; + + @Override + public boolean canHandle(String domain) { + return domain.equals("api.minecraftservices.com") || domain.equals("sessionserver.mojang.com"); + } + + @Override + public Optional handle(String domain, String path, IHTTPSession session) throws IOException { + if (domain.equals("api.minecraftservices.com") && path.equals("/privileges") && session.getMethod().equals("GET")) { + return Optional.of(Response.newFixedLength(Status.OK, CONTENT_TYPE_JSON, RESPONSE_PRIVILEGES)); + } else if (domain.equals("api.minecraftservices.com") && path.equals("/player/attributes") && session.getMethod().equals("GET")) { + return Optional.of(Response.newFixedLength(Status.OK, CONTENT_TYPE_JSON, RESPONSE_PLAYER_ATTRIBUTES)); + } else if (domain.equals("api.minecraftservices.com") && path.equals("/privacy/blocklist") && session.getMethod().equals("GET")) { + return Optional.of(Response.newFixedLength(Status.OK, CONTENT_TYPE_JSON, RESPONSE_PRIVACY_BLOCKLIST)); + } else if (domain.equals("sessionserver.mojang.com") && path.equals("/blockedservers") && session.getMethod().equals("GET")) { + return Optional.of(Response.newFixedLength(Status.NOT_FOUND, CONTENT_TYPE_TEXT, "")); + } else { + return Optional.empty(); + } + } +} diff --git a/src/main/java/moe/yushi/authlibinjector/httpd/PrivilegesFilter.java b/src/main/java/moe/yushi/authlibinjector/httpd/PrivilegesFilter.java deleted file mode 100644 index fb855fd..0000000 --- a/src/main/java/moe/yushi/authlibinjector/httpd/PrivilegesFilter.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2021 Haowei Wen and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package moe.yushi.authlibinjector.httpd; - -import static moe.yushi.authlibinjector.util.IOUtils.CONTENT_TYPE_JSON; -import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Optional; -import moe.yushi.authlibinjector.internal.fi.iki.elonen.IHTTPSession; -import moe.yushi.authlibinjector.internal.fi.iki.elonen.Response; -import moe.yushi.authlibinjector.internal.fi.iki.elonen.Status; -import moe.yushi.authlibinjector.internal.org.json.simple.JSONObject; - -public class PrivilegesFilter implements URLFilter { - - private final Map privileges = new LinkedHashMap<>(); - - public PrivilegesFilter() { - privileges.put("onlineChat", true); - privileges.put("multiplayerServer", true); - privileges.put("multiplayerRealms", true); - privileges.put("telemetry", false); - } - - @Override - public boolean canHandle(String domain) { - return domain.equals("api.minecraftservices.com"); - } - - @Override - public Optional handle(String domain, String path, IHTTPSession session) throws IOException { - if (domain.equals("api.minecraftservices.com") && path.equals("/privileges") && session.getMethod().equals("GET")) { - JSONObject response = new JSONObject(); - JSONObject privilegesJson = new JSONObject(); - privileges.forEach((name, enabled) -> { - JSONObject privilegeJson = new JSONObject(); - privilegeJson.put("enabled", enabled); - privilegesJson.put(name, privilegeJson); - }); - response.put("privileges", privilegesJson); - return Optional.of(Response.newFixedLength(Status.OK, CONTENT_TYPE_JSON, response.toJSONString())); - } else { - return Optional.empty(); - } - } -}