Explore all Minecraft open source software, libraries, packages, source code, cloud functions and APIs.

Popular New Releases in Minecraft

byte-buddy

Byte Buddy 1.12.8

mumble

1.3.4

docker-minecraft-server

2022.6.0

baritone

v1.8.1

HMCL

v3.5.2.218

Popular Libraries in Minecraft

Craft

by fogleman doticoncdoticon

star image 8642 doticonMIT

A simple Minecraft clone written in C using modern OpenGL (shaders).

Paper

by PaperMC doticonjavadoticon

star image 5799 doticonNOASSERTION

High performance Spigot fork that aims to fix gameplay and mechanics inconsistencies

MinecraftForge

by MinecraftForge doticonjavadoticon

star image 5407 doticonNOASSERTION

Modifications to the Minecraft base files to assist in compatibility between mods.

byte-buddy

by raphw doticonjavadoticon

star image 4838 doticonApache-2.0

Runtime code generation for the Java virtual machine.

Minecraft

by fogleman doticonpythondoticon

star image 4622 doticonMIT

Simple Minecraft-inspired program using Python and Pyglet

mumble

by mumble-voip doticonc++doticon

star image 4481 doticonNOASSERTION

Mumble is an open-source, low-latency, high quality voice chat software.

docker-minecraft-server

by itzg doticonshelldoticon

star image 4378 doticonApache-2.0

Docker image that provides a Minecraft Server that will automatically download selected version at startup

cuberite

by cuberite doticonc++doticon

star image 4060 doticonNOASSERTION

A lightweight, fast and extensible game server for Minecraft

baritone

by cabaletta doticonjavadoticon

star image 4053 doticonNOASSERTION

google maps for block game

Trending New libraries in Minecraft

sodium-fabric

by CaffeineMC doticonjavadoticon

star image 3168 doticonLGPL-3.0

A Fabric mod designed to improve frame rates and reduce micro-stutter

PojavLauncher

by PojavLauncherTeam doticonjavadoticon

star image 2537 doticonGPL-3.0

A Minecraft: Java Edition Launcher for Android and iOS based on Boardwalk. This repository contains source code for Android platform.

Iris

by IrisShaders doticonjavadoticon

star image 2036 doticonLGPL-3.0

(WIP) A modern shaders mod for Minecraft intended to be compatible with existing OptiFine shader packs

minecraft-weekend

by jdah doticoncdoticon

star image 1967 doticonMIT

Minecraft, but I made it in 48 hours.

minecraft-ondemand

by doctorray117 doticontypescriptdoticon

star image 1234 doticonApache-2.0

Templates to deploy a serverless Minecraft Server on demand in AWS

sm64ex

by sm64pc doticoncdoticon

star image 1078 doticon

Fork of https://github.com/sm64-port/sm64-port with additional features.

FarPlaneTwo

by PorkStudios doticonjavadoticon

star image 1065 doticonNOASSERTION

Level-of-Detail renderer in Minecraft. Allows for render distances of millions of blocks. (Cubic Chunks-compatible) (WIP)

webmc

by michaljaz doticonjavascriptdoticon

star image 941 doticonMIT

Minecraft client written in Javascript

MCinaBox

by AOF-Dev doticonjavadoticon

star image 923 doticonNOASSERTION

MCinaBox - A Minecraft: Java Edition Launcher for Android. An Encapsulation of [CosineMath's BoatApp](https://github.com/AOF-Dev/BoatApp).

Top Authors in Minecraft

1

PrismarineJS

40 Libraries

star icon5314

2

MinecraftModDevelopmentMods

33 Libraries

star icon224

3

thebigsmileXD

25 Libraries

star icon453

4

voxel

25 Libraries

star icon135

5

wode490390

23 Libraries

star icon158

6

Draylar

23 Libraries

star icon167

7

blay09

22 Libraries

star icon315

8

games647

22 Libraries

star icon1081

9

maruohon

22 Libraries

star icon733

10

martinohanlon

21 Libraries

star icon338

1

40 Libraries

star icon5314

3

25 Libraries

star icon453

4

25 Libraries

star icon135

5

23 Libraries

star icon158

6

23 Libraries

star icon167

7

22 Libraries

star icon315

8

22 Libraries

star icon1081

9

22 Libraries

star icon733

10

21 Libraries

star icon338

Trending Kits in Minecraft

No Trending Kits are available at this moment for Minecraft

Trending Discussions on Minecraft

First-person controller y-pos logic in Ursina

How to configure slf4j (for JDA) to work with log4j (for Minecraft Paper)?

Error [ERR_REQUIRE_ESM]: require() of ES Module not supported

Log4j vulnerability - Is Log4j 1.2.17 vulnerable (was unable to find any JNDI code in source)?

Minecraft Plugin ClassNotFound Error from External JAR

Infer dependencies in Gradle subproject from its parent project

Minecraft Forge 1.7.10 Custom Entity Not Spawning On The Client?

Generate custom ores in custom dimension

Special condition - remove all the version numbers from the mods to search for the new version

How to filter an array on click in react?

QUESTION

First-person controller y-pos logic in Ursina

Asked 2022-Mar-15 at 07:04

I have a clone of Minecraft and I want to see if the player falls off the island it would quit the game. I thought that if I wrote.

1if player.position == Vec3(x, -80, z):
2     quit()
3

it would quit the game but that didn't work so I don't know what to do.

Heres the Minecraft clone code.

1if player.position == Vec3(x, -80, z):
2     quit()
3from ursina import *
4from ursina.prefabs.first_person_controller import FirstPersonController
5app = Ursina()
6
7grass_color = color.rgb(1, 235, 113)
8stone_color = color.rgb(138,141,143)
9dirt_color = color.rgb(200, 157, 124)
10
11block_pick = 1
12
13def update():
14    if held_keys['escape']:
15        quit()
16
17    global block_pick
18
19    if held_keys['1']: block_pick = 1
20    if held_keys['2']: block_pick = 2
21    if held_keys['3']: block_pick = 3
22
23class Voxel(Button):
24    def __init__(self, position = (0,0,0), color = color.white):
25        super().__init__(
26            parent = scene,
27            position = position,
28            model = 'cube',
29            origin_y = 0.5,
30            texture = 'white_cube',
31            color = color,
32            highlight_color = color,
33                    )
34
35    def input(self,key):
36        if self.hovered:
37            if key == 'right mouse down':
38                if block_pick == 1:voxel = Voxel(position = self.position + mouse.normal, color = grass_color)
39                if block_pick == 2:voxel = Voxel(position = self.position + mouse.normal, color = stone_color)
40                if block_pick == 3:voxel = Voxel(position = self.position + mouse.normal, color = dirt_color)
41            if key == 'left mouse down':
42                destroy(self)
43            
44for z in range(20):
45    for x in range(20):
46        voxel = Voxel(position=(x,0,z), color = grass_color)
47
48for y in range(3):
49    for x in range(20):
50        for z in range(20):
51            voxel = Voxel(position=(x,y + -3,z), color = dirt_color)
52
53player = FirstPersonController()
54app.run()
55

ANSWER

Answered 2022-Mar-15 at 07:04

You checked only for a single value of the player's y position which won't work - after all, you'd be falling down quickly. You could check whether the player's height is below a certain cutoff:

1if player.position == Vec3(x, -80, z):
2     quit()
3from ursina import *
4from ursina.prefabs.first_person_controller import FirstPersonController
5app = Ursina()
6
7grass_color = color.rgb(1, 235, 113)
8stone_color = color.rgb(138,141,143)
9dirt_color = color.rgb(200, 157, 124)
10
11block_pick = 1
12
13def update():
14    if held_keys['escape']:
15        quit()
16
17    global block_pick
18
19    if held_keys['1']: block_pick = 1
20    if held_keys['2']: block_pick = 2
21    if held_keys['3']: block_pick = 3
22
23class Voxel(Button):
24    def __init__(self, position = (0,0,0), color = color.white):
25        super().__init__(
26            parent = scene,
27            position = position,
28            model = 'cube',
29            origin_y = 0.5,
30            texture = 'white_cube',
31            color = color,
32            highlight_color = color,
33                    )
34
35    def input(self,key):
36        if self.hovered:
37            if key == 'right mouse down':
38                if block_pick == 1:voxel = Voxel(position = self.position + mouse.normal, color = grass_color)
39                if block_pick == 2:voxel = Voxel(position = self.position + mouse.normal, color = stone_color)
40                if block_pick == 3:voxel = Voxel(position = self.position + mouse.normal, color = dirt_color)
41            if key == 'left mouse down':
42                destroy(self)
43            
44for z in range(20):
45    for x in range(20):
46        voxel = Voxel(position=(x,0,z), color = grass_color)
47
48for y in range(3):
49    for x in range(20):
50        for z in range(20):
51            voxel = Voxel(position=(x,y + -3,z), color = dirt_color)
52
53player = FirstPersonController()
54app.run()
55def update():
56    if player.y < -80:
57        print('You fell to death!')
58        app.quit()
59

Source https://stackoverflow.com/questions/71475015

QUESTION

How to configure slf4j (for JDA) to work with log4j (for Minecraft Paper)?

Asked 2022-Mar-11 at 16:05

I'm making plugin for Minecraft - 'Paper' exactly. And it uses JDA for Discord bot function.

The problem is, Minecraft(Paper) uses log4j as its logging library. JDA uses slf4j as its logging library. I want JDA to use log4j so that error message of JDA would be shown in console as plugin's error message. (See EDIT2 for actual logs)

No System.out.println() because Minecraft(Paper) will complain about using it.
No Logback because I think it is another logging library, thus it cannot work well with Minecraft(Paper)'s logging system (no JDA logs in Minecraft log etc.). I don't want to implement another logging library when there is already logging system provided by Minecraft, which is log4j.

JDA wiki only describes about Logback so I have to find my own way for making JDA with Minecraft's logging system, but it was no success.

For example:

1// Something went wrong in JDA and shows stacktrace
2[05:20:26] [Server thread/ERROR]: [MyPlugin] [JDA] 'JDA Error Message'
3(prints stacktrace of the error)
4
5// Show debug message of WebSocketClient (Since it is debug message, this can be turned off)
6[05:20:26] [Server thread/DEBUG]: [MyPlugin] [JDA] WebSocketClient - Connected to WebSocket
7
8// Show JDA message when JDA bot is loaded
9[05:20:26] [Server thread/DEBUG]: [MyPlugin] [JDA] JDA - Finished Loading!
10

These all messages should be part of the Minecraft(Paper)'s logging system, not mimicing it. This means, it should use JavaPlugin#getLogger().info() or something like this in somewhere of the code.

How to make JDA to be like this?
Just implementing log4j-slf4j18-impl doesn't work. I think I should do something about JDA's logging stuff.


EDIT: Here is current build.gradle file content. LINK

Currently, my plugin implements log4j-slf4j-impl for JDA.

ANSWER

Answered 2022-Feb-27 at 07:57

Log4j 2 SLF4J Binding exists for that purpose. It is an SLF4J logger implementation (like slf4j-simple) that logs everything to log4j. In other words, everything logged with SLF4J will be forwarded to log4j.

In order to use it, just add the following to your pom.xml (see this):

1// Something went wrong in JDA and shows stacktrace
2[05:20:26] [Server thread/ERROR]: [MyPlugin] [JDA] 'JDA Error Message'
3(prints stacktrace of the error)
4
5// Show debug message of WebSocketClient (Since it is debug message, this can be turned off)
6[05:20:26] [Server thread/DEBUG]: [MyPlugin] [JDA] WebSocketClient - Connected to WebSocket
7
8// Show JDA message when JDA bot is loaded
9[05:20:26] [Server thread/DEBUG]: [MyPlugin] [JDA] JDA - Finished Loading!
10<dependency>
11  <groupId>org.apache.logging.log4j</groupId>
12  <artifactId>log4j-slf4j18-impl</artifactId>
13  <version>2.17.2</version>
14</dependency>
15

If you use Gradle, it would look like this:

1// Something went wrong in JDA and shows stacktrace
2[05:20:26] [Server thread/ERROR]: [MyPlugin] [JDA] 'JDA Error Message'
3(prints stacktrace of the error)
4
5// Show debug message of WebSocketClient (Since it is debug message, this can be turned off)
6[05:20:26] [Server thread/DEBUG]: [MyPlugin] [JDA] WebSocketClient - Connected to WebSocket
7
8// Show JDA message when JDA bot is loaded
9[05:20:26] [Server thread/DEBUG]: [MyPlugin] [JDA] JDA - Finished Loading!
10<dependency>
11  <groupId>org.apache.logging.log4j</groupId>
12  <artifactId>log4j-slf4j18-impl</artifactId>
13  <version>2.17.2</version>
14</dependency>
15compile 'org.apache.logging.log4j:log4j-slf4j18-impl:2.17.2'
16

Adding this dependency includes and automatically registers the logger.

Source https://stackoverflow.com/questions/71280094

QUESTION

Error [ERR_REQUIRE_ESM]: require() of ES Module not supported

Asked 2022-Feb-03 at 22:08

I'm trying to make a Discord bot that just says if someone is online on the game.

However I keep getting this message:

[ERR_REQUIRE_ESM]: require() of ES Module from not supported. Instead change the require of index.js in... to a dynamic import() which is available in all CommonJS modules.

This is my code:

1    module.exports = {
2        name: 'username',
3        description: "this is the username command",
4        async execute(message, args) {
5
6            const fetch = require('node-fetch');
7
8            if (args.length !== 1) {
9                return message.channel.send("invalid username wtf")
10            }
11
12            const ign = args[0]
13
14            if (ign.length > 16 || ign.length < 3) {
15                return message.channel.send("invalid username wtf")
16            }
17
18            const uuid = await fetch(`https://api.mojang.com/users/profiles/minecraft/${ign}`).then(data => data.json()).then(data => data.id).catch(err => message.channel.send("error wtf"));
19            const onlineInfo = await fetch(`https://api.hypixel.net/status?key=${john}&uuid=${uuid}`).then(data => data.json());
20
21            if (uuid.length !== 32) {
22                return;
23            }
24
25            if (onlineinfo.success) {
26                if (onlineinfo.session.online) {
27                    message.channel.send("they are online")
28                }
29                else {
30                    message.channel.send("they are offline")
31                }
32            }
33            else {
34                message.channel.send("hypixel api bad wtf")
35            }
36        }
37    }
38

This is my package.json file:

1    module.exports = {
2        name: 'username',
3        description: "this is the username command",
4        async execute(message, args) {
5
6            const fetch = require('node-fetch');
7
8            if (args.length !== 1) {
9                return message.channel.send("invalid username wtf")
10            }
11
12            const ign = args[0]
13
14            if (ign.length > 16 || ign.length < 3) {
15                return message.channel.send("invalid username wtf")
16            }
17
18            const uuid = await fetch(`https://api.mojang.com/users/profiles/minecraft/${ign}`).then(data => data.json()).then(data => data.id).catch(err => message.channel.send("error wtf"));
19            const onlineInfo = await fetch(`https://api.hypixel.net/status?key=${john}&uuid=${uuid}`).then(data => data.json());
20
21            if (uuid.length !== 32) {
22                return;
23            }
24
25            if (onlineinfo.success) {
26                if (onlineinfo.session.online) {
27                    message.channel.send("they are online")
28                }
29                else {
30                    message.channel.send("they are offline")
31                }
32            }
33            else {
34                message.channel.send("hypixel api bad wtf")
35            }
36        }
37    }
38{
39    "name": "discordbot",
40    "version": "1.0.0",
41    "main": "main.js",
42    "scripts": {
43        "test": "echo \"Error: no test specified\" && exit 1",
44        "start": "node main.js"
45    },
46    "author": "",
47    "license": "ISC",
48    "description": "",
49    "dependencies": {
50        "discord.js": "^13.0.1",
51        "node-fetch": "^3.0.0"
52    }
53}
54

ANSWER

Answered 2021-Sep-07 at 06:38

node-fetch v3 recently stopped support for the require way of importing it in favor of ES Modules. You'll need to use ESM imports now, like:

1    module.exports = {
2        name: 'username',
3        description: "this is the username command",
4        async execute(message, args) {
5
6            const fetch = require('node-fetch');
7
8            if (args.length !== 1) {
9                return message.channel.send("invalid username wtf")
10            }
11
12            const ign = args[0]
13
14            if (ign.length > 16 || ign.length < 3) {
15                return message.channel.send("invalid username wtf")
16            }
17
18            const uuid = await fetch(`https://api.mojang.com/users/profiles/minecraft/${ign}`).then(data => data.json()).then(data => data.id).catch(err => message.channel.send("error wtf"));
19            const onlineInfo = await fetch(`https://api.hypixel.net/status?key=${john}&uuid=${uuid}`).then(data => data.json());
20
21            if (uuid.length !== 32) {
22                return;
23            }
24
25            if (onlineinfo.success) {
26                if (onlineinfo.session.online) {
27                    message.channel.send("they are online")
28                }
29                else {
30                    message.channel.send("they are offline")
31                }
32            }
33            else {
34                message.channel.send("hypixel api bad wtf")
35            }
36        }
37    }
38{
39    "name": "discordbot",
40    "version": "1.0.0",
41    "main": "main.js",
42    "scripts": {
43        "test": "echo \"Error: no test specified\" && exit 1",
44        "start": "node main.js"
45    },
46    "author": "",
47    "license": "ISC",
48    "description": "",
49    "dependencies": {
50        "discord.js": "^13.0.1",
51        "node-fetch": "^3.0.0"
52    }
53}
54import fetch from "node-fetch";
55

at the top of your file.

Source https://stackoverflow.com/questions/69081410

QUESTION

Log4j vulnerability - Is Log4j 1.2.17 vulnerable (was unable to find any JNDI code in source)?

Asked 2022-Feb-01 at 15:47

With regard to the Log4j JNDI remote code execution vulnerability that has been identified CVE-2021-44228 - (also see references) - I wondered if Log4j-v1.2 is also impacted, but the closest I got from source code review is the JMS-Appender.

The question is, while the posts on the Internet indicate that Log4j 1.2 is also vulnerable, I am not able to find the relevant source code for it.

Am I missing something that others have identified?

Log4j 1.2 appears to have a vulnerability in the socket-server class, but my understanding is that it needs to be enabled in the first place for it to be applicable and hence is not a passive threat unlike the JNDI-lookup vulnerability which the one identified appears to be.

Is my understanding - that Log4j v1.2 - is not vulnerable to the jndi-remote-code execution bug correct?

References

This blog post from Cloudflare also indicates the same point as from AKX....that it was introduced from Log4j 2!

Update #1 - A fork of the (now-retired) apache-log4j-1.2.x with patch fixes for few vulnerabilities identified in the older library is now available (from the original log4j author). The site is https://reload4j.qos.ch/. As of 21-Jan-2022 version 1.2.18.2 has been released. Vulnerabilities addressed to date include those pertaining to JMSAppender, SocketServer and Chainsaw vulnerabilities. Note that I am simply relaying this information. Have not verified the fixes from my end. Please refer the link for additional details.

ANSWER

Answered 2022-Jan-01 at 18:43

The JNDI feature was added into Log4j 2.0-beta9.

Log4j 1.x thus does not have the vulnerable code.

Source https://stackoverflow.com/questions/70310980

QUESTION

Minecraft Plugin ClassNotFound Error from External JAR

Asked 2021-Dec-31 at 16:46

I am trying to build a plugin for a Minecraft Spigot server that ultimately I would like to be able to communicate over serial with things connected to my PC (server is running locally on the PC as well).

I have been able to build and run the plugin and manipulate player/blocks in the game so I know the build process for my base plugin is working. My trouble started when I began trying to include an extra dependency: jSerialComm

I added the dependency entry in my pom.xml file:

1<dependency>
2    <groupId>com.fazecast</groupId>
3    <artifactId>jSerialComm</artifactId>
4    <version>[2.0.0,3.0.0)</version>
5    <scope>provided</scope>
6</dependency>
7

I added some basic code to import classes from jSerialComm and do something basic with them inside of a command in my plugin:

1<dependency>
2    <groupId>com.fazecast</groupId>
3    <artifactId>jSerialComm</artifactId>
4    <version>[2.0.0,3.0.0)</version>
5    <scope>provided</scope>
6</dependency>
7import com.fazecast.jSerialComm.SerialPort;
8
9public class CommandCheck implements CommandExecutor {
10
11    @Override
12    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
13        if (sender instanceof Player){
14            System.out.println(SerialPort.getCommPorts());
15        }
16        return false;
17    }
18}
19

