gpt4 book ai didi

java - 上传 Minecraft 皮肤

转载 作者:可可西里 更新时间:2023-11-01 17:34:17 27 4
gpt4 key购买 nike

在过去的几天里,我一直在尝试将 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com