1+ /*
2+ * MojangAPI-in-Java--Mojang Public API Java implementation.
3+ * Copyright (C) 2019 XiaoPangxie732
4+ *
5+ * This program is free software: you can redistribute it and/or modify
6+ * it under the terms of the GNU General Public License as published by
7+ * the Free Software Foundation, either version 3 of the License, or
8+ * (at your option) any later version.
9+ *
10+ * This program is distributed in the hope that it will be useful,
11+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ * GNU General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License
16+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
17+ */
18+ package cn .xiaopangxie732 .mojang_api ;
19+
20+ import java .awt .image .BufferedImage ;
21+ import java .io .ByteArrayOutputStream ;
22+ import java .io .File ;
23+ import java .io .IOException ;
24+ import java .io .InputStream ;
25+ import java .io .UnsupportedEncodingException ;
26+ import java .net .HttpURLConnection ;
27+ import java .net .MalformedURLException ;
28+ import java .net .URI ;
29+ import java .net .URL ;
30+ import java .net .URLEncoder ;
31+ import java .util .Properties ;
32+
33+ import javax .imageio .ImageIO ;
34+ import com .google .gson .Gson ;
35+
36+ import cn .xiaopangxie732 .mojang_api .util .Auth ;
37+
38+ public class Skin {
39+ /**
40+ * To change skin.
41+ * @param access_token The access token of UUID's account.
42+ * @param isSlim Skin is slim or not.
43+ * @param uuid UUID of player. can be get be using {@link UserName#UUIDAtNow(String)}
44+ * @param uri The skin image path. if it is a local file, it needs add a prefix "file:///" and replace "\\" to "/"(Windows).
45+ */
46+ public static void changeSkin (String access_token , boolean isSlim , String uuid , URI uri ) {
47+ try {
48+ String response = Auth .postConnection ("https://api.mojang.com/user/profile/" + uuid
49+ +"/skin" , "model=" + (isSlim ? "slim" : "" ) + "&url=" +
50+ URLEncoder .encode (uri .toURL ().toString (), "UTF-8" ), access_token );
51+ if (response != null )
52+ throw new IllegalArgumentException ("Failed to change skin" );
53+ } catch (UnsupportedEncodingException | MalformedURLException e ) {
54+ e .printStackTrace ();
55+ }
56+ }
57+ public static void changeSkinAndUpload (String access_token , boolean isSlim , String uuid , URI uri ) {
58+ StringBuffer response = new StringBuffer ();
59+ HttpURLConnection connection = null ;
60+ try {
61+ connection = (HttpURLConnection )(new URL ("https://api.mojang.com/user/profile/" + uuid
62+ +"/skin" ).openConnection ());
63+ connection .setDoOutput (true );
64+ connection .setRequestMethod ("PUT" );
65+ connection .setRequestProperty ("Authorization" , "Bearer " + access_token );
66+ /*
67+ * The boundary is Base64-encoded of "MojangAPI-in-Java_datatransfer"
68+ */
69+ connection .setRequestProperty ("Content-Type" , "multipart/form-data; boundary=TW9qYW5nQVBJLWluLUphdmFfZGF0YXRyYW5zZmVy" );
70+
71+ ByteArrayOutputStream baos = new ByteArrayOutputStream ();
72+ ImageIO .write (ImageIO .read (new File (uri )), new File (uri ).getName ().split ("." )[1 ], baos );
73+
74+ connection .getOutputStream ().write (new String (
75+ "--TW9qYW5nQVBJLWluLUphdmFfZGF0YXRyYW5zZmVy\r \n " +
76+ "Content-Disposition: form-data; name=\" model\" \r \n " +
77+ "\r \n " +
78+ "\r \n " +
79+ "--TW9qYW5nQVBJLWluLUphdmFfZGF0YXRyYW5zZmVy\r \n " +
80+ "Content-Disposition: form-data; name=\" file\" ; filename=\" skin.png\" \r \n " +
81+ "Content-Type: image/png\r \n " +
82+ (isSlim ? "slim" : "" ) + "\r \n " +
83+ new String (baos .toByteArray ()) + "\r \n " +
84+ "--TW9qYW5nQVBJLWluLUphdmFfZGF0YXRyYW5zZmVy--" ).getBytes ("UTF-8" ));
85+ connection .connect ();
86+ InputStream in = connection .getInputStream ();
87+ int i ;
88+ while ((i = in .read ())!= -1 ) {
89+ response .append ((char )i );
90+ }
91+ } catch (IOException ioe ) {
92+ InputStream err = connection .getErrorStream ();
93+ int i ;
94+ try {
95+ while ((i = err .read ())!= -1 ) {
96+ response .append ((char )i );
97+ }
98+ } catch (IOException e1 ) {
99+ e1 .printStackTrace ();
100+ }
101+ throw new IllegalStateException (new Gson ().fromJson (response .toString (), Properties .class ).getProperty ("errorMessage" ));
102+ } catch (Exception e ) {
103+ e .printStackTrace ();
104+ } finally {
105+ connection .disconnect ();
106+ }
107+ }
108+ public static void resetSkin (String access_token , String uuid ) {
109+ StringBuffer response = new StringBuffer ();
110+ HttpURLConnection connection = null ;
111+ try {
112+ connection = (HttpURLConnection )(new URL ("https://api.mojang.com/user/profile/" + uuid
113+ +"/skin" ).openConnection ());
114+ connection .setDoOutput (true );
115+ connection .setRequestMethod ("DELETE" );
116+ connection .setRequestProperty ("Authorization" , "Bearer " + access_token );
117+ connection .connect ();
118+ InputStream in = connection .getInputStream ();
119+ int i ;
120+ while ((i = in .read ())!= -1 ) {
121+ response .append ((char )i );
122+ }
123+ } catch (IOException ioe ) {
124+ InputStream err = connection .getErrorStream ();
125+ int i ;
126+ try {
127+ while ((i = err .read ())!= -1 ) {
128+ response .append ((char )i );
129+ }
130+ } catch (IOException e1 ) {
131+ e1 .printStackTrace ();
132+ }
133+ throw new IllegalStateException (new Gson ().fromJson (response .toString (), Properties .class ).getProperty ("errorMessage" ));
134+ } catch (Exception e ) {
135+ e .printStackTrace ();
136+ } finally {
137+ connection .disconnect ();
138+ }
139+ }
140+ }
0 commit comments