This builds fine, I'm using InteliJ and it does recognize the SerialPort class (no red underlines).

But when this command runs in the game I get a Class Not Found error:

1<dependency>
2    <groupId>com.fazecast</groupId>
3    <artifactId>jSerialComm</artifactId>
4    <version>[2.0.0,3.0.0)</version>
5    <scope>provided</scope>
6</dependency>
7import com.fazecast.jSerialComm.SerialPort;
8
9public class CommandCheck implements CommandExecutor {
10
11    @Override
12    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
13        if (sender instanceof Player){
14            System.out.println(SerialPort.getCommPorts());
15        }
16        return false;
17    }
18}
19org.bukkit.command.CommandException: Unhandled exception executing command 'check' in plugin MyFirstPlugin v1.0-SNAPSHOT
20        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
21        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
22        at org.bukkit.craftbukkit.v1_18_R1.CraftServer.dispatchCommand(CraftServer.java:821) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
23        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1939) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
24        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1778) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
25        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1759) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
26        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:46) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
27        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
28        at net.minecraft.network.protocol.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:30) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
29        at net.minecraft.server.TickTask.run(SourceFile:18) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
30        at net.minecraft.util.thread.IAsyncTaskHandler.c(SourceFile:151) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
31        at net.minecraft.util.thread.IAsyncTaskHandlerReentrant.c(SourceFile:23) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
32        at net.minecraft.server.MinecraftServer.b(MinecraftServer.java:1158) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
33        at net.minecraft.server.MinecraftServer.c(MinecraftServer.java:1) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
34        at net.minecraft.util.thread.IAsyncTaskHandler.y(SourceFile:125) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
35        at net.minecraft.server.MinecraftServer.bf(MinecraftServer.java:1137) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
36        at net.minecraft.server.MinecraftServer.y(MinecraftServer.java:1130) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
37        at net.minecraft.util.thread.IAsyncTaskHandler.c(SourceFile:134) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
38        at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1114) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
39        at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:1038) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
40        at net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:304) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
41        at java.lang.Thread.run(Thread.java:833) [?:?]
42Caused by: java.lang.NoClassDefFoundError: com/fazecast/jSerialComm/SerialPort
43        at com.foamyguy.myfirstplugin.CommandCheck.onCommand(CommandCheck.java:21) ~[?:?]
44        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
45        ... 21 more
46Caused by: java.lang.ClassNotFoundException: com.fazecast.jSerialComm.SerialPort
47        at org.bukkit.plugin.java.PluginClassLoader.loadClass0(PluginClassLoader.java:147) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
48        at org.bukkit.plugin.java.PluginClassLoader.loadClass(PluginClassLoader.java:99) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
49        at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?]
50        at com.foamyguy.myfirstplugin.CommandCheck.onCommand(CommandCheck.java:21) ~[?:?]
51        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
52        ... 21 more
53

I have unzipped and looked inside of the built jar file and the jSerialComm jar file is successfully being included within my plugin jar:

unzipped jar contents

What do I need to do in order to successfully use an external JAR file (jSerialComm specifically) from inside of a Minecraft plugin? Or alternatively, is there some built-in way that I can connect and communicate over serial ports without needing an external JAR and therefore not needing anything "special" in order to work?

ANSWER

Answered 2021-Dec-31 at 16:46

Even if the JAR is present in your plugin, the classes of the JAR are not loaded in the classpath and Spigot cannot access the classes.

You can use a plugin, such as the maven-shade-plugin, which copies all classes from your API-JAR to your Plugin-JAR.

First, set the scope from provided to compile.

