Rafistolage de Pintech

Alors aujourd’hui, un pote m’a filé deux cymbales Pintech (TC10 et TC16) pour la batterie ion drum rocker… MAIS elles ne fonctionnent plus :'(

Cymbale Pintech TC10

Cymbale Pintech TC10

En fait, en démontant le petit boitier derrière la cymbale, on s’aperçoit de plusieurs choses :

  1. La cymbale n’est en fait qu’un bout de plastique en forme de cymbale avec un transducteur piezo et un jack femelle… La Pintech TC10 est quand même à plus de 35 $ pièce (le piezo et le jack ne représentent pas plus de 1.5 € à eux deux)… Je ne suis pas certain qu’un bout de plastique moulé coûte plus de 30 $ à produire !! Bref !
  2. Le fil reliant le piezo et le jack est en fait sectionné… Rien de bien étonnant vu que l’ensemble est fixé sur de la mousse (et laisse donc les vibrations faire leur office)
Cymbale Pintech TC10

Le fil noir est sectionné

Cymbale Pintech TC10

On voit mieux quand c'est démonté 🙂

Bon du coup, j’ai essayé de rafistoler la chose :

Cymbale Pintech TC10

Fil ressoudé

Remontage, tests, et ça marche nikel chrome ! 😀

Même si on a toutes les chances qu’un des deux fils se casse de nouveau, au moins on peut encore jouer pas mal d’heures avec avant d’en racheter de nouvelles :p

Convertir les TimeStamp Java en DateTime C#

En bidouillant un peu les données récupérées par l’API Wow, je me suis rendu compte que certaines données sont en fait des TimeStamp Java. Le TimeStamp est une unité de mesure du temps utilisé principalement en Java.

Afin de pouvoir utiliser ces données dans mes traitements C#, j’ai fait quelques recherches sur le sujet…

Le TimeStamp Java s’appuie sur une date de référence. Cette date est fixée au 1 janvier 1970 à minuit. En java, lorsque l’on utilise un TimeStamp, il s’agit en réalité du nombre de millième de secondes écoulés depuis la date de référence (1 000 unités TimeSpamp donnent une seconde). En C# en revanche, l’unité de mesure est le tick (1 seconde vaut 10 000 000 ticks sous Windows). Cf. http://msdn.microsoft.com/en-us/library/system.datetime.ticks.aspx pour le détail d’un DateTime C#.

Et bien maintenant c’est tout simple ! Ce n’est qu’un peu de math… Je passe les détails du calcul, mais il suffit de multiplier par 10 000 le TimeStamp Java pour obtenir un nombre de Ticks Windows. Une fois ce nombre calculé, je n’ai plus qu’à l’ajouter à ma date de référence (01/01/1970) et le tour est joué !

Ah si, une dernière remarque : Il faut toujours penser aux fuseaux-horaires quand on joue avec les dates… Donc pour obtenir la vraie date dans le fuseau-horaire courant, il faut appliquer la fonction « ToLocaleTime ». Cette dernière se charge d’appliquer les décalages horaires adéquat en fonction de la machine sur laquelle s’exécute le traitement. Ainsi, plus besoin de s’enquiquiner avec l’ajout d’une ou deux heures…

Allez, un petit bout de code pour le fun :

/// <summary>
/// Helper pour les méthodes de compatibilité Java
/// </summary>
public static class JavaHelper
{
    private static DateTime _referenceDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Unspecified);

    /// <summary>
    /// Fonction permettant de convertir les TimeStamp Java en DateTime C#
    /// </summary>
    /// <param name="timeStamp">TimeStamp Java</param>
    /// <returns>Date C#</returns>
    public static DateTime ConvertJavaTimeStampToDateTime(long timeStamp)
    {
        return _referenceDate.AddTicks(timeStamp * 10000).ToLocalTime();
    }
}

