2016-04-04 101 views
1

Son birkaç gündür, bir Minecraft kaplamasını Mojang'ın sunucularına otomatik olarak yüklemeye çalışıyorum. Cilt hesabımda başarılı bir şekilde oturum açabiliyorum (ve çerezleri uygun şekilde ayarlayabiliyorum). Çerezleri ayarlamadan, https://minecraft.net/profile'a gittiğimde, giriş sayfasına gönderilirim, ancak kurabiyeleri ayarlıyorumsa profil sayfası bana gerektiği gibi getiriyor. Bir cilt yüklediğimde birçok kez gönderilen POST verisini inceledim, ama hayatım boyunca işe yaramayacaktım. Birçok kişinin düzeltmelerini denedim, ancak yine de bir düzeltme bulamıyorum. "InputStream = http2.getInputStream() 'dir;" Çizgi 98 oMinecraft Cilt Yükleme

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) 

çalıştırmayı edilir çalışırken

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();} 
} 

bu hatayı alıyorum HTML'yi ilk http değişkeniyle okumak için bloğu koyduğumda, hiçbir şey basmaz. Hata kodu 404'ü almaya devam ediyorum. Hata kodu 404'ün dosyada bulunmadığını biliyorum, ancak POST verisi göndermediğimde beni profil sayfasına getiriyor, bu yüzden POST ile bağlantılı olduğunu varsayıyorum. İlk http'daki alanlardan birini kaldırın, bana aynı hatayı verir (sadece giriş sayfasından ve sadece verileri almayı denediğimde). BufferedImage boş değil ve veri var. Bir BufferedImage olması gerekiyor çünkü onu yüklemeden önce bir şablondan düzenlemem gerekiyor. Baktıktan sonra, cildin içerik türünün image/png olduğunu görüyorum, fakat POST'a giden birçok şey olduğu için şu anda sahip olduğum şeyin olması gerekiyor. Kodlanmış değişkenim "PNG" ile başlıyor, çünkü Firefox'ta hata ayıklarken, cildin PNG ile başladığını gördüm (sadece tesadüf olabilir). "PNG" olmadan denedim ama hala şansım yoktu. Yüklediğim resim bir PNG. Herhangi bir yardım takdir edilir! Teşekkürler!

Düzenleme: Eski kodun ve hatanın olduğu yere koyduğum farklı bir hata (yeni koddan) aldım. Eski notları el değmemiş bıraktım. Birkaç hata bulmama yardımcı olması için gre_gor'a borç ver.

Düzenleme 2: Posta yoluyla nasıl ileti gönderileceğini biliyorum. Sadece bir cildin nasıl yükleneceğini merak ettim, bu da neyin yinelenmesi için işaretlendiğinden farklı.

+0

Neden görüntüyü base64 biçiminde kodluyorsunuz? PNG, PNG dosya başlığının bir parçasıdır. "authenticityToken", çerezlerde "access_token" ile aynı değildir. Cilt, "https: // minecraft.net/profile/skin" öğesine yüklenir ve verilerin, "multipart/form-data" biçiminde "application/x-www-form-urlencoded" şeklinde kodlanması gerekir. Bu şeyleri işlemek/ayrıştırmak için bir HTTP kitaplığı kullanmalısınız. –

+0

@gre_gor Çok hızlı yanıt verdiğiniz için teşekkür ederiz. Listelenen hataların çoğunu düzeltdim ve farklı bir hatayı getirdim (Yukarıdaki kodu ve hatayı güncelledim). 'Yanıt kodu 500' olmasının sebebinin, resmin doğru yüklenememesinden kaynaklandığını farz edeyim, düzeltemediğim tek hata buydu. Dış kütüphaneleri kullanmak istemiyorum.Yapmamı istediğin şey konusunda kafam karıştı. 'Out2' ile 'os2' ile yaptığım gibi görüntünün baytını [] yüklediğimi mi öneriyorsunuz? Ve eğer yapsaydım, hala 'cilt' olarak atanan değere sahipken bunu yapmaya nasıl giderim? – ACCFfan

+0

Olası bir kopyası [Java'da HTTP POST İsteği Gönderme] (http://stackoverflow.com/questions/3324717/sending-http-post-request-in-java) – Ferrybig

cevap

1

Dosyaları yüklemek için, verileri multipart/form-data olarak kodlamanız gerekir. Yalnızca Content-Type'un multipart/form-data'a değiştirilmesi, sihirli bir şekilde çalışmasını sağlamaz. Kendiniz için uygun HTTP yükünü oluşturmalısınız. İşte

------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-- 

çalışma kodudur:

O gibi görünmelidir

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); 
     } 
    } 
} 
İlgili konular