1<dependency>
2    <groupId>com.fazecast</groupId>
3    <artifactId>jSerialComm</artifactId>
4    <version>[2.0.0,3.0.0)</version>
5    <scope>provided</scope>
6</dependency>
7import com.fazecast.jSerialComm.SerialPort;
8
9public class CommandCheck implements CommandExecutor {
10
11    @Override
12    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
13        if (sender instanceof Player){
14            System.out.println(SerialPort.getCommPorts());
15        }
16        return false;
17    }
18}
19org.bukkit.command.CommandException: Unhandled exception executing command 'check' in plugin MyFirstPlugin v1.0-SNAPSHOT
20        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
21        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
22        at org.bukkit.craftbukkit.v1_18_R1.CraftServer.dispatchCommand(CraftServer.java:821) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
23        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1939) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
24        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1778) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
25        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1759) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
26        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:46) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
27        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
28        at net.minecraft.network.protocol.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:30) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
29        at net.minecraft.server.TickTask.run(SourceFile:18) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
30        at net.minecraft.util.thread.IAsyncTaskHandler.c(SourceFile:151) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
31        at net.minecraft.util.thread.IAsyncTaskHandlerReentrant.c(SourceFile:23) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
32        at net.minecraft.server.MinecraftServer.b(MinecraftServer.java:1158) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
33        at net.minecraft.server.MinecraftServer.c(MinecraftServer.java:1) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
34        at net.minecraft.util.thread.IAsyncTaskHandler.y(SourceFile:125) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
35        at net.minecraft.server.MinecraftServer.bf(MinecraftServer.java:1137) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
36        at net.minecraft.server.MinecraftServer.y(MinecraftServer.java:1130) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
37        at net.minecraft.util.thread.IAsyncTaskHandler.c(SourceFile:134) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
38        at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1114) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
39        at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:1038) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
40        at net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:304) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
41        at java.lang.Thread.run(Thread.java:833) [?:?]
42Caused by: java.lang.NoClassDefFoundError: com/fazecast/jSerialComm/SerialPort
43        at com.foamyguy.myfirstplugin.CommandCheck.onCommand(CommandCheck.java:21) ~[?:?]
44        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
45        ... 21 more
46Caused by: java.lang.ClassNotFoundException: com.fazecast.jSerialComm.SerialPort
47        at org.bukkit.plugin.java.PluginClassLoader.loadClass0(PluginClassLoader.java:147) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
48        at org.bukkit.plugin.java.PluginClassLoader.loadClass(PluginClassLoader.java:99) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
49        at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?]
50        at com.foamyguy.myfirstplugin.CommandCheck.onCommand(CommandCheck.java:21) ~[?:?]
51        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
52        ... 21 more
53<dependency>
54    <groupId>com.fazecast</groupId>
55    <artifactId>jSerialComm</artifactId>
56    <version>[2.0.0,3.0.0)</version>
57    <scope>compile</scope> <!-- -->
58</dependency>
59

Then add the maven-shade-plugin under build > plugins inside your pom.xml

1<dependency>
2    <groupId>com.fazecast</groupId>
3    <artifactId>jSerialComm</artifactId>
4    <version>[2.0.0,3.0.0)</version>
5    <scope>provided</scope>
6</dependency>
7import com.fazecast.jSerialComm.SerialPort;
8
9public class CommandCheck implements CommandExecutor {
10
11    @Override
12    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
13        if (sender instanceof Player){
14            System.out.println(SerialPort.getCommPorts());
15        }
16        return false;
17    }
18}
19org.bukkit.command.CommandException: Unhandled exception executing command 'check' in plugin MyFirstPlugin v1.0-SNAPSHOT
20        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
21        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
22        at org.bukkit.craftbukkit.v1_18_R1.CraftServer.dispatchCommand(CraftServer.java:821) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
23        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1939) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
24        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1778) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
25        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1759) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
26        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:46) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
27        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
28        at net.minecraft.network.protocol.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:30) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
29        at net.minecraft.server.TickTask.run(SourceFile:18) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
30        at net.minecraft.util.thread.IAsyncTaskHandler.c(SourceFile:151) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
31        at net.minecraft.util.thread.IAsyncTaskHandlerReentrant.c(SourceFile:23) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
32        at net.minecraft.server.MinecraftServer.b(MinecraftServer.java:1158) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
33        at net.minecraft.server.MinecraftServer.c(MinecraftServer.java:1) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
34        at net.minecraft.util.thread.IAsyncTaskHandler.y(SourceFile:125) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
35        at net.minecraft.server.MinecraftServer.bf(MinecraftServer.java:1137) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
36        at net.minecraft.server.MinecraftServer.y(MinecraftServer.java:1130) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
37        at net.minecraft.util.thread.IAsyncTaskHandler.c(SourceFile:134) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
38        at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1114) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
39        at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:1038) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
40        at net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:304) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
41        at java.lang.Thread.run(Thread.java:833) [?:?]
42Caused by: java.lang.NoClassDefFoundError: com/fazecast/jSerialComm/SerialPort
43        at com.foamyguy.myfirstplugin.CommandCheck.onCommand(CommandCheck.java:21) ~[?:?]
44        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
45        ... 21 more
46Caused by: java.lang.ClassNotFoundException: com.fazecast.jSerialComm.SerialPort
47        at org.bukkit.plugin.java.PluginClassLoader.loadClass0(PluginClassLoader.java:147) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
48        at org.bukkit.plugin.java.PluginClassLoader.loadClass(PluginClassLoader.java:99) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
49        at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?]
50        at com.foamyguy.myfirstplugin.CommandCheck.onCommand(CommandCheck.java:21) ~[?:?]
51        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
52        ... 21 more
53<dependency>
54    <groupId>com.fazecast</groupId>
55    <artifactId>jSerialComm</artifactId>
56    <version>[2.0.0,3.0.0)</version>
57    <scope>compile</scope> <!-- -->
58</dependency>
59<build>
60    <!-- ... -->
61    <plugins>
62      <!-- ... -->
63      <plugin>
64        <groupId>org.apache.maven.plugins</groupId>
65        <artifactId>maven-shade-plugin</artifactId>
66        <version>3.1.0</version>
67        <executions>
68          <execution>
69            <phase>package</phase>
70            <goals>
71              <goal>shade</goal>
72            </goals>
73          </execution>
74        </executions>
75      </plugin>
76      <!-- ... -->
77    </plugins>
78    <!-- ... -->
79  </build>
80

If you now build the jar (using e. g. man clean package), there should be a "fat-" jar file in the target/ folder that contains the classes of the API as well as your classes.

Contents of your plugin before:

1<dependency>
2    <groupId>com.fazecast</groupId>
3    <artifactId>jSerialComm</artifactId>
4    <version>[2.0.0,3.0.0)</version>
5    <scope>provided</scope>
6</dependency>
7import com.fazecast.jSerialComm.SerialPort;
8
9public class CommandCheck implements CommandExecutor {
10
11    @Override
12    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
13        if (sender instanceof Player){
14            System.out.println(SerialPort.getCommPorts());
15        }
16        return false;
17    }
18}
19org.bukkit.command.CommandException: Unhandled exception executing command 'check' in plugin MyFirstPlugin v1.0-SNAPSHOT
20        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
21        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
22        at org.bukkit.craftbukkit.v1_18_R1.CraftServer.dispatchCommand(CraftServer.java:821) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
23        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1939) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
24        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1778) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
25        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1759) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
26        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:46) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
27        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
28        at net.minecraft.network.protocol.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:30) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
29        at net.minecraft.server.TickTask.run(SourceFile:18) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
30        at net.minecraft.util.thread.IAsyncTaskHandler.c(SourceFile:151) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
31        at net.minecraft.util.thread.IAsyncTaskHandlerReentrant.c(SourceFile:23) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
32        at net.minecraft.server.MinecraftServer.b(MinecraftServer.java:1158) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
33        at net.minecraft.server.MinecraftServer.c(MinecraftServer.java:1) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
34        at net.minecraft.util.thread.IAsyncTaskHandler.y(SourceFile:125) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
35        at net.minecraft.server.MinecraftServer.bf(MinecraftServer.java:1137) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
36        at net.minecraft.server.MinecraftServer.y(MinecraftServer.java:1130) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
37        at net.minecraft.util.thread.IAsyncTaskHandler.c(SourceFile:134) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
38        at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1114) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
39        at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:1038) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
40        at net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:304) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
41        at java.lang.Thread.run(Thread.java:833) [?:?]
42Caused by: java.lang.NoClassDefFoundError: com/fazecast/jSerialComm/SerialPort
43        at com.foamyguy.myfirstplugin.CommandCheck.onCommand(CommandCheck.java:21) ~[?:?]
44        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
45        ... 21 more
46Caused by: java.lang.ClassNotFoundException: com.fazecast.jSerialComm.SerialPort
47        at org.bukkit.plugin.java.PluginClassLoader.loadClass0(PluginClassLoader.java:147) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
48        at org.bukkit.plugin.java.PluginClassLoader.loadClass(PluginClassLoader.java:99) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
49        at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?]
50        at com.foamyguy.myfirstplugin.CommandCheck.onCommand(CommandCheck.java:21) ~[?:?]
51        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
52        ... 21 more
53<dependency>
54    <groupId>com.fazecast</groupId>
55    <artifactId>jSerialComm</artifactId>
56    <version>[2.0.0,3.0.0)</version>
57    <scope>compile</scope> <!-- -->
58</dependency>
59<build>
60    <!-- ... -->
61    <plugins>
62      <!-- ... -->
63      <plugin>
64        <groupId>org.apache.maven.plugins</groupId>
65        <artifactId>maven-shade-plugin</artifactId>
66        <version>3.1.0</version>
67        <executions>
68          <execution>
69            <phase>package</phase>
70            <goals>
71              <goal>shade</goal>
72            </goals>
73          </execution>
74        </executions>
75      </plugin>
76      <!-- ... -->
77    </plugins>
78    <!-- ... -->
79  </build>
80├ com
81  ├ foamguy
82    └ myfirstplugin
83      └ ...
84├ plugin.yml
85└ jSerialComm-xxx.jar
86

Contents of your plugin after:

1<dependency>
2    <groupId>com.fazecast</groupId>
3    <artifactId>jSerialComm</artifactId>
4    <version>[2.0.0,3.0.0)</version>
5    <scope>provided</scope>
6</dependency>
7import com.fazecast.jSerialComm.SerialPort;
8
9public class CommandCheck implements CommandExecutor {
10
11    @Override
12    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
13        if (sender instanceof Player){
14            System.out.println(SerialPort.getCommPorts());
15        }
16        return false;
17    }
18}
19org.bukkit.command.CommandException: Unhandled exception executing command 'check' in plugin MyFirstPlugin v1.0-SNAPSHOT
20        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
21        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
22        at org.bukkit.craftbukkit.v1_18_R1.CraftServer.dispatchCommand(CraftServer.java:821) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
23        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1939) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
24        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1778) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
25        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1759) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
26        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:46) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
27        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
28        at net.minecraft.network.protocol.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:30) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
29        at net.minecraft.server.TickTask.run(SourceFile:18) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
30        at net.minecraft.util.thread.IAsyncTaskHandler.c(SourceFile:151) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
31        at net.minecraft.util.thread.IAsyncTaskHandlerReentrant.c(SourceFile:23) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
32        at net.minecraft.server.MinecraftServer.b(MinecraftServer.java:1158) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
33        at net.minecraft.server.MinecraftServer.c(MinecraftServer.java:1) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
34        at net.minecraft.util.thread.IAsyncTaskHandler.y(SourceFile:125) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
35        at net.minecraft.server.MinecraftServer.bf(MinecraftServer.java:1137) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
36        at net.minecraft.server.MinecraftServer.y(MinecraftServer.java:1130) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
37        at net.minecraft.util.thread.IAsyncTaskHandler.c(SourceFile:134) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
38        at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1114) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
39        at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:1038) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
40        at net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:304) ~[spigot-1.18.1-R0.1-SNAPSHOT.jar:3380-Spigot-8965a50-0ba6b90]
41        at java.lang.Thread.run(Thread.java:833) [?:?]
42Caused by: java.lang.NoClassDefFoundError: com/fazecast/jSerialComm/SerialPort
43        at com.foamyguy.myfirstplugin.CommandCheck.onCommand(CommandCheck.java:21) ~[?:?]
44        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
45        ... 21 more
46Caused by: java.lang.ClassNotFoundException: com.fazecast.jSerialComm.SerialPort
47        at org.bukkit.plugin.java.PluginClassLoader.loadClass0(PluginClassLoader.java:147) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
48        at org.bukkit.plugin.java.PluginClassLoader.loadClass(PluginClassLoader.java:99) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
49        at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?]
50        at com.foamyguy.myfirstplugin.CommandCheck.onCommand(CommandCheck.java:21) ~[?:?]
51        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot-api-1.18.1-R0.1-SNAPSHOT.jar:?]
52        ... 21 more
53<dependency>
54    <groupId>com.fazecast</groupId>
55    <artifactId>jSerialComm</artifactId>
56    <version>[2.0.0,3.0.0)</version>
57    <scope>compile</scope> <!-- -->
58</dependency>
59<build>
60    <!-- ... -->
61    <plugins>
62      <!-- ... -->
63      <plugin>
64        <groupId>org.apache.maven.plugins</groupId>
65        <artifactId>maven-shade-plugin</artifactId>
66        <version>3.1.0</version>
67        <executions>
68          <execution>
69            <phase>package</phase>
70            <goals>
71              <goal>shade</goal>
72            </goals>
73          </execution>
74        </executions>
75      </plugin>
76      <!-- ... -->
77    </plugins>
78    <!-- ... -->
79  </build>
80├ com
81  ├ foamguy
82    └ myfirstplugin
83      └ ...
84├ plugin.yml
85└ jSerialComm-xxx.jar
86├ com
87  ├ foamguy
88    └ myfirstplugin
89      └ ...
90  └ fazecast
91    └ jSerialComm
92      └ ...
93└ plugin.yml
94

