- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在过去的几天里,我一直在尝试将 Minecraft 皮肤自动上传到 Mojang 的服务器。我能够成功登录到我的皮肤帐户(并适本地设置 cookie)。在不设置 cookie 的情况下,当我转到 https://minecraft.net/profile 时我被发送到登录页面,但如果我设置了 cookie,它会按原样将我带到个人资料页面。当我上传皮肤时,我多次查看了发送的 POST 数据,但我无法让它工作。我已经尝试了很多人的修复,但我找不到有效的修复。
public static void uploadSkin(BufferedImage image, boolean male, String username, String password){
try {
URL url = new URL("https://minecraft.net/login");
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod("POST");
http.setDoOutput(true);
Map<String, String> arguments = new HashMap<>();
arguments.put("username", username);
arguments.put("password", password);
String s = "";
for(Map.Entry<String, String> entry : arguments.entrySet())s += "&" + URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + URLEncoder.encode(entry.getValue(), "UTF-8");
s = s.replaceFirst("&", "");
byte[] out = s.getBytes(StandardCharsets.UTF_8);
int length = out.length;
http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
http.setInstanceFollowRedirects(false);
http.connect();
OutputStream os = http.getOutputStream();
os.write(out);
String cooks = "";
String at = "";
for(int i = 0; i < 50; i++){
String headerName = http.getHeaderFieldKey(i);
String headerValue = http.getHeaderField(i);
if(headerName != null && headerValue != null)if("Set-Cookie".equalsIgnoreCase(headerName))cooks += ";" + headerValue.split(";")[0];
}
http.disconnect();
URL url3 = new URL("https://minecraft.net/profile");
URLConnection con3 = url3.openConnection();
HttpURLConnection http3 = (HttpURLConnection) con3;
http3.setRequestProperty("Cookie", cooks);
http3.connect();
for(int i = 0; i < 50; i++){
String headerName = http3.getHeaderFieldKey(i);
String headerValue = http3.getHeaderField(i);
if(headerName != null && headerValue != null)if("Set-Cookie".equalsIgnoreCase(headerName))if(headerValue.startsWith("PLAY_SESSION"))at = headerValue.split("AT=")[1].split("\"")[0];
}
http3.disconnect();
cooks = cooks.replaceFirst(";", "");
URL url2 = new URL("https://minecraft.net/profile/skin");
URLConnection con2 = url2.openConnection();
HttpURLConnection http2 = (HttpURLConnection) con2;
http2.setRequestProperty("Cookie", cooks);
http2.setRequestMethod("POST");
http2.setDoOutput(true);
Map<String, String> arguments2 = new HashMap<>();
arguments2.put("model", male ? "steve" : "3pxarm");
arguments2.put("authenticityToken", at);
String encoded = "PNG";
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(image, "png", bos);
byte[] imageBytes = bos.toByteArray();
BASE64Encoder encoder = new BASE64Encoder();
encoded += encoder.encode(imageBytes);
bos.close();
arguments2.put("skin", encoded);
String s2 = "";
for(Map.Entry<String, String> entry : arguments2.entrySet())s2 += "&" + URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + URLEncoder.encode(entry.getValue(), "UTF-8");
s2 = s2.replaceFirst("&", "");
byte[] out2 = s2.getBytes(StandardCharsets.UTF_8);
int length2 = out2.length;
http2.setFixedLengthStreamingMode(length2);
http2.setRequestProperty("Content-Type", "multipart/form-data; charset=UTF-8;");
http2.setInstanceFollowRedirects(false);
http2.connect();
OutputStream os2 = http2.getOutputStream();
os2.write(out2);
InputStream is = http2.getInputStream();
Scanner sc = new Scanner(is, "UTF-8");
sc.useDelimiter("\\A");
while(sc.hasNext())System.out.println(sc.next());
sc.close();
http2.disconnect();
} catch (Exception e) {e.printStackTrace();}
}
尝试运行时出现此错误
java.io.IOException: Server returned HTTP response code: 500 for URL: https://minecraft.net/profile/skin
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
at net.supernatenetwork.snn.TTESTT.uploadSkin(TTESTT.java:104)
at net.supernatenetwork.snn.TTESTT.main(TTESTT.java:27)
第 98 行是“InputStream is = http2.getInputStream();”当我将用于读取 HTML 的 block 放入第一个 http 变量时,它什么也不打印。我不断收到错误代码 404。我确实知道错误代码 404 转换为找不到文件,但如果我不发送 POST 数据,它会将我带到配置文件页面,所以我假设它链接到 POST,因为如果我删除第一个 http 中的一个字段,它给了我同样的错误(仅在登录页面并且仅当我尝试从中获取数据时)。 BufferedImage 不为空,并且它有数据。我需要它是 BufferedImage,因为我需要在上传之前从模板对其进行编辑。查看之后,我看到皮肤的内容类型是 image/png,但我需要它是我目前拥有的内容,因为 POST 中有很多内容。我的编码变量以“PNG”开头,因为当我在 Firefox 中调试时,我看到皮肤以 PNG 开头(可能只是巧合)。我在没有“PNG”的情况下尝试过,但仍然没有运气。我上传的图片是 PNG 格式。任何帮助表示赞赏!谢谢!
编辑:我得到了一个不同的错误(来自新代码),我把它放在旧代码和错误所在的位置。我没有动过旧笔记。感谢 gre_gor 帮助我找出了一些错误。
编辑 2:我知道如何邮寄东西。我只是想知道如何上传皮肤,这与标记为重复的皮肤不同。
最佳答案
要上传文件,您需要将数据编码为 multipart/form-data
.只是将 Content-Type
更改为 multipart/form-data
不会神奇地使其工作。您需要自己构建适当的 HTTP 负载。
它应该看起来像这样:
------WebKitFormBoundary4ytVzCJnzOYoi3v4
Content-Disposition: form-data; name="authenticityToken"
78142fca85887e53d795fab390a78cfe1f96acd5
------WebKitFormBoundary4ytVzCJnzOYoi3v4
Content-Disposition: form-data; name="model"
steve
------WebKitFormBoundary4ytVzCJnzOYoi3v4
Content-Disposition: form-data; name="skin"; filename="skin.png"
Content-Type: image/png
[PNG skin image data]
------WebKitFormBoundary4ytVzCJnzOYoi3v4--
这是工作代码:
import java.util.*;
import java.lang.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.net.HttpCookie;
import java.net.CookieManager;
import java.net.CookieHandler;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
class SkinUpload
{
public static void login(String email, String password) throws java.lang.Exception
{
String payload = "username=" + URLEncoder.encode(email, "UTF-8");
payload += "&password=" + URLEncoder.encode(password, "UTF-8");
byte[] payload_data = payload.getBytes("UTF-8");
HttpURLConnection http = (HttpURLConnection)(new URL("https://minecraft.net/login").openConnection());
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
http.setFixedLengthStreamingMode(payload_data.length);
http.connect();
http.getOutputStream().write(payload_data);
System.out.println("login: "+http.getResponseCode()+" "+http.getResponseMessage());
http.disconnect();
}
public static void profile() throws java.lang.Exception
{
HttpURLConnection http = (HttpURLConnection)(new URL("https://minecraft.net/profile").openConnection());
http.setRequestMethod("GET");
http.connect();
System.out.println("profile: "+http.getResponseCode()+" "+http.getResponseMessage());
http.disconnect();
}
public static void upload(String authenticityToken, BufferedImage image, boolean male) throws java.lang.Exception
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "png", baos);
String boundary = Long.toHexString(System.currentTimeMillis());
HttpURLConnection http = (HttpURLConnection)(new URL("https://minecraft.net/profile/skin").openConnection());
http.setRequestMethod("POST");
http.setDoOutput(true);
http.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
http.connect();
http.getOutputStream().write(("--"+boundary+"\r\n").getBytes());
http.getOutputStream().write(("Content-Disposition: form-data; name=\"authenticityToken\"\r\n\r\n").getBytes());
http.getOutputStream().write((authenticityToken+"\r\n").getBytes());
http.getOutputStream().write(("--"+boundary+"\r\n").getBytes());
http.getOutputStream().write(("Content-Disposition: form-data; name=\"model\"\r\n\r\n").getBytes());
http.getOutputStream().write(((male ? "steve" : "3pxarm")+"\r\n").getBytes());
http.getOutputStream().write(("--"+boundary+"\r\n").getBytes());
http.getOutputStream().write(("Content-Disposition: form-data; name=\"skin\"; filename=\"skin.png\"\r\n").getBytes());
http.getOutputStream().write(("Content-Type: image/png\r\n\r\n").getBytes());
http.getOutputStream().write(baos.toByteArray());
http.getOutputStream().write(("\r\n").getBytes());
http.getOutputStream().write(("--"+boundary+"--\r\n").getBytes());
http.getOutputStream().flush();
System.out.println("upload: "+http.getResponseCode()+" "+http.getResponseMessage());
http.disconnect();
}
public static String get_authenticityToken(List<HttpCookie> cookies) throws java.lang.Exception
{
for (HttpCookie cookie : cookies)
{
if (cookie.getName().equals("PLAY_SESSION"))
{
for (String param : cookie.getValue().split("&"))
{
int i = param.indexOf("=");
String name = URLDecoder.decode(param.substring(0, i), "UTF-8");
String value = URLDecoder.decode(param.substring(i + 1), "UTF-8");
if (name.equals("___AT"))
return value;
}
}
}
return null;
}
public static void main (String[] args) throws java.lang.Exception
{
if (args.length < 3)
{
System.out.println("Usage:\nSkinUpload [email] [password] [image file path]");
return;
}
String email = args[0];
String password = args[1];
String image_file = args[2];
// this should handle cookies for all HTTP requests
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
login(email, password);
profile();
// get authenticityToken from picked up cookies
String authenticityToken = get_authenticityToken(cookieManager.getCookieStore().getCookies());
if (authenticityToken == null)
{
System.out.println("Failed to get authenticityToken");
}
else
{
System.out.println("authenticityToken = "+authenticityToken);
BufferedImage skin = ImageIO.read(new File(image_file));
upload(authenticityToken, skin, true);
}
}
}
关于java - 上传 Minecraft 皮肤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36414727/
我不知道为什么当我从南边或东边看时我的纹理按预期渲染,但从北边或西边看时却隐藏了它们后面的对象。 我有一个不可见的 block ,它在其中渲染多个项目,并且在处理具有半透明纹理的 block 时遇到问
我想写一个 Minecraft 模组来增加一种新型的生物。那可能吗?我看到,在 Bukkit, EntityType is a predefined enum ,这让我相信可能没有办法添加新类型的实体
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我一直在尝试使用 MCP 将 Minecraft 源代码反编译到 eclipse 工作区。我正在使用 mcp940 反编译 Minecraft 1.12。当我运行 BATCH 文件 decompile
我正在尝试制作模组,但遇到了这个问题。当我尝试创建工艺配方时,它使我的游戏崩溃。我真的不知道为什么。我尝试使用Items.COOKED_BEEF 还尝试了 Item.cooked_beef。我导入了我
我最近正在开发 Minecraft mod,在处理函数的返回语句时,我发现它需要一个 INBT 实例作为返回类型。我有一个自定义对象,需要将其转换为 INBT 类型的 NBT?这是函数: public
我已经开始制作模组,它没有注册为元素。当我键入 /give Fidojj222 fcm:fuel_canister 时,它应该给我该项目,除非它说它不存在!我正在使用 eclipse 作为我的 IDE
我用 Python 为 Minecraft 1.12.2 编写了一个启动器,它只是准备一个命令并使用子进程运行它。 这是在 Linux Ubuntu 上形成的命令: #!/usr/bin/env ba
我想创建一个应用程序服务器可以联系的 Web 服务,以将自身添加到实现该应用程序的服务器列表中。然后,客户端可以联系该服务以获取服务器列表。类似于 minecraft's heartbeats wor
我在带有 OpenJDK 的 headless Linux 服务器上运行 Minecraft。我已经添加了太多的 mods 和它的滞后(即使在我的本地网络上)而没有使用太多的 CPU 或内存(例如它滞
我正在尝试制作一个插件来消除 Minecraft 中的饥饿感。但是,我找不到它的事件! 是否有玩家失去饥饿感时调用的事件? 类似 PlayerHungerChangeEvent 的东西? 最佳答案 我
我熟悉的唯一模型是漫射照明,但这看起来比那复杂得多。 最佳答案 每个方块的亮度级别从 15 到 0。每个级别都比它上面的级别低 20%。如果一个正方形包含一个光源,它会得到那个光源的光度,否则它会比最
我在学习东西的过程中对我的世界插件开发非常陌生。我正在开发一个 jail 插件,并创建了一种方法,可以让玩家知道他们的库存是否已满。它不起作用,我不明白为什么。代码: public void
我在启动我的世界服务器时遇到错误。我用于插件的外部库是推荐的构建 craftbukkit-1.6.4-R2.0。我使用 craftbukkit-1.6.4-R2.0 来启动服务器并作为 eclipse
我想用 launchProjectile 编写我自己的武器系统,我使用的是 Arrow。但是我怎样才能在不增加传播的情况下增加箭头速度呢?代码如下: @Override public void sho
我正在为 Android 编写 Minecraft 红石模拟器。我正在使用 Dijkstra 的一些变体进行模拟,但我听说,真正的模拟器会做一些不同的事情,并在每个红石滴答声中更新每个红石 block
我在尝试获取 Minecraft 插件中的标志线值时遇到问题。这是我的代码: package pl.maccraft.regssal; import org.bukkit.plugin.java.Ja
我需要找到一种方法来检查我的世界用户名和密码是否有效。 我发现这个文档讲述了很多有关 Minecraft 身份验证的事情:http://wiki.vg/Authentication 看起来它需要一个
对于一个 Minecraft 项目,我想让玩家逐渐面对 (0, 60, 0)。到目前为止,当玩家围绕 (0, 60, 0) 移动超过 720° 时,我尝试的一切似乎都失败了。 有人知道如何让相机无缝移
尝试编写 Minecraft 插件代码时,当我在游戏中运行/fakeop 时出现外部错误。/fakeop (playername) 虽然有效 public class CortexTroll exte
我是一名优秀的程序员,十分优秀!