NOTE : Pour le moment, la plus petite unité de mesure du temps que j’ai réussi à trouver sur UNIX est le centième de seconde (0.01 sec). il faut utiliser la fonction POSIX « times » définie dans l’include « sys/times.h ».

Astuce C# du jour : Déplacer les DLL d’un binaire DotNet

En temps normal, sans parler du GAC (Global Assembly Cache), toutes les DLL dont dépendent un binaire C# doivent se trouver dans le même répertoire que ce dernier pour qu’il puisse s’exécuter correctement… Malheureusement, plus les projets grossissent, et plus le nombre de DLL augmente. Ce qui rend l’organisation du répertoire du binaire quelque peu anarchique !

Et bien, voici la solution miracle : Il est possible d’indiquer par configuration les répertoires potentiels où se trouvent les DLL du projet ! 😀

Prenons l’exemple d’une application quelconque « CanShooter.exe » qui a besoin de la DLL « CanShooter.Bean.dll » pour fonctionner. Si nous déplaçons la DLL dans un sous-répertoire « Custom API », l’application ne fonctionne plus !

La magie opère lorsque l’on créé un fichier de configuration de l’application nommé « CanShooter.config » et qui contient les éléments suivants :

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <runtime>
   <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
     <probing privatePath="Custom API"/>
   </assemblyBinding>
 </runtime>
</configuration>

Et voilà, le tour est joué ! 😀

Client Rest

Et voilà, c’est fait ! J’ai fait un petit client Rest tout simplissime en C# 🙂

L’idée est ici d’avoir une petite API qui se charge pour moi de faire l’appel Web et la dé-sérialisation des données dans un objet C#. Je m’appuie sur les contrats WCF pour la définition de l’objet en mémoire (DataContract, DataMember, etc.).

Imaginons que je désire récupérer les informations de mon personnage de Wow avec sa guilde. Blizzard a mis à disposition des serveurs que nous pouvons interroger en JSON. Pour notre cas de figure, la documentation de Blizzard indique ceci :

URL = Host + "/api/wow/character/" + Realm + "/" + CharacterName
       + "?locale=" + locale + "&fields=" + optional(s) field(s)

Realm = <proper realm name> | <normalized realm name>

Ce qui nous donnera un appel Web qui ressemblera à ceci :

GET /api/wow/character/La Croisade écarlate/Shoubido?fields=guild
Host: eu.battle.net

La documentation indique également la structure des données en sortie :

HTTP/1.1 200 OK
<http headers>

{
   "realm": "Medivh",
   "name": "Uther",
   "level": 85,
   "lastModified": 1307596000000,
   "thumbnail": "medivh/1/1-avatar.jpg",
   "race": 1,
   "achievementPoints": 9745,
   "gender": 0,
   "class": 2,
   "guild":{
    "name":"Knights of the Silver Hand",
    "realm":"Medivh",
    "level":25,
    "members":50,
    "achievementPoints":7500,
    "emblem":{
      "icon":119,
      "iconColor":"ffb1b8b1",
      "border":0,
      "borderColor":"ffffffff",
      "backgroundColor":"ff006391"
    }
  }
}

Nous allons dans un premier temps nous focaliser sur la classe qui contiendra les données à récupérer. La déclaration est par exemple la suivante :

    [DataContract]
    public class CharacterRawData : IExtensibleDataObject
    {
        [DataMember(Name = "realm", IsRequired = true)]
        public string Realm { get; set; }

        [DataMember(Name = "name", IsRequired = true)]
        public string Name { get; set; }

        [DataMember(Name = "level", IsRequired = true)]
        public long Level { get; set; }

        [DataMember(Name = "lastModified", IsRequired = true)]
        public long LastModified { get; set; }

        // ... Les autres champs ne sont pas présentés

        public ExtensionDataObject ExtensionData { get; set; }
    }

