MFF

    Minecraft Forge France
    • Récent
    • Mots-clés
    • Populaire
    • Utilisateurs
    • Groupes
    • Forge Events
      • Automatique
      • Foncé
      • Clair
    • S'inscrire
    • Se connecter

    Coremod ajout de la fonction return

    Planifier Épinglé Verrouillé Déplacé Résolu Anciennes versions
    1.6.4
    7 Messages 4 Publieurs 1.7k Vues 1 Watching
    Charger plus de messages
    • Du plus ancien au plus récent
    • Du plus récent au plus ancien
    • Les plus votés
    Répondre
    • Répondre à l'aide d'un nouveau sujet
    Se connecter pour répondre
    Ce sujet a été supprimé. Seuls les utilisateurs avec les droits d'administration peuvent le voir.
    • garganG Hors-ligne
      gargan
      dernière édition par

      Bonjour à tous! j’essaye d’avoir des capes sur mon serveur en utilisant un coremod avec l’asm. J’ai donc fait ça:

      package pickandcraftSkin;
      
      import static org.objectweb.asm.Opcodes.ALOAD;
      import static org.objectweb.asm.Opcodes.INVOKESTATIC;
      
      import java.util.Iterator;
      
      import org.objectweb.asm.ClassReader;
      import org.objectweb.asm.ClassWriter;
      import org.objectweb.asm.tree.AbstractInsnNode;
      import org.objectweb.asm.tree.ClassNode;
      import org.objectweb.asm.tree.InsnList;
      import org.objectweb.asm.tree.MethodInsnNode;
      import org.objectweb.asm.tree.MethodNode;
      import org.objectweb.asm.tree.VarInsnNode;
      
      public class EDClassTransformer implements net.minecraft.launchwrapper.IClassTransformer {
      
      @Override
      public byte[] transform(String arg0, String arg1, byte[] arg2) {
      
      if (arg0.equals("beu")) {
      System.out.println("********* INSIDE OBFUSCATED AbstractClientPlayer TRANSFORMER ABOUT TO PATCH: " + arg0);
      return patchClassASM(arg0, arg2, true);
             }
      
      if (arg0.equals("net.minecraft.client.entity.AbstractClientPlayer")) {
      System.out.println("********* INSIDE AbstractClientPlayer TRANSFORMER ABOUT TO PATCH: " + arg0);
      return patchClassASM(arg0, arg2, false);
             }
             return arg2;
      }
      
      public byte[] patchClassASM(String name, byte[] bytes, boolean obfuscated) {
      
      String targetMethodName = "";
      
             if(obfuscated == true)
              targetMethodName ="d";
             else
              targetMethodName ="getSkinUrl";
      
           //set up ASM class manipulation stuff. Consult the ASM docs for details
         ClassNode classNode = new ClassNode();
             ClassReader classReader = new ClassReader(bytes);
             classReader.accept(classNode, 0);
      
           //Now we loop over all of the methods declared inside the Explosion class until we get to the targetMethodName "doExplosionB"
      
             // find method to inject into
             @SuppressWarnings("unchecked")
             Iterator <methodnode>methods = classNode.methods.iterator();
             while(methods.hasNext())
             {
                 MethodNode m = methods.next();
                 System.out.println("********* Method Name: "+m.name + " Desc:" + m.desc);
      
               //Check if this is doExplosionB and it's method signature is (Z)V which means that it accepts a boolean (Z) and returns a void (V)
                 if ((m.name.equals(targetMethodName) && m.desc.equals("(Ljava/lang/String;)Ljava/lang/String;")))
                 {
                     System.out.println("********* Inside target method!");
                     //on supprime tous les noeuds
                     AbstractInsnNode targetNode = null;
      
                     @SuppressWarnings("unchecked")
                     Iterator <abstractinsnnode>iter = m.instructions.iterator();
                     int index = -1;
      
                     while (iter.hasNext()) {
                         index++;
                         targetNode = iter.next();
                         m.instructions.remove(targetNode);
                     }
      
                     InsnList toInject = new InsnList();
      
      toInject.add(new VarInsnNode(ALOAD, 0));
                         toInject.add(new MethodInsnNode(INVOKESTATIC, "pickandcraftSkin/PlayerCustom", "getURLSkincustom", "(Ljava/lang/String;)Ljava/lang/String;"));
      
                     // inject new instruction list into method instruction list
                     m.instructions.insert(toInject);
      
                     System.out.println("Patching Complete!");
                     break;
                 }
             }
      
           //ASM specific for cleaning up and returning the final bytes for JVM processing.
             ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
             classNode.accept(writer);
             return writer.toByteArray();
           }
      }
      

      Le seul problème c’est que il faudrait ajouter l’instruction return avant l’invocation de la méthode static! comment faire?

      PS je ne suis pas sur que mon code est bon c’est la première fois que j’utilise l’ASM[/java]</abstractinsnnode></methodnode>

      1 réponse Dernière réponse Répondre Citer 0
      • garganG Hors-ligne
        gargan
        dernière édition par

        Personne?

        1 réponse Dernière réponse Répondre Citer 0
        • kevin_68K Hors-ligne
          kevin_68 Moddeurs confirmés
          dernière édition par

          Pas besoin d’asm, en plus il y a un tuto pour ça:
          http://www.minecraftforgefrance.fr/showthread.php?tid=321


          Mettez à jours vers la dernière version stable (1.8.9 voir même…

          1 réponse Dernière réponse Répondre Citer 0
          • jglrxavpokJ Hors-ligne
            jglrxavpok Modérateurs
            dernière édition par

            Explique un peu mieux ton problème.

            Modérateur sur MFF. 
            Mon Github: http://github.com/jglrxavpok
            Mon compte Steam si vous voulez jouer à CS:GO ou TF2 avec moi: https://steamcommunity.com/id/jglrxavpok/

            1 réponse Dernière réponse Répondre Citer 0
            • robin4002R Hors-ligne
              robin4002 Moddeurs confirmés Rédacteurs Administrateurs
              dernière édition par

              Aucune idée, en revanche tu peux faire un système de cape sans passé par l’asm, il y a un tutoriel sur le forum, et sinon tu peux aussi regarder les sources de FFMT lib.
              https://github.com/FFMT/FFMT-libs

              1 réponse Dernière réponse Répondre Citer 0
              • garganG Hors-ligne
                gargan
                dernière édition par

                Oui j’ai regarder le tuto sur le forum et je pense utiliser cette méthode pour les oreilles mais pour le reste c’est plus simple avec l’ASM.
                Pour l’instant j’ai réussi à supprimer le contenu de la méthode getSkinUrl et getCape Url et à ajouter l’invocation d’une méthode static. Je voudrais maintenant réussir à retourner le résultat! Mais je ne sais pas du tout comment faire!

                d’ailleurs si vous connaisez un bon tuto sur l’ASM et les spécification du bytecode en raccourcie même en anglais sa intéresserait, parce que vu la taille du tuto officiel… http://docs.oracle.com/javase/specs/jvms/se5.0/html/VMSpecTOC.doc.html

                1 réponse Dernière réponse Répondre Citer 0
                • garganG Hors-ligne
                  gargan
                  dernière édition par

                  j’ai réussi:

                  SkinFMLLoadingPlugin

                  
                  package pickandcraftSkin;
                  
                  import java.util.Map;
                  
                  import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion;
                  
                  @MCVersion(value = "1.6.4")
                  public class SkinFMLLoadingPlugin implements cpw.mods.fml.relauncher.IFMLLoadingPlugin {
                  
                  @Override
                  public String[] getLibraryRequestClass() {
                  // TODO Auto-generated method stub
                  return null;
                  }
                  
                  @Override
                  public String[] getASMTransformerClass() {
                  //This will return the name of the class "mod.culegooner.ExplosionDropsCore.EDClassTransformer"
                  return new String[]{SkinClassTransformer.class.getName()};
                  }
                  
                  @Override
                  public String getModContainerClass() {
                  //This is the name of our dummy container "mod.culegooner.ExplosionDropsCore.EDDummyContainer"
                  return SkinDummyContainer.class.getName();
                  }
                  
                  @Override
                  public String getSetupClass() {
                  // TODO Auto-generated method stub
                  return null;
                  }
                  
                  @Override
                  public void injectData(Map <string, object="">data) {
                  
                  }
                  
                  }
                  
                  

                  SkinClassTransformer

                  
                  package pickandcraftSkin;
                  
                  import static org.objectweb.asm.Opcodes.ARETURN;
                  import static org.objectweb.asm.Opcodes.ALOAD;
                  import static org.objectweb.asm.Opcodes.INVOKESTATIC;
                  import java.util.Iterator;
                  import org.objectweb.asm.ClassReader;
                  import org.objectweb.asm.ClassWriter;
                  import org.objectweb.asm.tree.ClassNode;
                  import org.objectweb.asm.tree.InsnList;
                  import org.objectweb.asm.tree.InsnNode;
                  import org.objectweb.asm.tree.MethodInsnNode;
                  import org.objectweb.asm.tree.MethodNode;
                  import org.objectweb.asm.tree.VarInsnNode;
                  
                  public class SkinClassTransformer implements net.minecraft.launchwrapper.IClassTransformer {
                  
                  @Override
                  public byte[] transform(String arg0, String arg1, byte[] arg2) {
                  //on cherche la classe qui nous interressent. On gère les deux cas: si elle est "obscurcie" ou pas
                  if (arg0.equals("beu")) {
                  System.out.println("********* INSIDE OBFUSCATED AbstractClientPlayer TRANSFORMER ABOUT TO PATCH: " + arg0);
                  return patchClassASM(arg0, arg2, true);
                  }
                  
                  if (arg0.equals("net.minecraft.client.entity.AbstractClientPlayer")) {
                  System.out.println("********* INSIDE AbstractClientPlayer TRANSFORMER ABOUT TO PATCH: " + arg0);
                  return patchClassASM(arg0, arg2, false);
                  }
                  return arg2;
                  }
                  
                  public byte[] patchClassASM(String name, byte[] bytes, boolean obfuscated) {
                  
                  String targetMethod1Name = "", targetMethod2Name = "";
                  boolean ok1 = false, ok2 = false;
                  
                  if(obfuscated == true) {
                  targetMethod1Name ="d";
                  targetMethod2Name = "e";
                  }
                  else {
                  targetMethod1Name ="getSkinUrl";
                  targetMethod2Name = "getCapeUrl";
                  }
                  
                  //on prépare la manipulation
                  ClassNode classNode = new ClassNode();
                  ClassReader classReader = new ClassReader(bytes);
                  classReader.accept(classNode, 0);
                  
                  //Maintenant, on boucle sur toutes les méthodes déclarées dans la classe jusqu'à trouver la/les methode(s) cible(s)
                  Iterator <methodnode>methods = classNode.methods.iterator();
                  while(methods.hasNext())
                  {
                  MethodNode m = methods.next();
                  System.out.println("********* Method Name: "+m.name + " Desc:" + m.desc);
                  
                  //On vérifie si il s'agit de la méthode cible et si elle a la même signature (http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html)
                  if ((m.name.equals(targetMethod1Name) && m.desc.equals("(Ljava/lang/String;)Ljava/lang/String;")))
                  {
                  System.out.println("********* Inside target method1!");
                  InsnList toInject = new InsnList();
                  
                  toInject.add(new VarInsnNode(ALOAD, 0));
                  toInject.add(new MethodInsnNode(INVOKESTATIC, "pickandcraftSkin/PlayerCustom", "getURLSkinCustom", "(Ljava/lang/String;)Ljava/lang/String;"));
                  toInject.add(new InsnNode(ARETURN));
                  
                  // inject new instruction list into method instruction list
                  m.instructions = toInject;
                  ok1 = true;
                  System.out.println("Patching Method1 Complete!");
                  }
                  else if ((m.name.equals(targetMethod2Name) && m.desc.equals("(Ljava/lang/String;)Ljava/lang/String;")))
                  {
                  System.out.println("********* Inside target2 method!");
                  InsnList toInject = new InsnList();
                  
                  toInject.add(new VarInsnNode(ALOAD, 0));
                  toInject.add(new MethodInsnNode(INVOKESTATIC, "pickandcraftSkin/PlayerCustom", "getURLCapeCustom", "(Ljava/lang/String;)Ljava/lang/String;"));
                  toInject.add(new InsnNode(ARETURN));
                  
                  // inject new instruction list into method instruction list
                  m.instructions = toInject;
                  ok2 = true;
                  System.out.println("Patching Method2 Complete!");
                  }
                  
                  if(ok1 && ok2)
                  break;
                  }
                  
                  //ASM specific for cleaning up and returning the final bytes for JVM processing.
                  ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
                  classNode.accept(writer);
                  return writer.toByteArray();
                  }
                  }
                  
                  

                  PlayerCustom

                  
                  package pickandcraftSkin;
                  
                  import java.net.HttpURLConnection;
                  import java.net.URL;
                  
                  import net.minecraft.util.StringUtils;
                  
                  public class PlayerCustom {
                  
                  private static String connexion (String adress, String par0Str, String part){
                  //on construit l'adresse URL en ajoutant le pseudo + l'extension de l'image (png)
                  int code=404;
                  //on lance une connexion à l'url afin de savoir si il y a un skin d'uploader
                  try {
                  URL u = new URL (adress);
                  HttpURLConnection huc = ( HttpURLConnection ) u.openConnection ();
                  huc.setRequestMethod ("GET");
                  huc.connect () ;
                  //on récupère le code HTTP retourné par le serveur
                  code = huc.getResponseCode() ;
                  System.out.println("SKINURL:code "+code);
                  
                  //si il y est correct on retourne l'adresse
                  if (code == HttpURLConnection.HTTP_OK)
                  return adress;
                  
                  //sinon si il y a une redirection on teste avec la nouvelle url. Bien sur il faudra retourné en php une chaine de texte formaté avec Url du site + le pseudo du joueur + l'extension mais ce n'est pas l'objet de ce tutoriel
                  else if (code == HttpURLConnection.HTTP_MOVED_TEMP
                  || code == HttpURLConnection.HTTP_MOVED_PERM
                  || code == HttpURLConnection.HTTP_SEE_OTHER) {
                  //on récupère la nouvelle adresse
                  String newUrl = huc.getHeaderField("Location");
                  
                  // et on lance une connection avec la nouvelle URL
                  huc = (HttpURLConnection) new URL(newUrl).openConnection();
                  huc.setRequestMethod ("GET");
                  huc.connect () ;
                  code = huc.getResponseCode() ;
                  System.out.println("SKINURL:code "+code);
                  //si cette fois le serveur renvoie un code 200 alors on retourne la nouvelle adresse
                  if (code == HttpURLConnection.HTTP_OK)
                  return newUrl;
                  }
                  }
                  catch(Exception e){
                  System.out.println("SKINURL:Bad Url.");
                  }
                  //si finalement on ne reçoit aucune réponse 200 on retourne l'adresse par défaut
                  return String.format("http://skins.minecraft.net/Minecraft"+ part + "/%s.png", new Object[] {StringUtils.stripControlCodes(par0Str)});
                  }
                  
                  public static String getURLSkinCustom(String par0Str)
                  {
                  String adress=String.format("http://monsite/skins/%s.png", new Object[] {StringUtils.stripControlCodes(par0Str)});
                  return connexion(adress, par0Str, "Skins");
                  }
                  
                  public static String getURLCapeCustom(String par0Str)
                  {
                  String adress=String.format("http://monsite/capes/%s.png", new Object[] {StringUtils.stripControlCodes(par0Str)});
                  return connexion(adress, par0Str, "Cloaks");
                  }
                  
                  }
                  
                  ```</methodnode></string,>
                  1 réponse Dernière réponse Répondre Citer 0
                  • 1 / 1
                  • Premier message
                    Dernier message
                  Design by Woryk
                  ContactMentions Légales

                  MINECRAFT FORGE FRANCE © 2024

                  Powered by NodeBB