Source https://stackoverflow.com/questions/70544085

QUESTION

Infer dependencies in Gradle subproject from its parent project

Asked 2021-Dec-15 at 04:07

I currently have 3 subprojects in my Gradle project, structured like so:

1Main Project
2| 
3-- Project A
4-- Project B
5-- Common Src
6

Project A has dependency on Lib A and Common Src, and Project B has dependency on Lib B and Common Src. Lib A and Lib B contain different implementations of the same classes.

My plan for Common Src project was to house all of the utility classes, necessarily depending on both Lib A and Lib B.

Is there a way to set this up, and how should my gradle project look like?

Things that I've tried:
  1. I've tried to remove Common Src as a subproject and just include it in the sourceSets of Project A and Project B. However, IntelliJ seems to mark Common Src as sources root of Project A, and even though build-through-gradle works, I cannot get IntelliJ to recognize that Project B also has sources root in Common Src.
  2. Add both Lib A and Lib B to dependency of Common Src, but obviously that doesn't work.
The background:

I've created a Minecraft mod compatible with both Forge (Project A) and Fabric (Project B) modloaders. I have utility classes in both projects that have the same source code but need to be compiled twice, each time with a different dependency. I don't want to have to write the code twice each time I want to change something in the Utility classes.

ANSWER

Answered 2021-Dec-15 at 04:07

EDIT: I've found a workaround:

  1. In both Project A and Project B, add a task in each of their build.gradle to copy the source files from Common Src to the build directory of each project.
  2. Configure sourceSets of both Project A and Project B to include source files from the build folder we just copied into
  3. Configure Common Src to be a gradle subproject, and add Lib A (or Lib B) to the dependencies of Common Src (just to get IntelliJ some context)

Source https://stackoverflow.com/questions/70357453

QUESTION

Minecraft Forge 1.7.10 Custom Entity Not Spawning On The Client?

Asked 2021-Dec-02 at 22:58

In my Minecraft Forge mod for 1.7.10. I am aware that this version is arguably old news, but it is my favorite version and all of my modding experience is with this version.

I am creating a custom TNT block. The issue is the primed version is not rendering. When ignited, the TNT disappears, and then shortly later there is an explosion. If the TNT was placed in the air, the explosion is below like it should be due to the primed TNT falling. The issue is that it is not rendering. When I use fn+f3+b to show hitboxes, no hitbox is shown.

The issue is the entity being spawned on the server does not replicate to the client. I know this because:

  • Switching out the entity renderer with the default RenderTNTPrimed still fails to render at all instead of rendering the default TNT hence my custom renderer class cannot be the issue.

  • Switching out my custom entity class with the copy paste vanilla EntityTNTPrimed code also does not solve the problem. If the problem was with my custom entity class then using bona fide vanilla code would fix the problem but it doesnt.

  • The entity and its renderer are being registered using RenderingRegistry.registerEntityRenderingHandler() from the client proxy and EntityRegistry.registerGlobalEntityID() then EntityRegistry.registerModEntity() in init() (I had tested the client proxy with System.out.println() and the client proxy works).

  • Though the largest evidence of the problem being the TNT spawing on the server but not the client is the fact that removing if(world.isRemote) return; from the handlers in my BlockTNT class causes the TNT to render. However I am not supposed to handle igniting the TNT on the client so I am not supposed to have to remove if(world.isRemote) return;. Besides doing this is a pseudo fix, because the entity is still invisible when /summoned.

  • The constructor for TNTPrimedCharged is only being called from the server, and onUpdate() for TNTPrimed and thus TNTPrimedCharged is also only being called by the server, as demostrated by adding print statements and the logs only show them printed from the SERVER thread.

The BlockTNT class (much of this is derived from vanilla code, but has been designed to take the corresponding custom primed TNT entity class while instantiating, the problem is not here because instantiating a default EntityTNTPrimed instead of the provided primed class does render correctly, but I have included this because this code helped demonstrate the origin of the problem):

1class BlockTNT extends net.minecraft.block.BlockTNT {
2    private final Class primed;
3    public BlockTNT(final Class primed) {
4        this.primed = primed;
5        stepSound = net.minecraft.block.Block.soundTypeGrass;
6    }
7    protected EntityTNTPrimed getPrimed(final World world, final int x, final int y, final int z, final EntityLivingBase igniter) {
8        try {
9            return (EntityTNTPrimed)primed.getDeclaredConstructor(World.class, double.class, double.class, double.class, EntityLivingBase.class).newInstance(world, (double)((float)x+0.5F), (double)((float)y+0.5F), (double)((float)z+0.5F), igniter);
10        } catch (Exception exception) {
11            return null;
12        }
13    }
14    @Override public void onBlockDestroyedByExplosion(final World world, final int x, final int y, final int z, final Explosion explosion) {
15        if(world.isRemote)
16            return;
17        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, explosion.getExplosivePlacedBy());
18        tnt.fuse = world.rand.nextInt(tnt.fuse>>2)+(tnt.fuse>>3);
19        world.spawnEntityInWorld(tnt);
20    }
21    @Override public void func_150114_a(final World world, final int x, final int y, final int z, final int meta, final EntityLivingBase igniter) {
22        if(world.isRemote || (meta&1) == 0)
23            return;
24        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, igniter);
25        world.spawnEntityInWorld(tnt);
26        world.playSoundAtEntity(tnt, "game.tnt.primed", 1.0F, 1.0F);
27    }
28}
29

Inside the main mod class I register the entities:

1class BlockTNT extends net.minecraft.block.BlockTNT {
2    private final Class primed;
3    public BlockTNT(final Class primed) {
4        this.primed = primed;
5        stepSound = net.minecraft.block.Block.soundTypeGrass;
6    }
7    protected EntityTNTPrimed getPrimed(final World world, final int x, final int y, final int z, final EntityLivingBase igniter) {
8        try {
9            return (EntityTNTPrimed)primed.getDeclaredConstructor(World.class, double.class, double.class, double.class, EntityLivingBase.class).newInstance(world, (double)((float)x+0.5F), (double)((float)y+0.5F), (double)((float)z+0.5F), igniter);
10        } catch (Exception exception) {
11            return null;
12        }
13    }
14    @Override public void onBlockDestroyedByExplosion(final World world, final int x, final int y, final int z, final Explosion explosion) {
15        if(world.isRemote)
16            return;
17        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, explosion.getExplosivePlacedBy());
18        tnt.fuse = world.rand.nextInt(tnt.fuse>>2)+(tnt.fuse>>3);
19        world.spawnEntityInWorld(tnt);
20    }
21    @Override public void func_150114_a(final World world, final int x, final int y, final int z, final int meta, final EntityLivingBase igniter) {
22        if(world.isRemote || (meta&1) == 0)
23            return;
24        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, igniter);
25        world.spawnEntityInWorld(tnt);
26        world.playSoundAtEntity(tnt, "game.tnt.primed", 1.0F, 1.0F);
27    }
28}
29@Instance public static ExampleMod instance;
30@SidedProxy(clientSide="com.examplemod.ClientProxy", serverSide="com.examplemod.CommonProxy") public static com.examplemod.CommonProxy proxy;
31private static void registerTnt(final Class primed, String name, final int id) {
32    proxy.registerTntRenderer(primed, registerBlock(new BlockTNT(primed), name.toLowerCase()+"_tnt"));
33    EntityRegistry.registerGlobalEntityID(primed, name = "PrimedTnt"+name, EntityRegistry.findGlobalUniqueEntityId());
34    EntityRegistry.registerModEntity(primed, name, id, instance, 160, 10, true);
35}
36@EventHandler public void init(FMLInitializationEvent event) {
37    registerTnt(com.examplemod.TNTPrimedCharged.class, "Charged", 0);
38    // ...
39}
40

And we register the renderer in the client proxy (again tested and works):

1class BlockTNT extends net.minecraft.block.BlockTNT {
2    private final Class primed;
3    public BlockTNT(final Class primed) {
4        this.primed = primed;
5        stepSound = net.minecraft.block.Block.soundTypeGrass;
6    }
7    protected EntityTNTPrimed getPrimed(final World world, final int x, final int y, final int z, final EntityLivingBase igniter) {
8        try {
9            return (EntityTNTPrimed)primed.getDeclaredConstructor(World.class, double.class, double.class, double.class, EntityLivingBase.class).newInstance(world, (double)((float)x+0.5F), (double)((float)y+0.5F), (double)((float)z+0.5F), igniter);
10        } catch (Exception exception) {
11            return null;
12        }
13    }
14    @Override public void onBlockDestroyedByExplosion(final World world, final int x, final int y, final int z, final Explosion explosion) {
15        if(world.isRemote)
16            return;
17        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, explosion.getExplosivePlacedBy());
18        tnt.fuse = world.rand.nextInt(tnt.fuse>>2)+(tnt.fuse>>3);
19        world.spawnEntityInWorld(tnt);
20    }
21    @Override public void func_150114_a(final World world, final int x, final int y, final int z, final int meta, final EntityLivingBase igniter) {
22        if(world.isRemote || (meta&1) == 0)
23            return;
24        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, igniter);
25        world.spawnEntityInWorld(tnt);
26        world.playSoundAtEntity(tnt, "game.tnt.primed", 1.0F, 1.0F);
27    }
28}
29@Instance public static ExampleMod instance;
30@SidedProxy(clientSide="com.examplemod.ClientProxy", serverSide="com.examplemod.CommonProxy") public static com.examplemod.CommonProxy proxy;
31private static void registerTnt(final Class primed, String name, final int id) {
32    proxy.registerTntRenderer(primed, registerBlock(new BlockTNT(primed), name.toLowerCase()+"_tnt"));
33    EntityRegistry.registerGlobalEntityID(primed, name = "PrimedTnt"+name, EntityRegistry.findGlobalUniqueEntityId());
34    EntityRegistry.registerModEntity(primed, name, id, instance, 160, 10, true);
35}
36@EventHandler public void init(FMLInitializationEvent event) {
37    registerTnt(com.examplemod.TNTPrimedCharged.class, "Charged", 0);
38    // ...
39}
40@Override public void registerTntRenderer(final Class primed, final Block block) {
41    RenderingRegistry.registerEntityRenderingHandler(primed, new com.examplemod.RenderTNTPrimed(block));
42}
43

Here is the class for the custom entities:

