• S'inscrire
    • Se connecter
    • Recherche
    • Récent
    • Mots-clés
    • Populaire
    • Utilisateurs
    • Groupes

    Résolu Crash serveur avec des EntityThrowable

    1.7.x
    1.7.10
    2
    6
    1015
    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.
    • Adsl Houba
      Adsl Houba dernière édition par

      Bonjour,

      Déjà un grand merci pour les tutoriels et les retours que vous faite aux moddeurs en français !!

      J’ai réalisé un mod pour les besoin d’un jeu sur un serveur modé, l’une des fonctionnalités que j’ai développé, est un périphérique CompterCraft.

      Il tire un projectile totalement décoratif (aucune impact, il permet juste de visualisé des tires entre turtle)

      #1 La premier question, peut on faire apparaître une EntityThrowable uniquement coté client ? (si oui comment ? et le crash pourrait’il se produire coté client ?)

      J’ai réussi à réaliser toutes les fonctionnalités que je voulais mais il arrive que si plusieurs projectiles sont tirés en même temps dans une condition particulière (que je n’ai pas réussi à comprendre) le serveur crash
      J’ai eu que deux crash en 4/5h de test du jeu avec que des tires multiples

      Le crash :

      Description: Exception in server tick loop
      
      java.util.ConcurrentModificationException
      at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
      at java.util.HashMap$KeyIterator.next(HashMap.java:1461)
      at net.minecraft.entity.EntityTracker.func_72788_a(EntityTracker.java:269)
      at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:648)
      at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:334)
      at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:547)
      at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:396)
      at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:685)
      

      (Version complet : https://github.com/mandonnaud/houbmod/blob/master/crashReport )

      L’extrais du code du périphérique :

      EntityProjectil tire=new EntityProjectil(worldObj);
      tire.setPosition(X+0.5, Y+0.5, Z);
      tire.direction((String)arguments[3],vitesse);
      worldObj.spawnEntityInWorld(tire);
      

      ( Code ligne 105 : https://github.com/mandonnaud/houbmod/blob/master/src/main/java/fr/adslhouba/houbmod/common/TileEntityGenLaser.java Ligne

      Le projectil

      package fr.adslhouba.houbmod.common;
      
      import net.minecraft.block.Block;
      import net.minecraft.block.BlockAir;
      import net.minecraft.entity.EntityLivingBase;
      import net.minecraft.entity.projectile.EntityThrowable;
      import net.minecraft.util.MovingObjectPosition;
      import net.minecraft.util.MovingObjectPosition.MovingObjectType;
      import net.minecraft.world.World;
      
      public class EntityProjectil extends EntityThrowable {
      
      private int ticksAlive=0;
      private int ticksAliveMax=400;
      
      public EntityProjectil(World par1World, double par2, double par4, double par6)
      {
      super(par1World, par2, par4, par6);
      }
      public EntityProjectil(World par1World, EntityLivingBase par2EntityLivingBase)
      {
      super(par1World, par2EntityLivingBase);
      }
      public EntityProjectil(World par1World)
      {
      super(par1World);
      this.motionX=0;
      this.motionY=0;
      this.motionZ=0;
      }
      
      public void direction(String direct,double vitesse) {
      this.posZ+=0.5;
      vitesse=vitesse*0.3;
      this.ticksAliveMax=(int) Math.round(120/vitesse)+2;
      if (direct.equals("SOUTH")) {
      this.motionZ=vitesse;
      this.motionX=0;
      //this.posX+=0.5;
      } else if (direct.equals("NORTH")) {
      this.motionZ=vitesse*-1;
      this.motionX=0;
      //this.posX+=0.5;
      } else if (direct.equals("WEST")) {
      this.motionZ=0;
      this.motionX=vitesse*-1;
      //this.posY+=0.5;
      } else if (direct.equals("EAST")) {
      this.motionZ=0;
      this.motionX=vitesse;
      //this.posY+=0.5;
      }
      }
      @Override
      protected void onImpact(MovingObjectPosition mop)
      {
      //this.setDead();
      }
      
         @Override
         public void onUpdate()
         {
          ++this.ticksAlive;
          if (this.ticksAlive<2) {
      
          } else if (this.ticksAlive>this.ticksAliveMax) {
          this.setDead();
          } else {  
          Block test=this.worldObj.getBlock((int)Math.floor(this.posX),(int)Math.floor(this.posY),(int)Math.floor(this.posZ));    
          if (test instanceof BlockAir) {
      
          } else {    
          this.setDead();
          }
          if (!this.isDead) {
          this.setPosition(this.posX, this.posY, this.posZ);
      this.posX += this.motionX;
         this.posZ += this.motionZ;
          }
        }
          }
      }
      

      Github complet du mod : https://github.com/mandonnaud/houbmod/tree/master/src/main/java/fr/adslhouba/houbmod

      Cordialement

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

        Salut,

        Les fonctions de lua sont-elle est exécuté dans un thread à part ? J’ai l’impression que oui, car ton problème c’est que tu fais spawn une entité (ce qui l’ajoute à la liste des entités) en même temps que la liste des entités est parcourus (surement par le thread du serveur).
        https://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html

        Faudrait donc faire spawn l’entité via le thread du serveur si c’est bien ça le problème.

        Quand à faire spawn l’entité sur le client, c’est possible mais l’entité sera purement esthétique, il ne pourra pas interagir sur le monde.

        1 réponse Dernière réponse Répondre Citer 0
        • Adsl Houba
          Adsl Houba dernière édition par

          Je suis développeur php/lua/as, je débute avec java.

          Les fonctions de lua sont-elle est exécuté dans un thread à part ? C’est tous à fait possible vu que le code est lancé via le lua de CC

          Faudrait donc faire spawn l’entité via le thread du serveur si c’est bien ça le problème. Du coup comment ?

          Quand à faire spawn l’entité sur le client, c’est possible mais l’entité sera purement esthétique, il ne pourra pas interagir sur le monde. Elle s’arrete juste quand y a un bloc, c’est tous. Aucune conséquence mais du coups même problème de thread ou pas ?

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

            Pour l’exécuter dans le thread serveur, tu pourra au lieu de faire span l’entité l’ajouter à une liste et via la fonction update du tile entity itérer la liste (avec un iterator pour éviter d’avoir une exception de modification concurrente à ce niveau) et faire spawn chaque entité dans la liste puis la retirer

            Concernant le Spawn de l’entité sur le client seulement, en utilisant un paquet il y a un peu près le même soucis car l’handler du packet est exécuté dans le thread de netty. Mais il y a une fonction pour faire exécuter du contenu dans le thread client (de tête je ne sais plus, je l’envoie dès que je suis sur mon pc)

            1 réponse Dernière réponse Répondre Citer 0
            • Adsl Houba
              Adsl Houba dernière édition par

              J’ai du te relire plusieurs fois pour tous comprendre  😄  (le temps de me remmetre dans le bain) mais j’ai compris je doit mettre le [size=smallspawnEntityInWorld dans la fonction] [size=smallonUpdate updateEntity.  Je capte bien le principe et pourquoi le crash. Merci]

              [EDIT] ok j’ai réussi

              J’attend que tu me retrouve la fonction pour le coté client car autant économisé la ressource serveur

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

                Pour le paquet : https://www.minecraftforgefrance.fr/showthread.php?tid=1118

                Ensuite pour être sur que la fonction s’exécute dans le thread client :

                IThreadListener thread = FMLCommonHandler.instance().getWorldThread(ctx.netHandler);
                if(thread.isCallingFromMinecraftThread())
                {
                this.process();
                }
                else
                {
                thread.addScheduledTask(new Runnable()
                {
                @Override
                public void run()
                {
                Handler.this.process();
                }
                });
                }
                

                Et dans ta fonction process tu fais spawn l’entité.

                1 réponse Dernière réponse Répondre Citer 0
                • 1 / 1
                • Premier message
                  Dernier message
                Design by Woryk
                Contact / Mentions Légales

                MINECRAFT FORGE FRANCE © 2018

                Powered by NodeBB