Jump to content

ElTotisPro50

Members
  • Posts

    266
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by ElTotisPro50

  1. Hi, im making a BlockEntity that can contain fluids, and render them in the GUI, only one fluid works perfectly, I can fill or drain it, sync it to the client, and render it. The problem comes when i try to have two fluids in the same GUI, depending on what I delete or leave, the fluids act differently; for example, deleting both of them from "saveAdditional" and "load" methods makes that the fluids cannot render. Also, it can only render one fluid alone, or again, render one fluid, but twice (copies one fluid to the other one). FYI the left one is water, the right one is a red custom fluid. How can I fix this? BoilerBlockEntity: https://pastebin.com/e6b2U3sD BoilerMenu: https://pastebin.com/D375yCNr BoilerScreen: https://pastebin.com/WMrK83Du
  2. Im trying to render a simple line using the "RenderLevelStageEvent", for testing, i put the start position above a diamond block, and the end position 5 blocks above the diamond block; The line rendering is almost good, but for some reason, apart from the original line, its rendering a second line that kind of looks "fake", it moves along with the camera, its like a ghost line that should not exist. Here is an example video: https://imgur.com/a/GRkSLVX Renderer.java @SubscribeEvent public static void test(RenderLevelStageEvent event) { if(Minecraft.getInstance().player == null) return; Player player = Minecraft.getInstance().player; Vec3 proj = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition(); double vpX = proj.x; double vpY = proj.y; double vpZ = proj.z; drawLine(event.getPoseStack(), new Vec3(11 - vpX, -60 - vpY, 12 - vpZ), new Vec3(11 - vpX, -55 - vpY, 12 - vpZ), new Color(255,0,0), 255); } public static void drawLine(PoseStack stack, Vec3 start, Vec3 end, Color color, int alpha) { RenderType rtype = new NoDepthWrappedRenderLayer(TotisRenderType.createLinesRenderType(3.0D, 0)); Matrix4f m = stack.last().pose(); Matrix3f norm = stack.last().normal(); MultiBufferSource.BufferSource buffer = Minecraft.getInstance().renderBuffers().bufferSource(); VertexConsumer bb = buffer.getBuffer(rtype); bb.vertex(m,(float)start.x,(float)start.y,(float)start.z).color(color.getRed(),color.getGreen(),color.getBlue(), alpha).normal(norm, 1.0F, 0.0F, 0.0F).endVertex(); bb.vertex(m,(float)end.x,(float)start.y,(float)start.z).color(color.getRed(),color.getGreen(),color.getBlue(), alpha).normal(norm, 1.0F, 0.0F, 0.0F).endVertex(); bb.vertex(m,(float)start.x,(float)start.y,(float)start.z).color(color.getRed(),color.getGreen(),color.getBlue(), alpha).normal(norm, 0.0F, 1.0F, 0.0F).endVertex(); bb.vertex(m,(float)start.x,(float)end.y,(float)start.z).color(color.getRed(),color.getGreen(),color.getBlue(), alpha).normal(norm, 0.0F, 1.0F, 0.0F).endVertex(); buffer.endBatch(rtype); //Btw im rendering 4 vertex because only two draws a 2D line, which looks good from one side, but thinner from the other, so this renders a 3D line that looks fine from any perspective } TotisRenderType.java: public class TotisRenderType extends RenderType { public TotisRenderType(String nameIn, VertexFormat formatIn, VertexFormat.Mode drawModeIn, int bufferSizeIn, boolean useDelegateIn, boolean needsSortingIn, Runnable setupTaskIn, Runnable clearTaskIn) { super(nameIn, formatIn, drawModeIn, bufferSizeIn, useDelegateIn, needsSortingIn, setupTaskIn, clearTaskIn); } public static RenderType createLinesRenderType(double width, int index) { return create("totis_lines" + index, DefaultVertexFormat.POSITION_COLOR_NORMAL, VertexFormat.Mode.LINES, 256, false, false, CompositeState.builder().setLayeringState(VIEW_OFFSET_Z_LAYERING).setLineState(new LineStateShard(OptionalDouble.of(width))).setShaderState(RENDERTYPE_LINES_SHADER).setTextureState(RenderStateShard.NO_TEXTURE).setTransparencyState(TRANSLUCENT_TRANSPARENCY).setDepthTestState(RenderStateShard.NO_DEPTH_TEST).setCullState(NO_CULL).setWriteMaskState(RenderStateShard.COLOR_WRITE).setLightmapState(NO_LIGHTMAP).createCompositeState(false)); } } NoDepthWrappedRenderLayer.java: public class NoDepthWrappedRenderLayer extends RenderType { private final RenderType delegate; public NoDepthWrappedRenderLayer(RenderType delegate) { super(Constants.MOD_ID + "no_depth", delegate.format(), delegate.mode(), delegate.bufferSize(), true, delegate.isOutline(), () -> { delegate.setupRenderState(); RenderSystem.disableDepthTest(); }, () -> { RenderSystem.enableDepthTest(); delegate.clearRenderState(); }); this.delegate = delegate; } public Optional<RenderType> m_7280_() { return this.delegate.outline(); } public boolean equals(@Nullable Object other) { return other instanceof NoDepthWrappedRenderLayer && this.delegate.equals(((NoDepthWrappedRenderLayer)other).delegate); } public int hashCode() { return Objects.hash(new Object[]{this.delegate}); } }
  3. i actually wanted to do something similar, apply some rendering to the player to make something like a blur, im looking at some shaders with .frag and .vert, but i dont know how would I apply them, do you know something that may help me?
  4. In 1.18.2 version I managed to started creating mixins, but the build.gradle file changed a bit in 1.19.4, and i don't know where to put the mixins stuff to start creating them. -Here's my 1.18.2 build.gradle file, i left comments like this "--------------------------------------------" where i put the stuff for adding mixins: https://pastebin.com/Gcq7E1Bp -Here's the new build.gradle from 1.19.4: https://pastebin.com/V8hMqjCS Probably it's the same, but i want to be sure
  5. https://github.com/Totis22/Change-players-skin-1.18.2/tree/main Remember that in the main method for changing skin, it requires any boolean condition/s. If all conditions are true the skin changes, but if one condition is false, it changes you back to your original skin. If "start with random skin" means, change player's skin when they enter the world, just use the same ".renderSkin()" method in the RenderHandEvent, selecting a downloaded random skin from your mod, or interacting with a skins web page, then, when you hold the item, stop the .renderSkin something like this: @SubscribeEvent public static void randomSkinManagment(EntityJoinWorldEvent event) { if (event.getEntity() instanceof Player) { Player player = (Player) event.getEntity(); skin = skins.get(rand.nextInt(skins.size())); } } @SubscribeEvent public static void playerHoldSword(TickEvent.PlayerTickEvent event) { if(event.player == null) return; Player player = event.player; if(player.getMainHandItem().is(Items.DIAMOND_SWORD)) { //save NBT Data to player: player.somewhereinNBTDATA.heldSword = true; } } @SubscribeEvent public static void renderSkinEvent(RenderLivingEvent event) { TotisCustomSkinRenderer.renderSkin( new ResourceLocation(Constants.MOD_ID, "textures/skins/" + skin + ".png"), event, event.getEntity(), false, player.somewhereinNBTDATA.heldSword == true); }
  6. would you upload the full code here or to github? I have been having problems with this
  7. im trying to render a simple line (two vertex) in the world, so im using RenderLevelLastEvent, the problem is that, is not working (does not render anything), the game does not crash, or give errors, or anything, if you know a bit about this, can you help to solve this? thanks btw: the start and end Vecs are positions of 2 blocks on my world, I tripled checked them, the positions are correct, so the problem is not the start and end positions. @SubscribeEvent public static void test(RenderLevelLastEvent event) { if (mc.player != null && mc.player.isAlive()) { Player player = mc.player; Level level = player.level; PoseStack stack = event.getPoseStack(); Matrix4f matrix = stack.last().pose(); Tesselator tesselator = Tesselator.getInstance(); BufferBuilder buffer = tesselator.getBuilder(); Vec3 start = new Vec3(-74, -61 ,-39); Vec3 end = new Vec3(-74, -54 ,-39); RenderSystem.disableTexture(); RenderSystem.enableDepthTest(); RenderSystem.depthFunc(515); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.depthMask(false); drawLine(start,end, 1.0f); RenderSystem.enableCull(); RenderSystem.depthMask(true); RenderSystem.disableBlend(); RenderSystem.defaultBlendFunc(); RenderSystem.enableTexture(); } public static void drawLine(Vec3 start, Vec3 end, float alpha) { if(start == null || end == null) return; PoseStack stack = RenderSystem.getModelViewStack(); Matrix4f matrix = stack.last().pose(); Tesselator tes = Tesselator.getInstance(); BufferBuilder buffer = tes.getBuilder(); RenderSystem.setShader(GameRenderer::getPositionColorShader); RenderSystem.lineWidth(1); buffer.begin(VertexFormat.Mode.DEBUG_LINES, DefaultVertexFormat.POSITION_COLOR); buffer.vertex(matrix,(float)start.x,(float)start.y,(float)start.z).color(1.0f,1.0f,1.0f, alpha).endVertex(); buffer.vertex(matrix,(float)end.x,(float)end.y,(float)end.z).color(1.0f,1.0f,1.0f, alpha).endVertex(); tes.end(); }
  8. this things can be rendered from anywhere? or i have to use the "RenderLevelLastEvent"?
  9. So, i want to render complex visual effects in minecraft 1.18.2, from creating simple lines, to things more complicated, like ray beams, electricity/lightning, explosions, player rendering, etc. Im guessing i need the knowledge of Tesselator, BufferBuilder, OpenGL etc. Do you know where could i learn from almost 0 this things? I dont mean a tutorial for creating this effects, but something to get me started, and something to give me enough knowledge to start this renderings.
  10. You know how can i do this for 1.18.2? i mean if you updated the code i would like to see it, and modify it for other purposes
  11. menu.getBlockEntity().getBlockPos() is the default method that gets the worldposition of the block entity, i checked just in case, and the position is correct: player.sendMessage(new TextComponent(menu.getBlockEntity().getBlockPos().getX()+","+menu.getBlockEntity().getBlockPos().getY()+","+menu.getBlockEntity().getBlockPos().getZ()), player.getUUID()); with "The order you write the bytes must be the order your read them." you mean i have to order the readers and writers in the constructor's order? public PacketSyncTeleporter2S( int dest, int x,int y,int z, int selected, boolean exists, String dimension, String name, BlockPos pos) { this.blockPos = pos; this.exists = exists; this.name = name; this.dimension = dimension; this.dest = dest; this.x = x; this.y = y; this.z = z; this.selected = selected; } //read public PacketSyncTeleporter2S(FriendlyByteBuf buf) { this.dimension = buf.readUtf(); this.name = buf.readUtf(); this.blockPos = buf.readBlockPos(); this.x = buf.readInt(); this.y = buf.readInt(); this.z = buf.readInt(); this.exists = buf.readBoolean(); this.dest = buf.readInt(); this.selected = buf.readInt(); } //write public void toBytes(FriendlyByteBuf buf) { buf.writeInt(x); buf.writeInt(y); buf.writeInt(z); buf.writeInt(selected); buf.writeInt(dest); buf.writeUtf(dimension); buf.writeUtf(name); buf.writeBoolean(exists); buf.writeBlockPos(blockPos); }
  12. I still cant figure it out, im trying to pass the variables from the screen to the block entity, actually, if i pass the values without sending them to the server with a package, it works, but if i close the menu and open it again the information removes public void savePos(int q) { ItemStack item = menu.getBlockEntity().getItemFromSlot(0); CompoundTag tag = item.getTag(); if(tag != null && tag.contains("hasInfo")) { String name = (!item.hasCustomHoverName()) ? "" : TotisPlayerUtils.getItemDisplayName(item); //ModMessages.sendToServer(new PacketSyncTeleporter2S(q, tag.getInt("x"),tag.getInt("y"),tag.getInt("z"), q, true, tag.getString(Constants.DIMENSION), name, menu.getBlockEntity().getBlockPos())); menu.getBlockEntity().setPosX(tag.getInt("x"), q); menu.getBlockEntity().setPosY(tag.getInt("y"), q); menu.getBlockEntity().setPosZ(tag.getInt("z"), q); menu.getBlockEntity().setSelectedWheelPart(q); menu.getBlockEntity().setDestName(q,name); menu.getBlockEntity().setDestExists(q,true); menu.getBlockEntity().setDestDimension(q,tag.getString(Constants.DIMENSION)); player.sendMessage(new TextComponent("Saved position in space "+q), player.getUUID()); } }
  13. I solved that, but now, I can't send information from screen to blockentity, it doesnt crash or anything, it just doesnt send what i need TeleporterScreen: https://pastebin.com/Qbp4GKK0 WarpPipeBlockEntity: https://pastebin.com/s6dXa7EX PacketSyncTeleporter2S: https://pastebin.com/u0S1jDx8 PacketSyncTeleporterPosToClient: https://pastebin.com/7A0Wccfc
  14. When I say information i mean strings, booleans, integers; saved in the block entity I made a block entity that can teleport me to 8 different saved locations, but for some reason, the information that i put from the screen to the block entity synchronizes with other places block entities, if i place one, break it and place it again the information should remove, but it doesnt. And if i place 2 or more block entities and modify one of them, the other one modifies too, basically like an ender chest, they sync with each-other and that SHOULD NOT happen (Video: https://imgur.com/a/viFLTRy) I spent days looking at the code and i cant find the bug lol BTW: the code is not clean and obviously is bad written, but right now my priority is to solve this problem; later, i will clean the code WarpPipeBlockEntity: https://pastebin.com/mGCNHwwm TeleporterMenu: https://pastebin.com/ZdwJ8DvP TeleporterScreen: https://pastebin.com/HELZBAqQ TeleportCrystalItem: https://pastebin.com/8fD9wkdW PacketSyncTeleporterPosToClient: https://pastebin.com/RNyY1miv ModMessages: https://pastebin.com/Zw0ShuLs
  15. it didnt work: @Mod.EventBusSubscriber(modid = Constants.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) public abstract class ModBusClientEvents { @SubscribeEvent public static void register(RegisterCapabilitiesEvent event) { event.register(PlayerThirst.class); } }
  16. I followed a tutorial on this(https://www.youtube.com/watch?v=My70x9LzeUM&t=297s) because i never had to use capabilities until now, the tutorial is for 1.19 but the process is exactly the same as 1.18.2. For testing, my capability is the same as the tutorial (thirst for players) but it's not working, when i press a key it removes 1 "thirst" and sends a message but nothing happens, no errors or crashes, i also tried to do the same but with a package sending it to the server just in case, but APPARENTLY AND FOR NOW, it has nothing to do with client and server. So maybe im attaching the capability to the player wrong? (BTW: the key pressing works correctly, so thats not the problem) public class PlayerThirstProvider implements ICapabilityProvider, INBTSerializable<CompoundTag> { public static Capability<PlayerThirst> CAPABILITY_PLAYER_DATA = CapabilityManager.get(new CapabilityToken<>() {}); private LazyOptional<PlayerThirst> optional = LazyOptional.of(this::create); PlayerThirst thirst = null; private PlayerThirst create() { if(this.thirst == null) { this.thirst = new PlayerThirst(); } return this.thirst; } @NotNull @Override public <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) { if(cap == CAPABILITY_PLAYER_DATA) { return optional.cast(); } return LazyOptional.empty(); } @Override public CompoundTag serializeNBT() { CompoundTag tag = new CompoundTag(); create().save(tag); return tag; } @Override public void deserializeNBT(CompoundTag nbt) { create().load(nbt); } } public class PlayerThirst { private int thirst; public int getThirst() { return this.thirst; } public void addThirst(int thirst) { this.thirst = Math.min(this.thirst + thirst, 10); } public void subThirst(int thirst) { this.thirst = Math.max(this.thirst - thirst, 0); } public void copyFrom(PlayerThirst source) { this.thirst = source.thirst; } public void save(CompoundTag tag) { tag.putInt("thirst", this.thirst); } public void load(CompoundTag tag) { this.thirst = tag.getInt("thirst"); } } @Mod.EventBusSubscriber(modid = Constants.MOD_ID) public abstract class ClientEvents { @SubscribeEvent public static void keyPress2(InputEvent.KeyInputEvent event) { if(ModKeybinds.MY_KEY.consumeClick()) { //ModMessages.sendToServer(new PacketThirst()); mc.player.getCapability(PlayerThirstProvider.CAPABILITY_PLAYER_DATA).ifPresent(thirst -> { thirst.subThirst(1); mc.player.sendMessage(new TextComponent(""+thirst.getThirst()),mc.player.getUUID()); }); } } @SubscribeEvent public static void register(RegisterCapabilitiesEvent event) { event.register(PlayerThirst.class); } @SubscribeEvent public void attachCapabilities(AttachCapabilitiesEvent<Entity> event) { if (event.getObject() instanceof Player) { if(!event.getObject().getCapability(PlayerThirstProvider.CAPABILITY_PLAYER_DATA).isPresent()) { event.addCapability(new ResourceLocation(Constants.MOD_ID, "playerdata"), new PlayerThirstProvider()); } } } @SubscribeEvent public static void onPlayerCloned(PlayerEvent.Clone event) { if (event.isWasDeath()) { event.getOriginal().getCapability(PlayerThirstProvider.CAPABILITY_PLAYER_DATA).ifPresent(oldStore -> { event.getPlayer().getCapability(PlayerThirstProvider.CAPABILITY_PLAYER_DATA).ifPresent(newStore -> { newStore.copyFrom(oldStore); }); }); } } } public class PacketThirst { public PacketThirst() { } // Read public PacketThirst(FriendlyByteBuf buf) { } public void write(FriendlyByteBuf buf) { } public boolean handle(Supplier<NetworkEvent.Context> ctx) { NetworkEvent.Context context = ctx.get(); context.enqueueWork(() -> { ServerPlayer serverPlayer = context.getSender(); serverPlayer.getCapability(PlayerThirstProvider.CAPABILITY_PLAYER_DATA).ifPresent(thirst -> { thirst.subThirst(1); serverPlayer.sendMessage(new TextComponent(""+thirst.getThirst()),serverPlayer.getUUID()); }); }); return true; } }
  17. So i created a custom model, and im rendering it to the player (im creating a hat) using the RenderLayer class, it renders correctly but it moves along with the body, not the head, it would be useful if im creating a backpack model but im not. So I have to make it rotate with the head like a normal hat would, i grabbed the rotation code from "Hats" mod by IChun (by now is just the pitch for testing) but is not working stack.rotate(Vector3f.XP.rotationDegrees(player.rotPitch)); //IChun solution This is how it looks in-game: https://imgur.com/a/lbV3VUk (The shape doesnt matter, is just a test) public class LivingEntityHatLayer<T extends LivingEntity> extends RenderLayer<T, EntityModel<T>> { private final List<HatData<T>> hats; public LivingEntityHatLayer(RenderLayerParent<T, EntityModel<T>> pRenderer, EntityModelSet modelSet) { super(pRenderer); hats = createHats(modelSet); } //This is the important part @Override public void render(PoseStack pose, MultiBufferSource pBuffer, int pPackedLight, T entity, float pLimbSwing, float pLimbSwingAmount, float pPartialTicks, float pAgeInTicks, float pNetHeadYaw, float pHeadPitch) { for(var entry : hats) { if(entity instanceof Player player) { if(player.isInvisible()) return; EntityModel<T> model = entry.getModel(); VertexConsumer vertexConsumer = pBuffer.getBuffer(RenderType.entityCutout(entry.getModel().getTextureLocation())); pose.translate(entry.getTranslation().x(),entry.getTranslation().y(),entry.getTranslation().z()); pose.scale(entry.getScale().x(), entry.getScale().y(), entry.getScale().z()); pose.mulPose(Vector3f.XP.rotationDegrees(player.rotPitch)); //This is where i need help this.getParentModel().copyPropertiesTo(model); model.prepareMobModel(entity, pLimbSwing, pLimbSwingAmount, pPartialTicks); model.setupAnim(entity, pLimbSwing, pLimbSwingAmount, pAgeInTicks, pNetHeadYaw, pHeadPitch); model.renderToBuffer(pose, vertexConsumer, pPackedLight, LivingEntityRenderer.getOverlayCoords(entity, 0.0F), 1.0F, 1.0F, 1.0F, 1.0F); } } } private List<HatData<T>> createHats(EntityModelSet modelSet) { List<HatData<T>> list = new ArrayList<>(); list.add(new HatData<>("Dick", new DickHat<>(modelSet.bakeLayer(DickHat.LAYER_LOCATION)), new Vector3f(0,-1.65f,0),new Vector3f(0.75f,0.75f,0.75f),new Vector3f(0,0,0))); return list; } }
  18. i looked source code from some mods that store player xp, to remove it they use this method from OpenMods: https://github.com/OpenMods/OpenModsLib/blob/1.16/src/main/java/openmods/utils/EnchantmentUtils.java The place i looked at: https://github.com/bl4ckscor3/XP-Tome/blob/1.18/src/main/java/bl4ckscor3/mod/xptome/XPTomeItem.java#L76 (from line 70 to 76) I copied the class too, and even used both PlayerXpEvents, at first it removes the xp i put but when i kill myself or something is like the xp never leaved me, it is not a "keepinventoryrule" cause im removing the xp from code :b BTW: in case you need to know, im removing the xp from a screen (client) when i press a button public class TotisPlayerUtils { private static int sum(int n, int a0, int d) { return n * (2 * a0 + (n - 1) * d) / 2; } private static int xpBarCap(int level) { if (level >= 30) return 112 + (level - 30) * 9; if (level >= 15) return 37 + (level - 15) * 5; return 7 + level * 2; } public static int getLevelForExperience(int targetXp) { int level = 0; while (true) { final int xpToNextLevel = xpBarCap(level); if (targetXp < xpToNextLevel) return level; level++; targetXp -= xpToNextLevel; } } public static int getExperienceForLevel(int level) { if (level == 0) return 0; if (level <= 15) return sum(level, 7, 2); if (level <= 30) return 315 + sum(level - 15, 37, 5); return 1395 + sum(level - 30, 112, 9); } public static int getPlayerXP(Player player) { return (int)(getExperienceForLevel(player.experienceLevel) + (player.experienceProgress * player.getXpNeededForNextLevel())); } public static void addPlayerXP(Player player, int amount) { int experience = getPlayerXP(player) + amount; player.totalExperience = experience; player.experienceLevel = getLevelForExperience(experience); int expForLevel = getExperienceForLevel(player.experienceLevel); player.experienceProgress = (experience - expForLevel) / (float)player.getXpNeededForNextLevel(); } } The screen part int xp = TotisPlayerUtils.getPlayerXP(player); if(xp >= 1) { int depositedXp = 20; int previousLevel = player.experienceLevel; MinecraftForge.EVENT_BUS.post(new PlayerXpEvent.XpChange(player, -depositedXp)); TotisPlayerUtils.addPlayerXP(player, -depositedXp); //should remove 20 xp, it does but not permanently if(previousLevel != player.experienceLevel) MinecraftForge.EVENT_BUS.post(new PlayerXpEvent.LevelChange(player, player.experienceLevel)); } else { player.sendMessage(new TextComponent(ChatFormatting.RED + "Error: no XP to deposit"), player.getUUID()); }
  19. https://pastebin.com/8E55a03n This is the error: java.lang.IllegalArgumentException: Duplicate id value for 1! at net.minecraft.network.syncher.SynchedEntityData.m_135372_(SynchedEntityData.java:117) ~[client-1.18.2-20220404.173914-srg.jar%2356!/:?] at net.minecraft.world.entity.player.Player.m_8097_(Player.java:199) ~[client-1.18.2-20220404.173914-srg.jar%2356!/:?] at net.minecraft.world.entity.Entity.<init>(Entit I removed the only entity i had completly and now it works, i dont know why
  20. when i build/export my mod, put it in the mods folder and run minecraft, when i create a new world, or try to enter a existing one it says invalid player data, thats all it doesnt happen when i run my mod in intellij/run my mod in runtime
  21. so, i create a new mod, add the jsoup library, build/export it, and use it in my main mod to make forge recognize it (also add the mandatory in mods.toml), but how do i use the new mod that has the jsoup library in my main mod, (inside intellij)
  22. Doesnt it does the same thing?, add the jsoup to the build.gradle but in another recently created mod, why thats a difference? What do you mean, i didnt runtime minecraft while adding the library Cause all the problems this could cause me, i prefer not to use it :b
  23. Im trying to test jsoup library in minecraft, so, i looked in the page and im suposed to put this in the "dependencies {}" implementation 'org.jsoup:jsoup:1.15.3' i did that, built it and it gave me a build successfull, when i try to use the library in game, for example grabbing a song lyrics, it gives me a NoClassDefFoundError BTW: im grabbing the lyrics when i press a button inside my screen BTW x2: i added the library in a different project (maven), used the same method for grabbing a song lyric, and it works, so maybe im doing something wrong in build.gradle because is not problem of pressing the button or the screen Crash report: https://pastebin.com/GLHVb0up build.gradle important stuff (if you need something else from the file tell me): buildscript { repositories { maven { url = 'https://maven.minecraftforge.net' } maven { url = 'https://maven.parchmentmc.org' } mavenCentral() } dependencies { classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true classpath 'org.parchmentmc:librarian:1.+' } } repositories { } dependencies { minecraft 'net.minecraftforge:forge:1.18.2-40.1.0' implementation 'org.jsoup:jsoup:1.15.3' } My screen class: public class LyricsGathererScreen extends AbstractContainerScreen<LyricsGathererMenu> { public static final ResourceLocation TEXTURE = new ResourceLocation(Constants.MOD_ID, "textures/gui/lyricsgatherer_gui.png"); private Button button; private EditBox box; private Player player; public LyricsGathererScreen(LyricsGathererMenu menu, Inventory inv, Component component) { super(menu, inv, component); this.player = inv.player; inventoryLabelY = -1000; } @Override protected void init() { super.init(); int x = (width - imageWidth) / 2; int y = (height - imageHeight) / 2; this.minecraft.keyboardHandler.setSendRepeatsToGui(true); this.box = new EditBox(font, x + 55, y + 14, 76, 15, TextComponent.EMPTY); this.box.setCanLoseFocus(false); this.box.setTextColor(-1); this.box.setTextColorUneditable(-1); this.box.setBordered(true); this.box.setMaxLength(50); this.box.setValue(""); this.addWidget(this.box); this.setInitialFocus(this.box); this.button = addRenderableWidget(new Button(x + 55,y + 52,70,20,new TextComponent("Get lyrics"), button -> { try { if(this.box.getValue().length() < 1) return; String test = TotisLyricsGathererUtils.getSongLyrics(this.box.getValue().trim()); player.sendMessage(new TextComponent(test), player.getUUID()); } catch(Exception e) {} })); } @Override public void removed() { super.removed(); this.minecraft.keyboardHandler.setSendRepeatsToGui(false); } public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) { if (pKeyCode == 256) { this.minecraft.player.closeContainer(); } return !this.box.keyPressed(pKeyCode, pScanCode, pModifiers) && !this.box.canConsumeInput() ? super.keyPressed(pKeyCode, pScanCode, pModifiers) : true; } @Override protected void renderLabels(PoseStack stack, int mouseX, int mouseY) { super.renderLabels(stack, mouseX, mouseY); } @Override protected void renderBg(PoseStack stack, float partialTick, int mouseX, int mouseY) { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.setShaderTexture(0, TEXTURE); int x = (width - imageWidth) / 2; int y = (height - imageHeight) / 2; this.blit(stack, x, y, 0, 0, imageWidth, imageHeight); // height - 95 } @Override public void render(PoseStack pPoseStack, int mouseX, int mouseY, float delta) { renderBackground(pPoseStack); super.render(pPoseStack, mouseX, mouseY, delta); this.renderFg(pPoseStack, mouseX, mouseY, delta); renderTooltip(pPoseStack, mouseX, mouseY); } public void renderFg(PoseStack pPoseStack, int pMouseX, int pMouseY, float pPartialTick) { this.box.render(pPoseStack, pMouseX, pMouseY, pPartialTick); } } The helper for find the lyrics (as i said, i used this exact method too for another project and it worked): public class TotisLyricsGathererUtils { private static final String songLyricsURL = "https://www.google.com"; private static final String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36"; public static String getSongLyrics(String all) throws IOException { Document doc = Jsoup.connect(songLyricsURL + "/search?q=" + all.replace(" ", "+").toLowerCase() + "+lyrics").userAgent(userAgent).get(); String title = doc.title(); title = String.join(" ",title).replace("- Buscar con Google", ""); Element p = doc.select("div.sATSHe").get(0); String lyrics = p.text(); lyrics = String.join(" ", lyrics).replace("Letras", ""); String[] parts = lyrics.split("Se produjo un error"); String realLyrics = parts[0]; return realLyrics.trim(); } }
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.