1class BlockTNT extends net.minecraft.block.BlockTNT {
2    private final Class primed;
3    public BlockTNT(final Class primed) {
4        this.primed = primed;
5        stepSound = net.minecraft.block.Block.soundTypeGrass;
6    }
7    protected EntityTNTPrimed getPrimed(final World world, final int x, final int y, final int z, final EntityLivingBase igniter) {
8        try {
9            return (EntityTNTPrimed)primed.getDeclaredConstructor(World.class, double.class, double.class, double.class, EntityLivingBase.class).newInstance(world, (double)((float)x+0.5F), (double)((float)y+0.5F), (double)((float)z+0.5F), igniter);
10        } catch (Exception exception) {
11            return null;
12        }
13    }
14    @Override public void onBlockDestroyedByExplosion(final World world, final int x, final int y, final int z, final Explosion explosion) {
15        if(world.isRemote)
16            return;
17        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, explosion.getExplosivePlacedBy());
18        tnt.fuse = world.rand.nextInt(tnt.fuse>>2)+(tnt.fuse>>3);
19        world.spawnEntityInWorld(tnt);
20    }
21    @Override public void func_150114_a(final World world, final int x, final int y, final int z, final int meta, final EntityLivingBase igniter) {
22        if(world.isRemote || (meta&1) == 0)
23            return;
24        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, igniter);
25        world.spawnEntityInWorld(tnt);
26        world.playSoundAtEntity(tnt, "game.tnt.primed", 1.0F, 1.0F);
27    }
28}
29@Instance public static ExampleMod instance;
30@SidedProxy(clientSide="com.examplemod.ClientProxy", serverSide="com.examplemod.CommonProxy") public static com.examplemod.CommonProxy proxy;
31private static void registerTnt(final Class primed, String name, final int id) {
32    proxy.registerTntRenderer(primed, registerBlock(new BlockTNT(primed), name.toLowerCase()+"_tnt"));
33    EntityRegistry.registerGlobalEntityID(primed, name = "PrimedTnt"+name, EntityRegistry.findGlobalUniqueEntityId());
34    EntityRegistry.registerModEntity(primed, name, id, instance, 160, 10, true);
35}
36@EventHandler public void init(FMLInitializationEvent event) {
37    registerTnt(com.examplemod.TNTPrimedCharged.class, "Charged", 0);
38    // ...
39}
40@Override public void registerTntRenderer(final Class primed, final Block block) {
41    RenderingRegistry.registerEntityRenderingHandler(primed, new com.examplemod.RenderTNTPrimed(block));
42}
43public abstract class TNTPrimed extends net.minecraft.entity.item.EntityTNTPrimed {
44    public TNTPrimed(final World world, final double x, final double y, final double z, final EntityLivingBase igniter) {
45        super(world, x, y, z, igniter);
46    }
47    public TNTPrimed(final World world) {
48        super(world);
49    }
50    @Override public void onUpdate() {
51        prevPosX = posX;
52        prevPosY = posY;
53        prevPosZ = posZ;
54        moveEntity(motionX, motionY -= 0.04D, motionZ);
55        motionX *= 0.98D;
56        motionY *= 0.98D;
57        motionZ *= 0.98D;
58        if(onGround) {
59            motionX *= 0.7D;
60            motionZ *= 0.7D;
61            motionY *= -0.5D;
62        }
63        if(fuse-- <= 0) {
64            setDead();
65            if(!worldObj.isRemote)
66                explode();
67        } else
68            worldObj.spawnParticle("smoke", posX, posY+0.5D, posZ, 0.0D, 0.0D, 0.0D);
69    }
70    protected abstract void explode();
71}
72
1class BlockTNT extends net.minecraft.block.BlockTNT {
2    private final Class primed;
3    public BlockTNT(final Class primed) {
4        this.primed = primed;
5        stepSound = net.minecraft.block.Block.soundTypeGrass;
6    }
7    protected EntityTNTPrimed getPrimed(final World world, final int x, final int y, final int z, final EntityLivingBase igniter) {
8        try {
9            return (EntityTNTPrimed)primed.getDeclaredConstructor(World.class, double.class, double.class, double.class, EntityLivingBase.class).newInstance(world, (double)((float)x+0.5F), (double)((float)y+0.5F), (double)((float)z+0.5F), igniter);
10        } catch (Exception exception) {
11            return null;
12        }
13    }
14    @Override public void onBlockDestroyedByExplosion(final World world, final int x, final int y, final int z, final Explosion explosion) {
15        if(world.isRemote)
16            return;
17        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, explosion.getExplosivePlacedBy());
18        tnt.fuse = world.rand.nextInt(tnt.fuse>>2)+(tnt.fuse>>3);
19        world.spawnEntityInWorld(tnt);
20    }
21    @Override public void func_150114_a(final World world, final int x, final int y, final int z, final int meta, final EntityLivingBase igniter) {
22        if(world.isRemote || (meta&1) == 0)
23            return;
24        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, igniter);
25        world.spawnEntityInWorld(tnt);
26        world.playSoundAtEntity(tnt, "game.tnt.primed", 1.0F, 1.0F);
27    }
28}
29@Instance public static ExampleMod instance;
30@SidedProxy(clientSide="com.examplemod.ClientProxy", serverSide="com.examplemod.CommonProxy") public static com.examplemod.CommonProxy proxy;
31private static void registerTnt(final Class primed, String name, final int id) {
32    proxy.registerTntRenderer(primed, registerBlock(new BlockTNT(primed), name.toLowerCase()+"_tnt"));
33    EntityRegistry.registerGlobalEntityID(primed, name = "PrimedTnt"+name, EntityRegistry.findGlobalUniqueEntityId());
34    EntityRegistry.registerModEntity(primed, name, id, instance, 160, 10, true);
35}
36@EventHandler public void init(FMLInitializationEvent event) {
37    registerTnt(com.examplemod.TNTPrimedCharged.class, "Charged", 0);
38    // ...
39}
40@Override public void registerTntRenderer(final Class primed, final Block block) {
41    RenderingRegistry.registerEntityRenderingHandler(primed, new com.examplemod.RenderTNTPrimed(block));
42}
43public abstract class TNTPrimed extends net.minecraft.entity.item.EntityTNTPrimed {
44    public TNTPrimed(final World world, final double x, final double y, final double z, final EntityLivingBase igniter) {
45        super(world, x, y, z, igniter);
46    }
47    public TNTPrimed(final World world) {
48        super(world);
49    }
50    @Override public void onUpdate() {
51        prevPosX = posX;
52        prevPosY = posY;
53        prevPosZ = posZ;
54        moveEntity(motionX, motionY -= 0.04D, motionZ);
55        motionX *= 0.98D;
56        motionY *= 0.98D;
57        motionZ *= 0.98D;
58        if(onGround) {
59            motionX *= 0.7D;
60            motionZ *= 0.7D;
61            motionY *= -0.5D;
62        }
63        if(fuse-- <= 0) {
64            setDead();
65            if(!worldObj.isRemote)
66                explode();
67        } else
68            worldObj.spawnParticle("smoke", posX, posY+0.5D, posZ, 0.0D, 0.0D, 0.0D);
69    }
70    protected abstract void explode();
71}
72public class TNTPrimedCharged extends com.examplemod.TNTPrimed {
73    public TNTPrimedCharged(final World world, final double x, final double y, final double z, final EntityLivingBase igniter) {
74        super(world, x, y, z, igniter);
75    }
76    public TNTPrimedCharged(final World world) {
77        super(world);
78    }
79    @Override protected void explode() {
80        worldObj.newExplosion(this, posX, posY, posZ, 8, false, true);
81    }
82}
83

Though I can state categorically that the custom entity renderer class is not the culprit, I am providing it for reference:

1class BlockTNT extends net.minecraft.block.BlockTNT {
2    private final Class primed;
3    public BlockTNT(final Class primed) {
4        this.primed = primed;
5        stepSound = net.minecraft.block.Block.soundTypeGrass;
6    }
7    protected EntityTNTPrimed getPrimed(final World world, final int x, final int y, final int z, final EntityLivingBase igniter) {
8        try {
9            return (EntityTNTPrimed)primed.getDeclaredConstructor(World.class, double.class, double.class, double.class, EntityLivingBase.class).newInstance(world, (double)((float)x+0.5F), (double)((float)y+0.5F), (double)((float)z+0.5F), igniter);
10        } catch (Exception exception) {
11            return null;
12        }
13    }
14    @Override public void onBlockDestroyedByExplosion(final World world, final int x, final int y, final int z, final Explosion explosion) {
15        if(world.isRemote)
16            return;
17        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, explosion.getExplosivePlacedBy());
18        tnt.fuse = world.rand.nextInt(tnt.fuse>>2)+(tnt.fuse>>3);
19        world.spawnEntityInWorld(tnt);
20    }
21    @Override public void func_150114_a(final World world, final int x, final int y, final int z, final int meta, final EntityLivingBase igniter) {
22        if(world.isRemote || (meta&1) == 0)
23            return;
24        final EntityTNTPrimed tnt = getPrimed(world, x, y, z, igniter);
25        world.spawnEntityInWorld(tnt);
26        world.playSoundAtEntity(tnt, "game.tnt.primed", 1.0F, 1.0F);
27    }
28}
29@Instance public static ExampleMod instance;
30@SidedProxy(clientSide="com.examplemod.ClientProxy", serverSide="com.examplemod.CommonProxy") public static com.examplemod.CommonProxy proxy;
31private static void registerTnt(final Class primed, String name, final int id) {
32    proxy.registerTntRenderer(primed, registerBlock(new BlockTNT(primed), name.toLowerCase()+"_tnt"));
33    EntityRegistry.registerGlobalEntityID(primed, name = "PrimedTnt"+name, EntityRegistry.findGlobalUniqueEntityId());
34    EntityRegistry.registerModEntity(primed, name, id, instance, 160, 10, true);
35}
36@EventHandler public void init(FMLInitializationEvent event) {
37    registerTnt(com.examplemod.TNTPrimedCharged.class, "Charged", 0);
38    // ...
39}
40@Override public void registerTntRenderer(final Class primed, final Block block) {
41    RenderingRegistry.registerEntityRenderingHandler(primed, new com.examplemod.RenderTNTPrimed(block));
42}
43public abstract class TNTPrimed extends net.minecraft.entity.item.EntityTNTPrimed {
44    public TNTPrimed(final World world, final double x, final double y, final double z, final EntityLivingBase igniter) {
45        super(world, x, y, z, igniter);
46    }
47    public TNTPrimed(final World world) {
48        super(world);
49    }
50    @Override public void onUpdate() {
51        prevPosX = posX;
52        prevPosY = posY;
53        prevPosZ = posZ;
54        moveEntity(motionX, motionY -= 0.04D, motionZ);
55        motionX *= 0.98D;
56        motionY *= 0.98D;
57        motionZ *= 0.98D;
58        if(onGround) {
59            motionX *= 0.7D;
60            motionZ *= 0.7D;
61            motionY *= -0.5D;
62        }
63        if(fuse-- <= 0) {
64            setDead();
65            if(!worldObj.isRemote)
66                explode();
67        } else
68            worldObj.spawnParticle("smoke", posX, posY+0.5D, posZ, 0.0D, 0.0D, 0.0D);
69    }
70    protected abstract void explode();
71}
72public class TNTPrimedCharged extends com.examplemod.TNTPrimed {
73    public TNTPrimedCharged(final World world, final double x, final double y, final double z, final EntityLivingBase igniter) {
74        super(world, x, y, z, igniter);
75    }
76    public TNTPrimedCharged(final World world) {
77        super(world);
78    }
79    @Override protected void explode() {
80        worldObj.newExplosion(this, posX, posY, posZ, 8, false, true);
81    }
82}
83class RenderTNTPrimed extends net.minecraft.client.renderer.entity.RenderTNTPrimed {
84    private final RenderBlocks renderer = new RenderBlocks();
85    private final Block block;
86    public RenderTNTPrimed(final Block block) {
87        super();
88        this.block = block;
89    }
90    @Override public void doRender(final EntityTNTPrimed entity, final double x, final double y, final double z, final float yaw, final float tick) {
91        GL11.glPushMatrix();
92        GL11.glTranslatef((float)x, (float)y, (float)z);
93        float var0 = entity.fuse-tick+1.0F;
94        if (var0 < 10.0F) {
95            final float scale = (float)Math.pow(Math.max(Math.min(1-var0/10, 1.0F), 0.0F), 4.0F)*0.3F+1.0F;
96            GL11.glScalef(scale, scale, scale);
97        }
98        bindEntityTexture(entity);
99        renderer.renderBlockAsItem(block, 0, entity.getBrightness(tick));
100        if (((entity.fuse/5)&1) == 0) {
101            GL11.glDisable(GL11.GL_TEXTURE_2D);
102            GL11.glDisable(GL11.GL_LIGHTING);
103            GL11.glEnable(GL11.GL_BLEND);
104            GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_DST_ALPHA);
105            GL11.glColor4f(1.0F, 1.0F, 1.0F, (1.0F-var0/100.0F)*0.8F);
106            renderer.renderBlockAsItem(block, 0, 1.0F);
107            GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
108            GL11.glDisable(GL11.GL_BLEND);
109            GL11.glEnable(GL11.GL_LIGHTING);
110            GL11.glEnable(GL11.GL_TEXTURE_2D);
111        }
112        GL11.glPopMatrix();
113    }
114}
115

