MFF

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

    Modification de la vitesse d'une fireball buggé côté serveur :/

    Planifier Épinglé Verrouillé Déplacé Sans suite
    1.10.x
    31 Messages 3 Publieurs 5.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.
    • robin4002R En ligne
      robin4002 Moddeurs confirmés Rédacteurs Administrateurs
      dernière édition par

      En fait la raison est surment du au fait que les valeurs de look.xCoord, look.yCoord et look.zCoord ne sont pas les mêmes côtés serveur.
      Je ne vois que ça qui pourrait causer ce soucis.

      Pour avoir une balle qui va plus vite fait simplement une classe extends EntityFireball (pas besoin de recréer un équivalent de EntityFireball comme actuellement) et reprend simplement cette partie du code dans le constructeur :

      accelX = accelX + this.rand.nextGaussian() * 0.4D;
      accelY = accelY + this.rand.nextGaussian() * 0.4D;
      accelZ = accelZ + this.rand.nextGaussian() * 0.4D;
      double d0 = (double)MathHelper.sqrt_double(accelX * accelX + accelY * accelY + accelZ * accelZ);
      this.accelerationX = accelX / d0 * 0.1D;
      this.accelerationY = accelY / d0 * 0.1D;
      this.accelerationZ = accelZ / d0 * 0.1D;
      

      En augmentant l’accélération. Exemple :

      accelX = accelX + this.rand.nextGaussian() * 0.4D;
      accelY = accelY + this.rand.nextGaussian() * 0.4D;
      accelZ = accelZ + this.rand.nextGaussian() * 0.4D;
      double d0 = (double)MathHelper.sqrt_double(accelX * accelX + accelY * accelY + accelZ * accelZ);
      this.accelerationX = accelX * 2 / d0 * 0.1D;
      this.accelerationY = accelY * 2 / d0 * 0.1D;
      this.accelerationZ = accelZ * 2 / d0 * 0.1D;
      
      1 réponse Dernière réponse Répondre Citer 0
      • GabsG Hors-ligne
        Gabs
        dernière édition par

        J’ai fais se que tu m’as dis mais y’a un soucis^^

        La vitesse la fireball est bien modifié et tout mais le truc c’est elle part pas droite et de façon aléatoire.
        Pour que elle ne parte pas de travers je fais ça:

        
        if(stack != null && stack.getItem() == /*Item.getByNameOrId("flansmod:9mm")*/Items.APPLE)
            {
            if(cap.getammo9mm() >= 1 | entityplayer.capabilities.isCreativeMode && timer <= 0)
            {
            timer = 20*2;
            Main.network.sendToAllAround(new PacketSounds(58), new NetworkRegistry.TargetPoint(entityplayer.dimension, entityplayer.posX, entityplayer.posY, entityplayer.posZ, 25));
            TEST fireball2 = new TEST(worldIn, entityplayer, look.xCoord, look.yCoord, look.zCoord);
          fireball2.setPosition(
          entityplayer.posX + look.xCoord,
          entityplayer.posY + 1 + look.yCoord,
          entityplayer.posZ + look.zCoord);
          fireball2.accelerationX = look.xCoord;//ça
          fireball2.accelerationY = look.yCoord;//ça
          fireball2.accelerationZ = look.zCoord;//ça
          System.out.println(fireball2.accelerationX + " " + fireball2.accelerationY + " " + fireball2.accelerationZ);
          worldIn.spawnEntityInWorld(fireball2);
          cap.removeammo9mm();
          cap.sync();
          System.out.println(cap.getammo9mm());
            }
        
        

        Mais le soucis c’est que quand je fais ça, la vitesse de la fireball n’est plus modifier forcément …

        J’ai essayer de regarder comment la fireball du ghast faisait mais j’ai pas trop compris x) !

        Voilà donc je sais pas trop comment faire la…

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

          J’ai fais se que tu m’as dis

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

            J’ai fais se que tu m’as dis mais y’a un soucis^^

            La vitesse la fireball est bien modifié et tout mais le truc c’est elle part pas droite et de façon aléatoire (en solo pas testé en multi).
            Pour que elle ne parte pas de travers je fais ça:

            
            if(stack != null && stack.getItem() == /*Item.getByNameOrId("flansmod:9mm")*/Items.APPLE)
                {
                if(cap.getammo9mm() >= 1 | entityplayer.capabilities.isCreativeMode && timer <= 0)
                {
                timer = 20*2;
                Main.network.sendToAllAround(new PacketSounds(58), new NetworkRegistry.TargetPoint(entityplayer.dimension, entityplayer.posX, entityplayer.posY, entityplayer.posZ, 25));
                TEST fireball2 = new TEST(worldIn, entityplayer, look.xCoord, look.yCoord, look.zCoord);
              fireball2.setPosition(
              entityplayer.posX + look.xCoord,
              entityplayer.posY + 1 + look.yCoord,
              entityplayer.posZ + look.zCoord);
              fireball2.accelerationX = look.xCoord;//ça
              fireball2.accelerationY = look.yCoord;//ça
              fireball2.accelerationZ = look.zCoord;//ça
              System.out.println(fireball2.accelerationX + " " + fireball2.accelerationY + " " + fireball2.accelerationZ);
              worldIn.spawnEntityInWorld(fireball2);
              cap.removeammo9mm();
              cap.sync();
              System.out.println(cap.getammo9mm());
                }
            
            

            Mais le soucis c’est que quand je fais ça, la vitesse de la fireball n’est plus modifier forcément …

            J’ai essayer de regarder comment la fireball du ghast faisait mais j’ai pas trop compris x) !

            Voilà donc je sais pas trop comment faire la…

            J’ai essayer de faire le Vec3d dans le constructeur de l’entity la vitesse est modif en solo mais pas multi c’est comme avant…

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

              Vires les 3 lignes avec du random et voila. (celle-ci :
                     accelX = accelX + this.rand.nextGaussian() * 0.4D;
                     accelY = accelY + this.rand.nextGaussian() * 0.4D;
                     accelZ = accelZ + this.rand.nextGaussian() * 0.4D; )

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

                Exact^^ ça ma l’air pas mal je testes en multi ce week-end je te dirais merci 🙂

                EDIT:

                Ouais c’est bon, par contre on voit la fireball partir y’a pas moyen de pas la voir? appart re créer l’entité

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

                  Ouais c’est bon, par contre on voit la fireball partir y’a pas moyen de pas la voir? appart re créer l’entité

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

                    Il faut lui ajouter un rendu et enregistrer l’entité.

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

                      @‘robin4002’:

                      Il faut lui ajouter un rendu et enregistrer l’entité.

                      Ok donc j’ai ajouter mon rendu puis enregistrer comme tu m’as dis:

                      Dans le clientproxy:
                      RenderingRegistry.registerEntityRenderingHandler(Bullet.class, RenderBullet::new);

                      render:

                      
                      package com.CSC.net.Render;
                      
                      import org.lwjgl.opengl.GL11;
                      
                      import com.CSC.net.Entity.EntityBullet;
                      import com.CSC.net.Entity.Bullet;
                      import com.CSC.net.Model.ModelBullet;
                      
                      import net.minecraft.client.Minecraft;
                      import net.minecraft.client.model.ModelBase;
                      import net.minecraft.client.renderer.GlStateManager;
                      import net.minecraft.client.renderer.Tessellator;
                      import net.minecraft.client.renderer.VertexBuffer;
                      import net.minecraft.client.renderer.entity.Render;
                      import net.minecraft.client.renderer.entity.RenderManager;
                      import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
                      import net.minecraft.entity.Entity;
                      import net.minecraft.entity.projectile.EntityArrow;
                      import net.minecraft.util.ResourceLocation;
                      import net.minecraft.util.math.MathHelper;
                      import net.minecraftforge.fml.client.registry.IRenderFactory;
                      
                      public class RenderBullet extends Render
                      {
                      public RenderBullet(RenderManager renderMan)
                          {
                              super(renderMan);
                          } 
                      
                      private static final ResourceLocation bulletTexture = new ResourceLocation("csc:textures/items/bullet.png");
                      
                      protected ResourceLocation getEntityTexture(Bullet bullet)
                          {
                              return bulletTexture;
                          }
                      
                          protected ResourceLocation getEntityTexture(Entity entity)
                          {
                              return this.getEntityTexture((Bullet)entity);
                          }
                      
                          public void doRender(Entity entity, double transX, double transY, double transZ, float param5, float dir)
                          {
                              this.doRender((Bullet)entity, transX, transY, transZ, param5, dir);
                          }
                      
                          public void doRender(Bullet star, double transX, double transY, double transZ, float param5, float dir)
                          {
                          this.bindEntityTexture(star);
                              GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
                              GlStateManager.pushMatrix();
                      
                              GlStateManager.translate((float)transX, (float)transY, (float)transZ);
                              //GlStateManager.rotate(star.prevRotationYaw + (star.rotationYaw - star.prevRotationYaw) * dir - 90.0F, 0.0F, 1.0F, 0.0F);         
                              //GlStateManager.rotate(star.getRandomTilt(), 1.0F, 0.0F, 0.0F);
                      
                              Tessellator tessellator = Tessellator.getInstance();
                              VertexBuffer vertexbuffer = tessellator.getBuffer();
                      
                              GlStateManager.enableRescaleNormal();    
                      
                              float scale = 0.05F;  
                              GlStateManager.scale(scale, scale, scale);
                      
                              GL11.glNormal3f(0.0F, 0.0F,scale);
                      
                              vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX);      
                              vertexbuffer.pos(-2.0D, -2.0D, 0.0D).tex(0, 0);
                              vertexbuffer.pos(2.0D, -2.0D, 0.0D).tex(1, 0);
                              vertexbuffer.pos(2.0D, 2.0D, 0.0D).tex(1, 1);
                              vertexbuffer.pos(-2.0D, 2.0D, 0.0D).tex(0, 1);        
                              tessellator.draw();        
                      
                              GlStateManager.rotate(180.0F, 1.0F, 0.0F, 0.0F);       
                      
                              vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX);        
                              vertexbuffer.pos(-2.0D, -2.0D, 0.0D).tex(0, 0);
                              vertexbuffer.pos(2.0D, -2.0D, 0.0D).tex(1, 0);
                              vertexbuffer.pos(2.0D, 2.0D, 0.0D).tex(1, 1);
                              vertexbuffer.pos(-2.0D, 2.0D, 0.0D).tex(0, 1);        
                              tessellator.draw();
                      
                              GlStateManager.disableRescaleNormal();
                              GlStateManager.popMatrix();
                      
                              super.doRender(star, transX, transY, transZ, param5, dir);
                          }
                      }
                      
                      

                      bullet:

                      
                      public class Bullet extends EntityFireball{
                      
                      public int damage = 0;
                      
                      public Bullet(World worldIn, EntityLivingBase shooter, double accelX, double accelY, double accelZ, int damage) {
                      super(worldIn, shooter, accelX, accelY, accelZ);
                      this.damage = damage;
                              double d0 = (double)MathHelper.sqrt_double(accelX * accelX + accelY * accelY + accelZ * accelZ);
                              this.accelerationX = accelX * 40 / d0 * 0.1D;
                              this.accelerationY = accelY * 40 / d0 * 0.1D;
                              this.accelerationZ = accelZ * 40 / d0 * 0.1D;
                              this.setSize(0.15F, 0.15F);
                      }
                      
                      @Override
                      protected void onImpact(RayTraceResult result) {
                      if (!this.worldObj.isRemote)
                              {
                                  if (result.entityHit != null && this.shootingEntity != null)
                                  {
                                      result.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.shootingEntity), damage);
                                      this.applyEnchantments(this.shootingEntity, result.entityHit);
                                  }
                                  if (result.typeOfHit == RayTraceResult.Type.BLOCK && this.shootingEntity != null)
                              {
                              System.out.println("");
                              if(this.shootingEntity.worldObj.rand.nextInt(2) == 0)
                              {
                              Main.network.sendToAllAround(new PacketSounds(84), new NetworkRegistry.TargetPoint(shootingEntity.dimension, shootingEntity.posX, shootingEntity.posY, shootingEntity.posZ, 10));
                              }
                              }
                      
                                  //boolean flag = this.worldObj.getGameRules().getBoolean("mobGriefing");
                                  //this.worldObj.newExplosion((Entity)null, this.posX, this.posY, this.posZ, (float)this.explosionPower, flag, flag);
                                  this.setDead();
                      
                              }
                      }
                      
                      }
                      
                      

                      La fireball est toujours présente normal?

                      EDIT:

                      Aussi petit question quand je tire ma balle part droite par contre la fireball du moin la texture par de travers normal? je peux réglé ça ou pas?

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

                        Tu as enregistré l’entité ?

                        Et j’ai pas très bien compris ta question.

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

                          Ah oui c’est vrai il faut l’enregistrer l’entité.

                          Euhh j’ai regarder j’ai pas trouvé appart des veille façon de register qui existe plus pour une simple entité apparemment (EntityRegistry).

                          Pour ma question en gros quand je tire avec mon arme mon entity par droite par contre la texture de la fireball par a droite ou a gauche fin elle part dans une direction random au lieux de partir droite je sais si tu vois se que je veux dire sinon je te montrerais .

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

                            Je ne vois pas trop d’où ça pourrait venir 😕

                            Tu dois utiliser cette fonction :
                            EntityRegistry.registerModEntity(entity.class, et je ne sais plus quels paramètres)

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

                              D’accord 😕 bon pas bien grave, maintenant ça fait un petit cube blanc mais y’a toujours les flammes de la fireball

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

                                Bonsoir,

                                Alors maintenant j’ai plus rien^^ et je voudrais voir la texture de ma balle quand je tires.

                                J’ai copier la classe rendu de la fireball mais toujours pareil rien sauf que j’ai une petite erreur qui apparaît quand je tires:

                                
                                [20:25:36] [Server thread/WARN]: Keeping entity Chicken that already exists with UUID 54c121d9-dc18-4f40-a238-c6778a2bad52
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: java.lang.NoSuchMethodException: com.CSC.net.Entity.Bullet.<init>(net.minecraft.world.World)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at java.lang.Class.getConstructor0(Unknown Source)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at java.lang.Class.getConstructor(Unknown Source)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at net.minecraft.entity.EntityList.createEntityFromNBT(EntityList.java:175)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at net.minecraft.world.chunk.storage.AnvilChunkLoader.createEntityFromNBT(AnvilChunkLoader.java:626)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at net.minecraft.world.chunk.storage.AnvilChunkLoader.readChunkEntity(AnvilChunkLoader.java:553)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at net.minecraft.world.chunk.storage.AnvilChunkLoader.loadEntities(AnvilChunkLoader.java:503)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at net.minecraftforge.common.chunkio.ChunkIOProvider.syncCallback(ChunkIOProvider.java:96)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at net.minecraftforge.common.chunkio.ChunkIOExecutor.tick(ChunkIOExecutor.java:150)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:747)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:687)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:536)
                                [20:25:36] [Server thread/INFO] [STDERR]: [net.minecraft.entity.EntityList:createEntityFromNBT:180]: at java.lang.Thread.run(Unknown Source)
                                [20:25:36] [Server thread/WARN]: Skipping Entity with id csc.Bullet
                                
                                

                                Je vous passe m’a classe render:

                                
                                package com.CSC.net.Render;
                                
                                import org.lwjgl.opengl.GL11;
                                
                                import com.CSC.net.Entity.EntityBullet;
                                import com.CSC.net.Entity.Bullet;
                                import com.CSC.net.Model.ModelBullet;
                                
                                import net.minecraft.client.Minecraft;
                                import net.minecraft.client.model.ModelBase;
                                import net.minecraft.client.renderer.GlStateManager;
                                import net.minecraft.client.renderer.Tessellator;
                                import net.minecraft.client.renderer.VertexBuffer;
                                import net.minecraft.client.renderer.entity.Render;
                                import net.minecraft.client.renderer.entity.RenderManager;
                                import net.minecraft.client.renderer.texture.TextureAtlasSprite;
                                import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
                                import net.minecraft.entity.Entity;
                                import net.minecraft.entity.projectile.EntityArrow;
                                import net.minecraft.entity.projectile.EntityFireball;
                                import net.minecraft.init.Items;
                                import net.minecraft.util.ResourceLocation;
                                import net.minecraft.util.math.MathHelper;
                                import net.minecraftforge.fml.client.registry.IRenderFactory;
                                
                                public class RenderBullet extends Render <bullet>{
                                public RenderBullet(RenderManager renderMan)
                                    {
                                        super(renderMan);
                                    } 
                                
                                private static final ResourceLocation bulletTexture = new ResourceLocation("csc:textures/items/bullet.png");
                                
                                public void doRender(Bullet entity, double x, double y, double z, float entityYaw, float partialTicks)
                                    {
                                        GlStateManager.pushMatrix();
                                        this.bindEntityTexture(entity);
                                        GlStateManager.translate((float)x, (float)y, (float)z);
                                        GlStateManager.enableRescaleNormal();
                                        TextureAtlasSprite textureatlassprite = Minecraft.getMinecraft().getRenderItem().getItemModelMesher().getParticleIcon(Items.FIRE_CHARGE);
                                        Tessellator tessellator = Tessellator.getInstance();
                                        VertexBuffer vertexbuffer = tessellator.getBuffer();
                                        float f = textureatlassprite.getMinU();
                                        float f1 = textureatlassprite.getMaxU();
                                        float f2 = textureatlassprite.getMinV();
                                        float f3 = textureatlassprite.getMaxV();
                                        float f4 = 1.0F;
                                        float f5 = 0.5F;
                                        float f6 = 0.25F;
                                        GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
                                        GlStateManager.rotate((float)(this.renderManager.options.thirdPersonView == 2 ? -1 : 1) * -this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F);
                                
                                        if (this.renderOutlines)
                                        {
                                            GlStateManager.enableColorMaterial();
                                            GlStateManager.enableOutlineMode(this.getTeamColor(entity));
                                        }
                                
                                        vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX_NORMAL);
                                        vertexbuffer.pos(-0.5D, -0.25D, 0.0D).tex((double)f, (double)f3).normal(0.0F, 1.0F, 0.0F).endVertex();
                                        vertexbuffer.pos(0.5D, -0.25D, 0.0D).tex((double)f1, (double)f3).normal(0.0F, 1.0F, 0.0F).endVertex();
                                        vertexbuffer.pos(0.5D, 0.75D, 0.0D).tex((double)f1, (double)f2).normal(0.0F, 1.0F, 0.0F).endVertex();
                                        vertexbuffer.pos(-0.5D, 0.75D, 0.0D).tex((double)f, (double)f2).normal(0.0F, 1.0F, 0.0F).endVertex();
                                        tessellator.draw();
                                
                                        if (this.renderOutlines)
                                        {
                                            GlStateManager.disableOutlineMode();
                                            GlStateManager.disableColorMaterial();
                                        }
                                
                                        GlStateManager.disableRescaleNormal();
                                        GlStateManager.popMatrix();
                                        super.doRender(entity, x, y, z, entityYaw, partialTicks);
                                    }
                                
                                @Override
                                protected ResourceLocation getEntityTexture(Bullet entity) {
                                // TODO Auto-generated method stub
                                return bulletTexture;
                                }
                                }
                                
                                

                                Voilà merci 🙂

                                Petite question: Je voudrais faire un genre de viseur laser pour une arme c’est possible ? si oui comment je peux procédé merci :)</bullet></init>

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

                                  Il manque un constructeur avec seulement world dans la classe de ton entité.

                                  Pour le viseur, aucune idée.

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

                                  MINECRAFT FORGE FRANCE © 2024

                                  Powered by NodeBB