Il peut être bon enfant, après avoir connecté votre joueur à votre launcher, d'afficher sa tête, afin de rendre le tout encore plus sublime.
Je vais vous montrer deux manières de récupérer la tête de votre joueurs lorsqu'il sera connecté, ou simplement à l'aide de son pseudonyme pour la première méthode.
0 . Code XAML de la fenêtre
Dans ce tutoriel, aucun graphisme particulier, si ce n'est le minimum requis.
Un bouton , une zone de texte pour le pseudonyme, une zone d'image , et puisqu'on est fous, une bordure . En WPF, bien entendu.
Voici le code XAML de notre fenêtre :
Code (xml):
<Window x:Class ="SkinRetriever.MainWindow"
xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d ="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc ="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local ="clr-namespace:SkinRetriever"
mc:Ignorable ="d"
Title ="MainWindow" Height ="123.835" Width ="226.165" >
<Grid Background ="#FF212121" >
<Button x:Name ="BTN_GET" Content ="Obtenir" HorizontalAlignment ="Center" Margin ="88,47,10,23" VerticalAlignment ="Center" Width ="120" Height ="30" TextOptions.TextHintingMode ="Animated" />
<TextBox x:Name ="TXT_USERNAME" HorizontalAlignment ="Center" Height ="30" Margin ="88,17,10,53" TextWrapping ="Wrap" Text ="Hawezo" VerticalAlignment ="Center" Width ="120" TextAlignment ="Center" TextOptions.TextHintingMode ="Animated" VerticalContentAlignment ="Center" />
<Border BorderBrush ="#FF767676" BorderThickness ="1" HorizontalAlignment ="Left" Height ="64" Margin ="10,10,0,-10" VerticalAlignment ="Top" Width ="64" >
<Image x:Name ="IMG_HEAD" HorizontalAlignment ="Left" Height ="64" Margin ="0" VerticalAlignment ="Top" Width ="64" />
</Border>
</Grid>
</Window>
Comme vous le voyez, c'est une interface tout à fait rudimentaire.
I . La méthode dépendante
Cette méthode, si elle est la plus simple, est celle qui comporte le plus de risque de dysfonctionner.
En effet, son fonctionnement est à base de requête vers des API externes , telles que Minotar , que nous allons utiliser ici.
Double-cliquez sur le bouton BTN_GET afin d'ouvrir son évènement par défaut, Click .
1 . Manière simple
Je vous la déconseille (genre vraiment), mais c'est toujours utile quand même.
La manière la plus simple est de télécharger l'image directement avec un WebClient dans un MemoryStream , sans passer par un autre thread .
D'ailleurs, je déconseille, mais vous faire généralement votre connexion dans un autre thread : si tel est le cas, rien ne vous empêche de mettre cela à la fin de votre thread, ça ne bloquera rien, et dans ce cas, c'est même conseillé !
Vous devez donc créer une variable de type BitmapImage , appeler sa fonction BeginInit() , puis mettre la valeur de son StreamSource à un nouveau MemoryStream nouvellement déclaré, qui lui aura dans son constructeur un nouveau WebClient vide, mais dont on appellera directement la méthode DownloadData , avec comme argument l'URL de Minotar avec le nom du joueur à la fin.
Si vous avez suivi, franchement, bien joué.
Voici le code :
Code (csharp):
BitmapImage head
= new BitmapImage
( ) ; // Création d'un objet BitmapImage
head
. BeginInit ( ) ; // Initialisation de l'objet
head
. StreamSource = new MemoryStream
( new WebClient
( ) . DownloadData ( "https://minotar.net/avatar/" + TXT_USERNAME
. Text ) ) ; // Récupération de l'image grâce à un WebClient couplé d'un MemoryStream, le tout calé dans le StreamSource du BitmapImage
head
. EndInit ( ) ; // Fin de son initialisation
Image image
= this . IMG_HEAD as Image
; // Conversion du contrôle Image
image
. Source = head
; // Affichage de la source
Attention › Ici, je n'ai pas vérifié le contenu de TXT_USERNAME car je n'en ai pas besoin. Vous non plus, si vous avez effectué une connexion et que vous avez récupéré le pseudo, mais sachez qu'un nom d'utilisateur invalide renverra la tête de Steve.
Cliquez pour agrandir...
Il y a également quelque chose auquel il faut faire attention : les exceptions web .
En effet, si vous n'êtes pas connecté à internet, que Minotar est indisponible, ou que vous avez mal écrit l'adresse... attention. À vous de gérer cela avec un try/catch.
2 . La manière chiante compliquée
Si vous n'êtes pas dans un thread, vous devez donc en créer un.
C'est heureusement plutôt simple. Dans l'évènement Click de votre bouton, écrivez :
Code (csharp):
String name
= TXT_USERNAME
. Text ;
Thread headDownload
= new Thread
( ( ) => thread_Head
( name
) ) ;
headDownload
. Start ( ) ;
Maintenant, écrivez la méthode headDownload avec le contenu du code de la manière simple, avec par contre un appel au Dispatcher afin de pouvoir accéder aux éléments du thread de l'IU . Compris ? Allez, je vous le donne.
Code (csharp):
private void thread_Head
( String name
)
{
BitmapImage head
= new BitmapImage
( ) ;
head
. BeginInit ( ) ;
head
. StreamSource = new MemoryStream
( new WebClient
( ) . DownloadData ( "https://minotar.net/avatar/" + name
) ) ;
head
. EndInit ( ) ;
head
. Freeze ( ) ;
this . Dispatcher . Invoke ( ( Action
) ( delegate
{
Image image
= this . IMG_HEAD as Image
; // Conversion du contrôle Image
image
. Source = head
; // Affichage de la source
} ) ) ;
}
II . La manière indépendante
Cette façon de faire est carrément plus complexe, mais vous ne serez pas dépendant d'API comme Minotar.
Elle consiste à télécharger directement le skin, et à en extraire la tête \o/
1 . Télécharger le skin
Il y a plusieurs manières de récupérer le skin du joueur. La première, la plus simple, et de le récupérer directement depuis sa source , à l'adresse suivante :
http://s3.amazonaws.com/MinecraftSkins/ USERNAME.png
Je vais utiliser cette façon de faire par soucis de simplicité.
La seconde méthode est de faire une requête GET à l'adresse https://sessionserver.mojang.com/session/minecraft/profile/UUID et de décoder le texte de la clé "value ", codée en base64 , et de récupérer l'URL de la clé SKIN.url fraîchement obtenue.
C'est moins compliqué que ça en a l'air, mais ça reste fastidieux pour pas grand chose.
Pour information, j'ai développé une API permettant de faire cette requête .
Voici donc le code de mon téléchargement :
Code (csharp):
private void BTN_GET_Click
( object sender, RoutedEventArgs e
)
{
String name
= TXT_USERNAME
. Text ;
Thread headDownload
= new Thread
( ( ) => thread_Head
( name
) ) ;
headDownload
. Start ( ) ;
}
private void thread_Head
( String name
)
{
BitmapImage head
= new BitmapImage
( ) ;
head
. BeginInit ( ) ;
head
. StreamSource = new MemoryStream
( new WebClient
( ) . DownloadData ( "http://s3.amazonaws.com/MinecraftSkins/" + name
+ ".png" ) ) ;
head
. EndInit ( ) ;
head
. Freeze ( ) ;
this . Dispatcher . Invoke ( ( Action
) ( delegate
{
Image image
= this . IMG_HEAD as Image
; // Conversion du contrôle Image
image
. Source = head
; // Affichage de la source
} ) ) ;
}
2 . Découpage de précision
Vous avez maintenant le skin. Il faut maintenant ne récupérer que ce qui nous intéresse : la tête.
Pour cela, rien de plus simple ! À la place de mettre head comme source, découpez votre image à l'aide de CroppedImage .
La tête est située à 8 pixels du bord supérieur gauche (0, 0 ) et mesure 8 pixels .
Code (csharp):
image
. Source = new CroppedBitmap
( head,
new Int32Rect
( 8 ,
8 ,
8 ,
8 ) ) ;
Simplissime... sauf que si vous lancez, votre tête sera floue.
Pour remédier à ce problème, modifier le XAML de votre Image et ajoutez-y RenderOptions.BitmapScalingMode="NearestNeighbor" . Cela a pour effet d'empêcher le floutage des éléments trop petits lors de leur redimensionnement.
Voici le code-behind final :
Code (csharp):
private void BTN_GET_Click
( object sender, RoutedEventArgs e
)
{
String name
= TXT_USERNAME
. Text ;
Thread headDownload
= new Thread
( ( ) => thread_Head
( name
) ) ;
headDownload
. Start ( ) ;
}
private void thread_Head
( String name
)
{
BitmapImage head
= new BitmapImage
( ) ;
head
. BeginInit ( ) ;
head
. StreamSource = new MemoryStream
( new WebClient
( ) . DownloadData ( "https://minotar.net/skin/" + name
+ "" ) ) ;
head
. EndInit ( ) ;
head
. Freeze ( ) ;
this . Dispatcher . Invoke ( ( Action
) ( delegate
{
Image image
= this . IMG_HEAD as Image
; // Conversion du contrôle Image
this . UseLayoutRounding = true ;
image
. UseLayoutRounding = false ;
image
. Source = new CroppedBitmap
( head,
new Int32Rect
( 8 ,
8 ,
8 ,
8 ) ) ; // Affichage de la source
} ) ) ;
}
Je tenais à partager le fait que Minotar peut également fournir d'autres modèles de tête .
En voici les adresses :
Minotar peut également fournir des tailles différentes d'image , en ajoutant simplement "/taille " à la fin de l'url.
Exemple : https://minotar.net/avatar/Hawezo/64
Je vous invite à vous rendre sur la page minotar.net pour vous renseigner.
Voici comment ça rend, de mon côté :
Vous savez maintenant obtenir la tête de votre joueur.
Pensez à bien gérer votre code, à ne pas bloquer l'interface utilisateur grâce à vos threads.
Une bonne organisation est aussi de mise.
Si vous avez des questions, n'hésitez pas.