So when the server calls world.spawnEntityInWorld() on my custom entity why does it fail to spawn it on the client as well? How can I fix this because the TNT just disappearing when being ignited is undesirable and I have no idea what else to try. How can I make the custom primed TNT show up on the client?

Upon reverse engineering other similar mods (specifically the Too Much TNT mod), their TNT primed entities successfully render when /summon is used, and they do check for clientside in their TNT block classes. After investigation, I cannot tell what they are doing differently that would cause their entities to render but not mine.

I have spent several unfruitful hours researching this problem, and given that as of this edit this question is second hit for Googling basic search terms like 'Minecraft Forge 1.7.10 Entity Not Rendering' and third for 'Minecraft Forge 1.7.10 Entity Invisible,' it is very likely that further research will be in vain.

The problem is simply that when my mod added entity is spawned on the server thread, it is not also spawned on the client thread, even though it should be. How do I fix this? I tried everything.

ANSWER

Answered 2021-Dec-02 at 22:58

It turns out the problem was actually not the entity not spawning on the client. The issue was that the fuse property was being set to 0 on the client even though it is set to 80 on the server. And thus the client side TNT is instantly setDead()ing itself. Implementing cpw.mods.fml.common.registry.IEntityAdditionalSpawnData and then setting the fuse property to the correct value in readSpawnData seems to have solved the problem.

Source https://stackoverflow.com/questions/70119718

QUESTION

Generate custom ores in custom dimension

Asked 2021-Nov-25 at 16:54

I have recently created a custom dimension using data packs in Minecraft 1.16.5. This dimension is a part of a mod that I am writing and I am currently trying to generate custom ores in that dimension; However, I was not able to generate ores in a custom dimension the same way that I generate ores in the Overworld or Nether. As I mentioned the dimension is handled via data packs (.json files) but the biomes are handled in game code (.java). I am very new to Java & modding, any suggestions would be appreciated. Thanks in advance.

Minecraft version : 1.16.5
Forge version : 36.2.9

The current code for Overworld & Nether ore gen :

1public class OreGeneration 
2{
3    public static void generateOres(final BiomeLoadingEvent event)
4    {
5        // Gigalium :
6        if(!(event.getCategory().equals(Biome.Category.THEEND)))
7        {
8            // Nether :
9            if(event.getCategory().equals(Biome.Category.NETHER))
10            {
11                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NETHERRACK, BlockInit.GIGALIUM_NETHER_ORE.get().defaultBlockState(), 6, 25, 50, 2);
12                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NETHERRACK, BlockInit.GIGALIUM_NETHER_ORE.get().defaultBlockState(), 4, 51, 120, 2);
13            }
14
15            // Overworld :
16            if(event.getCategory().equals(Biome.Category.SWAMP) || event.getCategory().equals(Biome.Category.TAIGA))
17            {
18                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 5, 12, 15, 2);
19                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 4, 16, 20, 2);
20            }
21
22            if(!(event.getCategory().equals(Biome.Category.SWAMP) && event.getCategory().equals(Biome.Category.TAIGA)))
23            {
24                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 4, 10, 13, 1);
25                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 3, 14, 18, 1);
26            }
27        }
28    }
29
30    private static void generateOre(BiomeGenerationSettingsBuilder settings, RuleTest fillerType, BlockState state, int veinSize, int minHeight, int maxHeight, int amount)
31    {
32        settings.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Feature.ORE.configured(new OreFeatureConfig(fillerType, state, veinSize)).decorated(Placement.RANGE.configured(new TopSolidRangeConfig(minHeight, 0, maxHeight))).squared().count(amount));
33    }
34}
35

Dimension code :

1public class OreGeneration 
2{
3    public static void generateOres(final BiomeLoadingEvent event)
4    {
5        // Gigalium :
6        if(!(event.getCategory().equals(Biome.Category.THEEND)))
7        {
8            // Nether :
9            if(event.getCategory().equals(Biome.Category.NETHER))
10            {
11                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NETHERRACK, BlockInit.GIGALIUM_NETHER_ORE.get().defaultBlockState(), 6, 25, 50, 2);
12                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NETHERRACK, BlockInit.GIGALIUM_NETHER_ORE.get().defaultBlockState(), 4, 51, 120, 2);
13            }
14
15            // Overworld :
16            if(event.getCategory().equals(Biome.Category.SWAMP) || event.getCategory().equals(Biome.Category.TAIGA))
17            {
18                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 5, 12, 15, 2);
19                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 4, 16, 20, 2);
20            }
21
22            if(!(event.getCategory().equals(Biome.Category.SWAMP) && event.getCategory().equals(Biome.Category.TAIGA)))
23            {
24                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 4, 10, 13, 1);
25                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 3, 14, 18, 1);
26            }
27        }
28    }
29
30    private static void generateOre(BiomeGenerationSettingsBuilder settings, RuleTest fillerType, BlockState state, int veinSize, int minHeight, int maxHeight, int amount)
31    {
32        settings.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Feature.ORE.configured(new OreFeatureConfig(fillerType, state, veinSize)).decorated(Placement.RANGE.configured(new TopSolidRangeConfig(minHeight, 0, maxHeight))).squared().count(amount));
33    }
34}
35{
36    "type": "gigawhat_gigamod:gigaland",
37    "generator": {
38        "type": "minecraft:noise",
39        "seed": 0,
40        "settings": {
41            "bedrock_roof_position": -10,
42            "bedrock_floor_position": 0,
43            "sea_level": 80,
44            "disable_mob_generation": true,
45            "default_block": {
46                "Name": "gigawhat_gigamod:gigastone"
47            },
48            "default_fluid": {
49                "Name": "minecraft:water",
50                "Properties": {
51                    "level": "0"
52                }
53            },
54            "noise": {
55                "height": 256,
56                "density_factor": 1,
57                "density_offset": -0.46875,
58                "size_horizontal": 1,
59                "size_vertical": 2,
60                "simplex_surface_noise": true,
61                "random_density_offset": true,
62                "amplified": true,
63                "sampling": {
64                    "xz_scale": 1,
65                    "y_scale": 1,
66                    "xz_factor": 80,
67                    "y_factor": 160
68                },
69                "bottom_slide": {
70                    "target": -30,
71                    "size": 0,
72                    "offset": 0
73                },
74                "top_slide": {
75                    "target": -10,
76                    "size": 3,
77                    "offset": 0
78                }
79            },
80            "structures": {
81                "structures": {}
82            }
83        },
84        "biome_source": {
85            "type": "minecraft:fixed",
86            "biome": "gigawhat_gigamod:gigaland_main_biome"
87        }
88    }
89}
90

Biome Init code :

1public class OreGeneration 
2{
3    public static void generateOres(final BiomeLoadingEvent event)
4    {
5        // Gigalium :
6        if(!(event.getCategory().equals(Biome.Category.THEEND)))
7        {
8            // Nether :
9            if(event.getCategory().equals(Biome.Category.NETHER))
10            {
11                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NETHERRACK, BlockInit.GIGALIUM_NETHER_ORE.get().defaultBlockState(), 6, 25, 50, 2);
12                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NETHERRACK, BlockInit.GIGALIUM_NETHER_ORE.get().defaultBlockState(), 4, 51, 120, 2);
13            }
14
15            // Overworld :
16            if(event.getCategory().equals(Biome.Category.SWAMP) || event.getCategory().equals(Biome.Category.TAIGA))
17            {
18                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 5, 12, 15, 2);
19                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 4, 16, 20, 2);
20            }
21
22            if(!(event.getCategory().equals(Biome.Category.SWAMP) && event.getCategory().equals(Biome.Category.TAIGA)))
23            {
24                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 4, 10, 13, 1);
25                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 3, 14, 18, 1);
26            }
27        }
28    }
29
30    private static void generateOre(BiomeGenerationSettingsBuilder settings, RuleTest fillerType, BlockState state, int veinSize, int minHeight, int maxHeight, int amount)
31    {
32        settings.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Feature.ORE.configured(new OreFeatureConfig(fillerType, state, veinSize)).decorated(Placement.RANGE.configured(new TopSolidRangeConfig(minHeight, 0, maxHeight))).squared().count(amount));
33    }
34}
35{
36    "type": "gigawhat_gigamod:gigaland",
37    "generator": {
38        "type": "minecraft:noise",
39        "seed": 0,
40        "settings": {
41            "bedrock_roof_position": -10,
42            "bedrock_floor_position": 0,
43            "sea_level": 80,
44            "disable_mob_generation": true,
45            "default_block": {
46                "Name": "gigawhat_gigamod:gigastone"
47            },
48            "default_fluid": {
49                "Name": "minecraft:water",
50                "Properties": {
51                    "level": "0"
52                }
53            },
54            "noise": {
55                "height": 256,
56                "density_factor": 1,
57                "density_offset": -0.46875,
58                "size_horizontal": 1,
59                "size_vertical": 2,
60                "simplex_surface_noise": true,
61                "random_density_offset": true,
62                "amplified": true,
63                "sampling": {
64                    "xz_scale": 1,
65                    "y_scale": 1,
66                    "xz_factor": 80,
67                    "y_factor": 160
68                },
69                "bottom_slide": {
70                    "target": -30,
71                    "size": 0,
72                    "offset": 0
73                },
74                "top_slide": {
75                    "target": -10,
76                    "size": 3,
77                    "offset": 0
78                }
79            },
80            "structures": {
81                "structures": {}
82            }
83        },
84        "biome_source": {
85            "type": "minecraft:fixed",
86            "biome": "gigawhat_gigamod:gigaland_main_biome"
87        }
88    }
89}
90public class ModBiomes 
91{
92    public static final DeferredRegister<Biome> BIOMES = DeferredRegister.create(ForgeRegistries.BIOMES, Gigamod.MOD_ID);
93
94    public static final RegistryObject<Biome> GIGALAND_MAIN_BIOME = BIOMES.register("gigaland_main_biome", () -> makeGigalandMainBiome(() -> ModConfiguredSurfaceBuilders.GIGALAND_SURFACE, 0.205f, 0.02f));
95
96    private static Biome makeGigalandMainBiome(final Supplier<ConfiguredSurfaceBuilder<?>> surfaceBuilder, float depth, float scale) 
97    {
98        MobSpawnInfo.Builder mobspawninfo$builder = new MobSpawnInfo.Builder();
99        BiomeGenerationSettings.Builder biomegenerationsettings$builder = (new BiomeGenerationSettings.Builder()).surfaceBuilder(surfaceBuilder);
100
101        DefaultBiomeFeatures.addDefaultOverworldLandStructures(biomegenerationsettings$builder);
102        biomegenerationsettings$builder.addStructureStart(StructureFeatures.MINESHAFT);
103
104        DefaultBiomeFeatures.addDefaultCarvers(biomegenerationsettings$builder);
105        DefaultBiomeFeatures.addDefaultUndergroundVariety(biomegenerationsettings$builder);
106
107        mobspawninfo$builder.addSpawn(EntityClassification.MONSTER, new MobSpawnInfo.Spawners(EntityType.BLAZE, 100, 10, 15));
108
109        return (new Biome.Builder()).precipitation(RainType.RAIN).biomeCategory(Category.EXTREME_HILLS).depth(depth).scale(scale).temperature(1.5F).downfall(0.9F).specialEffects((new BiomeAmbience.Builder()).waterColor(65518).waterFogColor(16763760).fogColor(16763760).skyColor(16763760).foliageColorOverride(9547008).grassColorOverride(9547008).ambientParticle(new ParticleEffectAmbience(ParticleTypes.LAVA, 0.003f)).skyColor(16763760).ambientLoopSound(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP).ambientMoodSound(new MoodSoundAmbience(SoundEvents.AMBIENT_WARPED_FOREST_MOOD, 6000, 8, 2.0D)).ambientAdditionsSound(new SoundAdditionsAmbience(SoundEvents.AMBIENT_NETHER_WASTES_MOOD, 0.0111D)).build()).mobSpawnSettings(mobspawninfo$builder.build()).generationSettings(biomegenerationsettings$builder.build()).build();
110    }
111
112    public static void register(IEventBus eventBus)
113    {
114        BIOMES.register(eventBus);
115    }
116}
117