Le point important dans cette déclaration de classe est qu’il faut hériter de l’interface IExtensibleDataObject. Petit rappel WCF : Cette interface impose la présence de la propriété ExtensionData qui sera alimentée par les champs non déclarés dans la classe au moment de la sérialisation / dé-sérialisation des données par le moteur WCF. Ainsi, nous ne pouvons pas perdre les informations restituées par le serveur de Blizzard.

Une fois cet objet défini, il suffit d’utiliser mon petit client Rest comme suit :

// Création du client Rest
var restClient = new RestClient(new Uri("http://eu.battle.net"));

// On demande au client Rest de récupérer les données
var result = restClient.Retrieve<CharacterRawData>(
  RestResource.Create("/api/wow/character/{realm}/{character name}")
  .AddPathParameter("realm", "La Croisade écarlate")
  .AddPathParameter("character name", "Shoubido")
  .AddQueryParameter("fields", "pvp")
  .AddQueryParameter("locale", CultureInfo.CurrentCulture));

En fait, pour résumer :

  1. Nous créons un client Rest avec l’adresse du serveur que nous désirons interroger
  2. Nous appelons la méthode « Retrieve » du client Rest. Le type générique de cette méthode correspond au type de la classe qu’elle doit utiliser pour dé-sérialiser les données du serveur (Le type doit obligatoirement implémenter l’interface « IExtensibleDataObject »). Donc ici, la variable « result » est de type « CharacterRawData ». La méthode « Retrieve » prend en paramètre une ressource Rest (« RestResource »). Cette ressource définie les éléments nécessaires pour interroger le serveur.
  3. Nous utilisons la méthode statique « RestResource.Create » pour créer une nouvelle ressource Rest. Cette ressource définie l’URL à interroger (chemin + paramètres GET éventuels).
  4. Le chemin est paramétrée avec le nom de la guilde et le nom du personnage. Chaque paramètre du chemin est définie entre accolades. Afin de valoriser ces paramètres, il faut utiliser la fonction « AddPathParameter » qui prend en paramètre le nom du paramètre ainsi que sa valeur (qui peut être de tout type – Le client Rest convertira la valeur en chaîne de caractères).
  5. Enfin, l’URL peut posséder des paramètres GET qui sont valorisés en utilisant la fonction « AddQueryParameter » qui prend en paramètre le nom du paramètre GET ainsi que sa valeur (qui peut être de tout type – Le client Rest convertira la valeur en chaîne de caractères).

Et voilà, le tour est joué ! 😀 Le code source de ce petit client Rest se trouve ici.

Enjoy !

Blizzard nous offre une API Web pour Wow o_O

Depuis le 15/08/2011, Blizzard a mis à disposition une API Web permettant d’interroger les serveurs de Wow. Aujourd’hui, seul la consultation des informations est possible.

On peut par exemple facilement obtenir les informations suivantes :

  • Les caractéristiques de son personnage (hauts faits, montures, familiers, etc.)
  • Les informations d’une guilde (liste des personnages, hauts faits, récompenses, etc.)
  • Le statut des royaumes
  • Les éléments actuellement en vente à l’hôtel des ventes. Dommage que l’on ne puisse pas (encore) acheter ou mettre aux enchères !
  • Les caractéristiques d’un objet du jeu
  • Les informations PvP d’une team

L’avantage de leur API Web est qu’il n’est pas nécessaire d’avoir des outils très compliqués à utiliser pour que cela fonctionne. Leur API est basée sur REST (J’ai volontairement omis les termes de « norme » ou « standard » puisque REST est plus une convention qu’un standard).

Ainsi, si l’on veut obtenir la liste des personnages de ma guilde de Wow, il suffit d’utiliser son navigateur et de lui indiquer l’URL suivante pour obtenir un fichier texte avec toutes les informations dedans : http://eu.battle.net/api/wow/guild/La Croisade écarlate/The Dark Avengers?locale=fr-FR&fields=members.

Blizzard a mis en ligne une documentation de son API ici : http://blizzard.github.com/api-wow-docs/.

Il ne me reste plus qu’à faire un petit client REST 😀