ANSWER

Answered 2021-Nov-25 at 16:54

Answering my own question.

Instead of using event.getCategory().equals(SomeBiomeCategory) in the if statement in the OreGen class you should use event.getName().equals(YourModBiomeInit.BiomeName.getId(). Because event.getCategory().equals(SomeBiomeCategory) gets the category of the biome currently generating whilst event.getName().equals(YourModBiomeInit.BiomeName.getId() gets the registered name (or id).

So the if statement would look something like this :

1public class OreGeneration 
2{
3    public static void generateOres(final BiomeLoadingEvent event)
4    {
5        // Gigalium :
6        if(!(event.getCategory().equals(Biome.Category.THEEND)))
7        {
8            // Nether :
9            if(event.getCategory().equals(Biome.Category.NETHER))
10            {
11                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NETHERRACK, BlockInit.GIGALIUM_NETHER_ORE.get().defaultBlockState(), 6, 25, 50, 2);
12                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NETHERRACK, BlockInit.GIGALIUM_NETHER_ORE.get().defaultBlockState(), 4, 51, 120, 2);
13            }
14
15            // Overworld :
16            if(event.getCategory().equals(Biome.Category.SWAMP) || event.getCategory().equals(Biome.Category.TAIGA))
17            {
18                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 5, 12, 15, 2);
19                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 4, 16, 20, 2);
20            }
21
22            if(!(event.getCategory().equals(Biome.Category.SWAMP) && event.getCategory().equals(Biome.Category.TAIGA)))
23            {
24                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 4, 10, 13, 1);
25                generateOre(event.getGeneration(), OreFeatureConfig.FillerBlockType.NATURAL_STONE, BlockInit.GIGALIUM_ORE.get().defaultBlockState(), 3, 14, 18, 1);
26            }
27        }
28    }
29
30    private static void generateOre(BiomeGenerationSettingsBuilder settings, RuleTest fillerType, BlockState state, int veinSize, int minHeight, int maxHeight, int amount)
31    {
32        settings.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Feature.ORE.configured(new OreFeatureConfig(fillerType, state, veinSize)).decorated(Placement.RANGE.configured(new TopSolidRangeConfig(minHeight, 0, maxHeight))).squared().count(amount));
33    }
34}
35{
36    "type": "gigawhat_gigamod:gigaland",
37    "generator": {
38        "type": "minecraft:noise",
39        "seed": 0,
40        "settings": {
41            "bedrock_roof_position": -10,
42            "bedrock_floor_position": 0,
43            "sea_level": 80,
44            "disable_mob_generation": true,
45            "default_block": {
46                "Name": "gigawhat_gigamod:gigastone"
47            },
48            "default_fluid": {
49                "Name": "minecraft:water",
50                "Properties": {
51                    "level": "0"
52                }
53            },
54            "noise": {
55                "height": 256,
56                "density_factor": 1,
57                "density_offset": -0.46875,
58                "size_horizontal": 1,
59                "size_vertical": 2,
60                "simplex_surface_noise": true,
61                "random_density_offset": true,
62                "amplified": true,
63                "sampling": {
64                    "xz_scale": 1,
65                    "y_scale": 1,
66                    "xz_factor": 80,
67                    "y_factor": 160
68                },
69                "bottom_slide": {
70                    "target": -30,
71                    "size": 0,
72                    "offset": 0
73                },
74                "top_slide": {
75                    "target": -10,
76                    "size": 3,
77                    "offset": 0
78                }
79            },
80            "structures": {
81                "structures": {}
82            }
83        },
84        "biome_source": {
85            "type": "minecraft:fixed",
86            "biome": "gigawhat_gigamod:gigaland_main_biome"
87        }
88    }
89}
90public class ModBiomes 
91{
92    public static final DeferredRegister<Biome> BIOMES = DeferredRegister.create(ForgeRegistries.BIOMES, Gigamod.MOD_ID);
93
94    public static final RegistryObject<Biome> GIGALAND_MAIN_BIOME = BIOMES.register("gigaland_main_biome", () -> makeGigalandMainBiome(() -> ModConfiguredSurfaceBuilders.GIGALAND_SURFACE, 0.205f, 0.02f));
95
96    private static Biome makeGigalandMainBiome(final Supplier<ConfiguredSurfaceBuilder<?>> surfaceBuilder, float depth, float scale) 
97    {
98        MobSpawnInfo.Builder mobspawninfo$builder = new MobSpawnInfo.Builder();
99        BiomeGenerationSettings.Builder biomegenerationsettings$builder = (new BiomeGenerationSettings.Builder()).surfaceBuilder(surfaceBuilder);
100
101        DefaultBiomeFeatures.addDefaultOverworldLandStructures(biomegenerationsettings$builder);
102        biomegenerationsettings$builder.addStructureStart(StructureFeatures.MINESHAFT);
103
104        DefaultBiomeFeatures.addDefaultCarvers(biomegenerationsettings$builder);
105        DefaultBiomeFeatures.addDefaultUndergroundVariety(biomegenerationsettings$builder);
106
107        mobspawninfo$builder.addSpawn(EntityClassification.MONSTER, new MobSpawnInfo.Spawners(EntityType.BLAZE, 100, 10, 15));
108
109        return (new Biome.Builder()).precipitation(RainType.RAIN).biomeCategory(Category.EXTREME_HILLS).depth(depth).scale(scale).temperature(1.5F).downfall(0.9F).specialEffects((new BiomeAmbience.Builder()).waterColor(65518).waterFogColor(16763760).fogColor(16763760).skyColor(16763760).foliageColorOverride(9547008).grassColorOverride(9547008).ambientParticle(new ParticleEffectAmbience(ParticleTypes.LAVA, 0.003f)).skyColor(16763760).ambientLoopSound(SoundEvents.AMBIENT_CRIMSON_FOREST_LOOP).ambientMoodSound(new MoodSoundAmbience(SoundEvents.AMBIENT_WARPED_FOREST_MOOD, 6000, 8, 2.0D)).ambientAdditionsSound(new SoundAdditionsAmbience(SoundEvents.AMBIENT_NETHER_WASTES_MOOD, 0.0111D)).build()).mobSpawnSettings(mobspawninfo$builder.build()).generationSettings(biomegenerationsettings$builder.build()).build();
110    }
111
112    public static void register(IEventBus eventBus)
113    {
114        BIOMES.register(eventBus);
115    }
116}
117if(event.getName().equals(YourModBiomeInit.SOME_BIOME.getId()))
118{
119   // Generate ores ...
120}
121

Source https://stackoverflow.com/questions/70032415

QUESTION

Special condition - remove all the version numbers from the mods to search for the new version

Asked 2021-Oct-29 at 17:19

Trying to create an update script for Minecraft mods and need to be able to remove all the version numbers from the mods to search for the new version.

I have gotten it working to a point but am stuck on one last part. I cannot get it to leave out the 25 from pre25 from that line I need cfm pre (the 25 is the build number which I do not want)

1[A-Za-z].*?(?=-[0-9])|(?<= ).*(?= )|([s].*?[k])|([f].*?[e])
2
1[A-Za-z].*?(?=-[0-9])|(?<= ).*(?= )|([s].*?[k])|([f].*?[e])
21.17.1-additionalbars-2.1.0.jar
3'[1.17.1] SecurityCraft v1.8.23-beta5.jar'
4absentbydesign-1.17.1-1.6.0.jar
5additionalbarsbop-2.1.0.jar
6AdditionalEnchantedMiner-1.17-17.6-SNAPSHOT.jar
7additionallanterns-1.0.0a-mc1.17.jar
8cfm-7.0.0pre25-1.17.1.jar
9Croptopia-1.17-FORGE-1.6.2.jar
10nekoration-1.17.X-1.4.0.jar
11ScalableCatsForce-2.13.6-build-4-with-library.jar
12spark-forge.jar
13treeharvester_1.17.1-3.2.jar
14

ANSWER

Answered 2021-Oct-29 at 13:46

This part in your pattern is matching too much, as this part .*?(?=-[0-9]) is matching as least as possible chars until it can assert -[0-9] to the right which will match pre25 in pre25-1


You could update the pattern to match an optional part matching digits separated by dots, and in the positive lookahead add asserting optional digits at the beginning [A-Za-z_]+(?:\d+(?:\.\d+)+)?(?=[0-9]*-[0-9]) to reach the hyphen followed by a digit.

You could make the .*? non greedy matching all between spaces as .* can over match in case of more spaces.

The updated pattern (without the capture groups if you want a match only) could look like

1[A-Za-z].*?(?=-[0-9])|(?<= ).*(?= )|([s].*?[k])|([f].*?[e])
21.17.1-additionalbars-2.1.0.jar
3'[1.17.1] SecurityCraft v1.8.23-beta5.jar'
4absentbydesign-1.17.1-1.6.0.jar
5additionalbarsbop-2.1.0.jar
6AdditionalEnchantedMiner-1.17-17.6-SNAPSHOT.jar
7additionallanterns-1.0.0a-mc1.17.jar
8cfm-7.0.0pre25-1.17.1.jar
9Croptopia-1.17-FORGE-1.6.2.jar
10nekoration-1.17.X-1.4.0.jar
11ScalableCatsForce-2.13.6-build-4-with-library.jar
12spark-forge.jar
13treeharvester_1.17.1-3.2.jar
14[A-Za-z_]+(?:\d+(?:\.\d+)+)?(?=[0-9]*-[0-9])|(?<= ).*?(?= )|s.*?k|f.*?e
15

Source https://stackoverflow.com/questions/69769333

QUESTION

How to filter an array on click in react?

Asked 2021-Oct-05 at 23:48

So, basically, I'm making a website where you can search for Minecraft hacked clients. There is a search bar on the website, but you have to search in exact terms (different topic lol). Basically on the click of a button (search button) I then want to filter using the search term, (not automatically as I have it now) I've been searching but cant find a way to do it.

Code ->

1import CountUp from 'react-countup';
2import { Link } from 'react-router-dom';
3import '../App.css';
4
5/*Components ->*/
6import Client from '../components/client.js'
7
8function App() {
9
10    const [search, setSearch] = React.useState({
11        searchname: ''
12    });
13
14    **Array containing client data ->** const [client, setClient] = React.useState([
15        { safestatus: 'safe-status-green', safe: 'Safe (Verified)', name: 'Impact', price: 'Free', mcversion: '1.11.2 - 1.16.5', type: 'Injected', compat: 'None (Stand alone client)', desc: 'The Impact client is an advanced utility mod for Minecraft, it is packaged with Baritone and includes a large number of useful mods.', screen: 'https://impactclient.net/', download: 'https://impactclient.net/'},
16        { safestatus: 'safe-status-green', safe: 'Safe (Verified)', name: 'Future', price: '15€', mcversion: '1.8.9 - 1.14.4', type: 'Injected', compat: 'None (Stand alone client)', desc: 'Vanilla, OptiFine, Forge and Liteloader support, Easy to use account manager, Auto-reconnect mod.', screen: 'https://www.futureclient.net/', download: 'https://www.futureclient.net/'}
17        
18    ]);
19
20    const updateSearch = (event) => {
21        event.persist();
22        setSearch((prev) => ({
23            ...prev,
24            [event.target.name]: event.target.value
25          }));
26    };
27    
28  return (
29    <body>
30        <div className='header'><Link to='/'>Hacked Hub</Link><div className='header-links'><Link to='/about-us'>About Us</Link> | <Link to='/faq'>FAQ</Link></div></div>
31        <div className='counter'><CountUp end={16} duration={0.5}></CountUp>+</div>
32        <div className='counter-desc'><div className='code'>hacked clients</div> and counting...</div>
33        <div className='nxt-tab'>
34            <input name='searchname' value={search.searchname} onChange={updateSearch} placeholder='Search'></input>
35            <select name='price'>
36                <option value='Free'>Free</option>
37                <option value='Paid'>Paid</option>
38            </select>
39            <select name='safe'>
40                <option value='Safe'>Safe</option>
41                <option value='Probably Safe'>Probably Safe</option>
42                <option value='Not Safe'>Not Safe (BE CAREFUL!)</option>
43            </select>
44            <select name='mcver'>
45                <option value='1.8.9'>1.8.9</option>
46                <option value='1.12.2'>1.12.2</option>
47                <option value='1.16.5'>1.16.5</option>
48                <option value='1.17+'>1.17+</option>
49            </select>
50            <select name='type'>
51                <option value='Main'>Injected</option>
52                <option value='Side'>Mod</option>
53            </select>
54            <select name='compatibility'>
55                <option value='With Most Other Clients'>With Most Other Clients</option>
56                <option value='Stand Alone'>Stand Alone</option>
57            </select>
58            <div className='client-warning'><div className='safe-status-red'><div className='code'>⚠ WARNING ⚠</div></div> Only download clients you know are <div className='code'>100%</div> safe! If we do find a client that is a <div className='code'>rat / virus / BTC miner</div> we will tag it as <div className='safe-status-red'><div className='code'>UNSAFE IMMEDIATELY</div></div>. The saftey warnings for clients are <div className='code'>MERE RECCOMENDATIONS</div>, please do thorough research before downloading any hacked client that you are not <div className='code'>100%</div> sure is safe. This page is also in <div className='code'>development</div>, meaning features are prone to break! So be careful!!!</div>
59            <div className='code'>Sponsored clients</div>
60                <h1>None XD</h1>
61            <div className='code'>Submitted clients</div>
62                {client
63                    **Filtering the array then mapping it -> (This i want to do onClick)** .filter((client) => client.name === search.searchname)
64                    .map((client, index) => {
65                        return (
66                            <Client
67                                safestatus={client.safestatus}
68                                safe={client.safe}
69                                name={client.name}
70                                price={client.price}
71                                mcversion={client.mcversion}
72                                type={client.type}
73                                compat={client.compat}
74                                desc={client.desc}
75                                screen={client.screen}
76                                download={client.download}
77                            />
78                        );
79                    })}
80            </div>
81    </body>
82  );
83}
84
85export default App;
86

Anyone know how I could do this onClick?

ANSWER

Answered 2021-Oct-05 at 23:48

Use two pieces of state; one to track the value in your text field and the other to store the search term for filtering. Only set the latter when you click your button

1import CountUp from 'react-countup';
2import { Link } from 'react-router-dom';
3import '../App.css';
4
5/*Components ->*/
6import Client from '../components/client.js'
7
8function App() {
9
10    const [search, setSearch] = React.useState({
11        searchname: ''
12    });
13
14    **Array containing client data ->** const [client, setClient] = React.useState([
15        { safestatus: 'safe-status-green', safe: 'Safe (Verified)', name: 'Impact', price: 'Free', mcversion: '1.11.2 - 1.16.5', type: 'Injected', compat: 'None (Stand alone client)', desc: 'The Impact client is an advanced utility mod for Minecraft, it is packaged with Baritone and includes a large number of useful mods.', screen: 'https://impactclient.net/', download: 'https://impactclient.net/'},
16        { safestatus: 'safe-status-green', safe: 'Safe (Verified)', name: 'Future', price: '15€', mcversion: '1.8.9 - 1.14.4', type: 'Injected', compat: 'None (Stand alone client)', desc: 'Vanilla, OptiFine, Forge and Liteloader support, Easy to use account manager, Auto-reconnect mod.', screen: 'https://www.futureclient.net/', download: 'https://www.futureclient.net/'}
17        
18    ]);
19
20    const updateSearch = (event) => {
21        event.persist();
22        setSearch((prev) => ({
23            ...prev,
24            [event.target.name]: event.target.value
25          }));
26    };
27    
28  return (
29    <body>
30        <div className='header'><Link to='/'>Hacked Hub</Link><div className='header-links'><Link to='/about-us'>About Us</Link> | <Link to='/faq'>FAQ</Link></div></div>
31        <div className='counter'><CountUp end={16} duration={0.5}></CountUp>+</div>
32        <div className='counter-desc'><div className='code'>hacked clients</div> and counting...</div>
33        <div className='nxt-tab'>
34            <input name='searchname' value={search.searchname} onChange={updateSearch} placeholder='Search'></input>
35            <select name='price'>
36                <option value='Free'>Free</option>
37                <option value='Paid'>Paid</option>
38            </select>
39            <select name='safe'>
40                <option value='Safe'>Safe</option>
41                <option value='Probably Safe'>Probably Safe</option>
42                <option value='Not Safe'>Not Safe (BE CAREFUL!)</option>
43            </select>
44            <select name='mcver'>
45                <option value='1.8.9'>1.8.9</option>
46                <option value='1.12.2'>1.12.2</option>
47                <option value='1.16.5'>1.16.5</option>
48                <option value='1.17+'>1.17+</option>
49            </select>
50            <select name='type'>
51                <option value='Main'>Injected</option>
52                <option value='Side'>Mod</option>
53            </select>
54            <select name='compatibility'>
55                <option value='With Most Other Clients'>With Most Other Clients</option>
56                <option value='Stand Alone'>Stand Alone</option>
57            </select>
58            <div className='client-warning'><div className='safe-status-red'><div className='code'>⚠ WARNING ⚠</div></div> Only download clients you know are <div className='code'>100%</div> safe! If we do find a client that is a <div className='code'>rat / virus / BTC miner</div> we will tag it as <div className='safe-status-red'><div className='code'>UNSAFE IMMEDIATELY</div></div>. The saftey warnings for clients are <div className='code'>MERE RECCOMENDATIONS</div>, please do thorough research before downloading any hacked client that you are not <div className='code'>100%</div> sure is safe. This page is also in <div className='code'>development</div>, meaning features are prone to break! So be careful!!!</div>
59            <div className='code'>Sponsored clients</div>
60                <h1>None XD</h1>
61            <div className='code'>Submitted clients</div>
62                {client
63                    **Filtering the array then mapping it -> (This i want to do onClick)** .filter((client) => client.name === search.searchname)
64                    .map((client, index) => {
65                        return (
66                            <Client
67                                safestatus={client.safestatus}
68                                safe={client.safe}
69                                name={client.name}
70                                price={client.price}
71                                mcversion={client.mcversion}
72                                type={client.type}
73                                compat={client.compat}
74                                desc={client.desc}
75                                screen={client.screen}
76                                download={client.download}
77                            />
78                        );
79                    })}
80            </div>
81    </body>
82  );
83}
84
85export default App;
86const [ searchValue, setSearchValue ] = React.useState("")
87const [ searchTerm, setSearchTerm ] = React.useState("")
88
89const filteredClient = React.useMemo(() => {
90  if (searchTerm.length > 0) {
91    return client.filter(({ name }) => name === searchTerm)
92  }
93  return client
94}, [ searchTerm, client ])
95

and in your JSX

1import CountUp from 'react-countup';
2import { Link } from 'react-router-dom';
3import '../App.css';
4
5/*Components ->*/
6import Client from '../components/client.js'
7
8function App() {
9
10    const [search, setSearch] = React.useState({
11        searchname: ''
12    });
13
14    **Array containing client data ->** const [client, setClient] = React.useState([
15        { safestatus: 'safe-status-green', safe: 'Safe (Verified)', name: 'Impact', price: 'Free', mcversion: '1.11.2 - 1.16.5', type: 'Injected', compat: 'None (Stand alone client)', desc: 'The Impact client is an advanced utility mod for Minecraft, it is packaged with Baritone and includes a large number of useful mods.', screen: 'https://impactclient.net/', download: 'https://impactclient.net/'},
16        { safestatus: 'safe-status-green', safe: 'Safe (Verified)', name: 'Future', price: '15€', mcversion: '1.8.9 - 1.14.4', type: 'Injected', compat: 'None (Stand alone client)', desc: 'Vanilla, OptiFine, Forge and Liteloader support, Easy to use account manager, Auto-reconnect mod.', screen: 'https://www.futureclient.net/', download: 'https://www.futureclient.net/'}
17        
18    ]);
19
20    const updateSearch = (event) => {
21        event.persist();
22        setSearch((prev) => ({
23            ...prev,
24            [event.target.name]: event.target.value
25          }));
26    };
27    
28  return (
29    <body>
30        <div className='header'><Link to='/'>Hacked Hub</Link><div className='header-links'><Link to='/about-us'>About Us</Link> | <Link to='/faq'>FAQ</Link></div></div>
31        <div className='counter'><CountUp end={16} duration={0.5}></CountUp>+</div>
32        <div className='counter-desc'><div className='code'>hacked clients</div> and counting...</div>
33        <div className='nxt-tab'>
34            <input name='searchname' value={search.searchname} onChange={updateSearch} placeholder='Search'></input>
35            <select name='price'>
36                <option value='Free'>Free</option>
37                <option value='Paid'>Paid</option>
38            </select>
39            <select name='safe'>
40                <option value='Safe'>Safe</option>
41                <option value='Probably Safe'>Probably Safe</option>
42                <option value='Not Safe'>Not Safe (BE CAREFUL!)</option>
43            </select>
44            <select name='mcver'>
45                <option value='1.8.9'>1.8.9</option>
46                <option value='1.12.2'>1.12.2</option>
47                <option value='1.16.5'>1.16.5</option>
48                <option value='1.17+'>1.17+</option>
49            </select>
50            <select name='type'>
51                <option value='Main'>Injected</option>
52                <option value='Side'>Mod</option>
53            </select>
54            <select name='compatibility'>
55                <option value='With Most Other Clients'>With Most Other Clients</option>
56                <option value='Stand Alone'>Stand Alone</option>
57            </select>
58            <div className='client-warning'><div className='safe-status-red'><div className='code'>⚠ WARNING ⚠</div></div> Only download clients you know are <div className='code'>100%</div> safe! If we do find a client that is a <div className='code'>rat / virus / BTC miner</div> we will tag it as <div className='safe-status-red'><div className='code'>UNSAFE IMMEDIATELY</div></div>. The saftey warnings for clients are <div className='code'>MERE RECCOMENDATIONS</div>, please do thorough research before downloading any hacked client that you are not <div className='code'>100%</div> sure is safe. This page is also in <div className='code'>development</div>, meaning features are prone to break! So be careful!!!</div>
59            <div className='code'>Sponsored clients</div>
60                <h1>None XD</h1>
61            <div className='code'>Submitted clients</div>
62                {client
63                    **Filtering the array then mapping it -> (This i want to do onClick)** .filter((client) => client.name === search.searchname)
64                    .map((client, index) => {
65                        return (
66                            <Client
67                                safestatus={client.safestatus}
68                                safe={client.safe}
69                                name={client.name}
70                                price={client.price}
71                                mcversion={client.mcversion}
72                                type={client.type}
73                                compat={client.compat}
74                                desc={client.desc}
75                                screen={client.screen}
76                                download={client.download}
77                            />
78                        );
79                    })}
80            </div>
81    </body>
82  );
83}
84
85export default App;
86const [ searchValue, setSearchValue ] = React.useState("")
87const [ searchTerm, setSearchTerm ] = React.useState("")
88
89const filteredClient = React.useMemo(() => {
90  if (searchTerm.length > 0) {
91    return client.filter(({ name }) => name === searchTerm)
92  }
93  return client
94}, [ searchTerm, client ])
95<input
96  name="searchname"
97  placeholder="Search"
98  value={searchValue}
99  onChange={e => setSearchValue(e.target.value)}
100/>
101
102<!-- snip -->
103
104<button
105  type="button"
106  onClick={() => setSearchTerm(searchValue)}
107>Search</button>
108
109<!-- snip -->
110
111{filteredClient.map((client, index) => (
112  <Client .../>
113))}
114

Source https://stackoverflow.com/questions/69457630

Community Discussions contain sources that include Stack Exchange Network

Tutorials and Learning Resources in Minecraft

Share this Page

share link

Get latest updates on Minecraft