mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 01:04:24 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ec8685098 | ||
|
|
f375683bcd | ||
|
|
9cd61b99f1 | ||
|
|
ad5ca0b67d | ||
|
|
b76746e62f | ||
|
|
4cfa1f83c4 | ||
|
|
da7e5f8bfa | ||
|
|
cd8eccc29c |
No files matched your search
@@ -0,0 +1,18 @@
|
||||
plugins {
|
||||
id 'net.minecraftforge.forge.build.convention'
|
||||
id 'jvm-test-suite'
|
||||
}
|
||||
|
||||
gradleutils.displayName = 'FMLLoader-Tests'
|
||||
description = 'JUnit tests for FMLLoader, not meant for distribution'
|
||||
|
||||
dependencies {
|
||||
testImplementation(project(':fmlloader'))
|
||||
testImplementation(libs.guava)
|
||||
testImplementation(libs.junit.api)
|
||||
testRuntimeOnly(libs.bundles.junit.runtime)
|
||||
}
|
||||
|
||||
tasks.named('test') {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) Forge Development LLC and contributors
|
||||
* SPDX-License-Identifier: LGPL-2.1-only
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.loading.test;
|
||||
|
||||
import com.google.common.graph.Graph;
|
||||
import com.google.common.graph.GraphBuilder;
|
||||
import com.google.common.graph.MutableGraph;
|
||||
|
||||
import net.minecraftforge.fml.loading.toposort.CyclePresentException;
|
||||
import net.minecraftforge.fml.loading.toposort.StronglyConnectedComponentDetector;
|
||||
import net.minecraftforge.fml.loading.toposort.TopologicalSort;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Tests for {@link TopologicalSort} and {@link StronglyConnectedComponentDetector}
|
||||
*/
|
||||
class TopologicalSortTest {
|
||||
@Test
|
||||
void resultProperlySorted() {
|
||||
MutableGraph<String> graph = GraphBuilder.directed().build();
|
||||
graph.putEdge("a", "b");
|
||||
graph.putEdge("a", "c");
|
||||
graph.putEdge("b", "c");
|
||||
var sorted = TopologicalSort.topologicalSort(graph, Comparator.naturalOrder());
|
||||
assertEquals(List.of("a", "b", "c"), sorted);
|
||||
}
|
||||
|
||||
@Test
|
||||
void throwsOnCycle() {
|
||||
MutableGraph<String> graph = GraphBuilder.directed().build();
|
||||
graph.putEdge("a", "b");
|
||||
graph.putEdge("b", "a");
|
||||
|
||||
var exception = Assertions.assertThrows(CyclePresentException.class, () -> TopologicalSort.topologicalSort(graph, Comparator.naturalOrder()));
|
||||
assertEquals(Set.of(
|
||||
Set.of("a", "b")
|
||||
), exception.getCycles());
|
||||
}
|
||||
|
||||
@Test
|
||||
void simpleCycle() {
|
||||
MutableGraph<String> graph = GraphBuilder.directed().build();
|
||||
// a -> b -> c -> a
|
||||
graph.putEdge("a", "b");
|
||||
graph.putEdge("b", "c");
|
||||
graph.putEdge("c", "a");
|
||||
|
||||
var cycles = cyclesOf(graph);
|
||||
assertEquals(Set.of(
|
||||
Set.of("a", "b", "c")
|
||||
), cycles);
|
||||
}
|
||||
|
||||
@Test
|
||||
void noCycle() {
|
||||
MutableGraph<String> graph = GraphBuilder.directed().build();
|
||||
graph.putEdge("a", "b");
|
||||
graph.putEdge("a", "c");
|
||||
graph.putEdge("b", "d");
|
||||
graph.putEdge("c", "d");
|
||||
graph.putEdge("d", "e");
|
||||
|
||||
var cycles = cyclesOf(graph);
|
||||
assertTrue(cycles.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Regression test: the previous implementation lowered the lowlink of a node from every already-visited
|
||||
* successor, including successors whose component was already completed. That merged nodes into the wrong
|
||||
* component, so a member of the real cycle ({@code c}) was missing from the reported cycle.
|
||||
*/
|
||||
@Test
|
||||
void reportsAllMembersOfCycle() {
|
||||
MutableGraph<String> graph = GraphBuilder.directed().build();
|
||||
graph.addNode("a");
|
||||
graph.addNode("b");
|
||||
graph.addNode("c");
|
||||
graph.putEdge("a", "b");
|
||||
graph.putEdge("a", "c");
|
||||
graph.putEdge("b", "a");
|
||||
graph.putEdge("c", "b");
|
||||
|
||||
var cycles = cyclesOf(graph);
|
||||
assertEquals(Set.of(
|
||||
Set.of("a", "b", "c")
|
||||
), cycles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Regression test: the previous implementation invented a cycle out of {@code c -> d -> a}, which is a plain
|
||||
* path, because it compared against the DFS depth instead of a discovery counter and ignored whether a
|
||||
* successor was still on the stack.
|
||||
*/
|
||||
@Test
|
||||
void doesNotInventCycles() {
|
||||
MutableGraph<String> graph = GraphBuilder.directed().build();
|
||||
graph.addNode("a");
|
||||
graph.addNode("b");
|
||||
graph.addNode("c");
|
||||
graph.addNode("d");
|
||||
graph.putEdge("a", "b");
|
||||
graph.putEdge("b", "a");
|
||||
graph.putEdge("c", "d");
|
||||
graph.putEdge("d", "a");
|
||||
|
||||
var cycles = cyclesOf(graph);
|
||||
assertEquals(Set.of(
|
||||
Set.of("a", "b")
|
||||
), cycles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reproduces the shape of the mod graphs that reported bogus cycles in the wild: one real three-node cycle,
|
||||
* with nodes that merely depend on members of the cycle and a node on a plain path into it.
|
||||
*
|
||||
* <p>Every reported component must be the real cycle itself; nodes such as {@code dependent_a} only depend on
|
||||
* the cycle and must not be reported.
|
||||
*
|
||||
* @see <a href="https://github.com/MinecraftForge/MinecraftForge/pull/10924">related GitHub issue</a>
|
||||
*/
|
||||
@Test
|
||||
void reportsOnlyRealCycles() {
|
||||
MutableGraph<String> graph = GraphBuilder.directed().build();
|
||||
// Mirrors the insertion order of ModSorter: every mod is added as a node first, edges are added afterwards.
|
||||
for (String mod : List.of("upstream", "cycle_a", "cycle_b", "dependent_a", "cycle_c", "dependent_b")) {
|
||||
graph.addNode(mod);
|
||||
}
|
||||
// a -> b -> a
|
||||
graph.putEdge("cycle_a", "cycle_b");
|
||||
graph.putEdge("cycle_b", "cycle_a");
|
||||
// a -> c -> b -> a
|
||||
graph.putEdge("cycle_a", "cycle_c");
|
||||
graph.putEdge("cycle_c", "cycle_b");
|
||||
// dA -> b -> a - Valid
|
||||
graph.putEdge("dependent_a", "cycle_b");
|
||||
// dB -> b -> a - Valid
|
||||
graph.putEdge("dependent_b", "cycle_b");
|
||||
// u -> a -> b -> a - Not valid, but u is not part of the cycle so shouldn't be reported
|
||||
graph.putEdge("upstream", "cycle_a");
|
||||
|
||||
var cycles = cyclesOf(graph);
|
||||
assertEquals(Set.of(
|
||||
Set.of("cycle_a", "cycle_b", "cycle_c")
|
||||
), cycles);
|
||||
|
||||
var exception = Assertions.assertThrows(CyclePresentException.class, () -> TopologicalSort.topologicalSort(graph, Comparator.naturalOrder()));
|
||||
assertEquals(Set.of(
|
||||
Set.of("cycle_a", "cycle_b", "cycle_c")
|
||||
), exception.getCycles());
|
||||
}
|
||||
|
||||
private static Set<Set<String>> cyclesOf(Graph<String> graph) {
|
||||
var detector = new StronglyConnectedComponentDetector<>(graph);
|
||||
var connected = detector.getComponents();
|
||||
var cycles = new HashSet<>(connected);
|
||||
cycles.removeIf(component -> component.size() < 2);
|
||||
return cycles;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import net.minecraftforge.forgedev.legacy.tasks.JarJarMetadataOptions
|
||||
import org.gradle.api.plugins.jvm.JvmTestSuite
|
||||
|
||||
plugins {
|
||||
id 'jvm-test-suite'
|
||||
id 'net.minecraftforge.forge.build.convention'
|
||||
alias libs.plugins.apt
|
||||
}
|
||||
@@ -38,13 +36,6 @@ dependencies {
|
||||
annotationProcessor(libs.bundles.log4j){ transitive = false }
|
||||
}
|
||||
|
||||
testing.suites.named('test', JvmTestSuite) {
|
||||
dependencies {
|
||||
compileOnly libs.jetbrains.annotations
|
||||
runtimeOnly libs.bootstrap
|
||||
}
|
||||
}
|
||||
|
||||
convention.manifest('net/minecraftforge/fml/loading/', [
|
||||
'Automatic-Module-Name': 'net.minecraftforge.fmlloader',
|
||||
'Forge-Module-Layer' : 'boot'
|
||||
|
||||
+26
-28
@@ -22,15 +22,18 @@ import java.util.Set;
|
||||
*
|
||||
* <p>This detector evaluates the graph lazily and won't reflect the modifications in the
|
||||
* graph after initial evaluation.
|
||||
*
|
||||
* <p> Implementation based on <a href="https://en.wikipedia.org/w/index.php?title=Tarjan%27s_strongly_connected_components_algorithm&oldid=1384955226">Wikipedia Psudocode</a>
|
||||
*/
|
||||
public class StronglyConnectedComponentDetector<T> {
|
||||
private final Graph<T> graph;
|
||||
private final Map<T, Integer> ids = new HashMap<>();
|
||||
private T[] elements;
|
||||
private int[] dfn;
|
||||
private int[] low;
|
||||
private int[] indexes;
|
||||
private int[] lowlinks;
|
||||
private int[] stack;
|
||||
private int top;
|
||||
private int index;
|
||||
private BitSet onStack;
|
||||
private Set<Set<T>> components;
|
||||
|
||||
@@ -58,48 +61,43 @@ public class StronglyConnectedComponentDetector<T> {
|
||||
}
|
||||
|
||||
final int n = nodes.size();
|
||||
dfn = new int[n];
|
||||
low = new int[n];
|
||||
indexes = new int[n];
|
||||
lowlinks = new int[n];
|
||||
stack = new int[n];
|
||||
onStack = new BitSet(n);
|
||||
top = -1;
|
||||
index = 1;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (dfn[i] == 0) {
|
||||
dfs(i, 1);
|
||||
}
|
||||
if (indexes[i] == 0)
|
||||
dfs(i);
|
||||
}
|
||||
}
|
||||
|
||||
private void dfs(int now, int depth) {
|
||||
dfn[now] = depth;
|
||||
low[now] = depth;
|
||||
top++;
|
||||
stack[top] = now;
|
||||
private void dfs(int now) {
|
||||
indexes[now] = lowlinks[now] = index++;
|
||||
stack[++top] = now;
|
||||
onStack.set(now);
|
||||
|
||||
for (T each : graph.successors(elements[now])) {
|
||||
int to = ids.get(each);
|
||||
if (dfn[to] != 0) {
|
||||
if (low[now] > dfn[to]) {
|
||||
low[now] = dfn[to];
|
||||
}
|
||||
} else {
|
||||
dfs(to, depth + 1);
|
||||
if (low[now] > low[to]) {
|
||||
low[now] = low[to];
|
||||
}
|
||||
if (indexes[to] == 0) { // 0 is unvisited
|
||||
dfs(to);
|
||||
if (lowlinks[now] > lowlinks[to])
|
||||
lowlinks[now] = lowlinks[to];
|
||||
} else if (onStack.get(to)) {
|
||||
if (lowlinks[now] > indexes[to])
|
||||
lowlinks[now] = indexes[to];
|
||||
}
|
||||
}
|
||||
|
||||
if (dfn[now] == low[now]) {
|
||||
if (indexes[now] == lowlinks[now]) {
|
||||
Set<T> component = new HashSet<>();
|
||||
while (top >= 0) {
|
||||
final int t = stack[top];
|
||||
component.add(elements[t]);
|
||||
onStack.clear(t);
|
||||
top--;
|
||||
if (t == now) {
|
||||
final int w = stack[top--];
|
||||
onStack.clear(w);
|
||||
component.add(elements[w]);
|
||||
if (w == now)
|
||||
break;
|
||||
}
|
||||
}
|
||||
components.add(component);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ jarjar = "0.4.2"
|
||||
log4j = "2.26.0"
|
||||
lwjgl = "3.4.3"
|
||||
gradle = "9.7.1" # Gradle we bundle with the MDK
|
||||
junit = "6.1.3"
|
||||
|
||||
[libraries]
|
||||
# TODO [Forge][Buildscript We should not be needing to manually add transitive dependencies
|
||||
@@ -106,6 +107,12 @@ lwjgl-opengl = { module = "org.lwjgl:lwjgl-opengl", version.ref = "lwjgl" }
|
||||
lwjgl-stb = { module = "org.lwjgl:lwjgl-stb", version.ref = "lwjgl" }
|
||||
lwjgl-tinyfd = { module = "org.lwjgl:lwjgl-tinyfd", version.ref = "lwjgl" }
|
||||
|
||||
|
||||
junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" }
|
||||
junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
|
||||
junit-platform = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit" }
|
||||
|
||||
|
||||
[bundles]
|
||||
# Google's InMemory File System. Used by ForgeDev Tests for now, but could be useful for a lot of things.
|
||||
jimfs = ["guava", "failureaccess"]
|
||||
@@ -123,3 +130,4 @@ night-config = ["night-config-toml", "night-config-core"]
|
||||
jarjar = ["jarjar-fs", "jarjar-selector", "jarjar-meta"]
|
||||
log4j = ["log4j-api", "log4j-core"]
|
||||
lwjgl = ["lwjgl", "lwjgl-sdl", "lwjgl-opengl", "lwjgl-stb", "lwjgl-tinyfd"]
|
||||
junit-runtime = ["junit-engine", "junit-platform"]
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
--- a/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java
|
||||
+++ b/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java
|
||||
@@ -63,7 +_,9 @@
|
||||
}
|
||||
|
||||
Vec3 oldPos = user.position();
|
||||
- if (user.randomTeleport(xx, yy, zz, true, BlockTags.CONSUMABLE_DOES_NOT_TELEPORT_TO)) {
|
||||
+ var event = net.minecraftforge.event.ForgeEventFactory.onChorusFruitTeleport(user, xx, yy, zz);
|
||||
+ if (event == null) return false;
|
||||
+ if (user.randomTeleport(event.getTargetX(), event.getTargetY(), event.getTargetZ(), true, BlockTags.CONSUMABLE_DOES_NOT_TELEPORT_TO)) {
|
||||
level.gameEvent(GameEvent.TELEPORT, oldPos, GameEvent.Context.of(user));
|
||||
SoundSource soundSource;
|
||||
SoundEvent soundEvent;
|
||||
@@ -18,6 +18,7 @@ plugins {
|
||||
rootProject.name = 'forge'
|
||||
|
||||
include 'fmlloader'
|
||||
include 'fmlloader-tests'
|
||||
include 'fmlcore'
|
||||
include 'mclanguage'
|
||||
include 'javafmllanguage'
|
||||
|
||||
@@ -7,6 +7,10 @@ package net.minecraftforge.client;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
/// @deprecated This class is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
/// Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
/// We may keep it or add it back in a future version if there is enough demand.
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public final class StencilManager
|
||||
{
|
||||
private static final BitSet BITS = new BitSet(8);
|
||||
|
||||
@@ -13,7 +13,12 @@ import java.util.Set;
|
||||
/**
|
||||
* Fired when an Atlas is being loaded.
|
||||
* This allows you to add custom metadata sections that will be loaded from the sprite's .mcmeta file.
|
||||
*
|
||||
* @deprecated This event is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
* Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
* We may keep it or add it back in a future version if there is enough demand.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public final class GatherAtlasMetadataSectionsEvent extends MutableEvent {
|
||||
public static final EventBus<GatherAtlasMetadataSectionsEvent> BUS = EventBus.create(GatherAtlasMetadataSectionsEvent.class);
|
||||
|
||||
@@ -26,4 +31,4 @@ public final class GatherAtlasMetadataSectionsEvent extends MutableEvent {
|
||||
public void addType(MetadataSectionType<?> definition) {
|
||||
this.types.add(definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -10,9 +10,12 @@ import com.mojang.math.Transformation;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
/**
|
||||
* Vertex pipeline element that applies a transformation to incoming geometry.
|
||||
*/
|
||||
/// Vertex pipeline element that applies a transformation to incoming geometry.
|
||||
///
|
||||
/// @deprecated This class is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
/// Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
/// We may keep it or add it back in a future version if there is enough demand.
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public class TransformingVertexPipeline extends VertexConsumerWrapper
|
||||
{
|
||||
private final Transformation transformation;
|
||||
|
||||
@@ -11,7 +11,12 @@ import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
* Wrapper for {@link VertexConsumer} which delegates all operations to its parent.
|
||||
* <p>
|
||||
* Useful for defining custom pipeline elements that only process certain data.
|
||||
*
|
||||
* @deprecated This class is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
* Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
* We may keep it or add it back in a future version if there is enough demand.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public class VertexConsumerWrapper implements VertexConsumer {
|
||||
protected final VertexConsumer parent;
|
||||
|
||||
|
||||
@@ -14,19 +14,21 @@ import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* A small helper class to aid Forge modders in migrating from EventBus 6 to the new EventBus 7.
|
||||
* <p>
|
||||
* Refer to the <a href="https://gist.github.com/PaintNinja/ad82c224aecee25efac1ea3e2cf19b91">migration guide</a>
|
||||
* mentioned in the <a href="https://files.minecraftforge.net">Forge 1.21.6 changelog</a> or
|
||||
* <a href="https://forums.minecraftforge.net/topic/159525-forge-581-minecraft-1218/">1.21.8 announcement</a> on the
|
||||
* forums, or ask in <a href="https://discord.minecraftforge.net">the Forge Discord</a> for help with migrating your mod
|
||||
* to the new system.
|
||||
* </p>
|
||||
* <p>
|
||||
* You can also check the updated example code in <a href="https://files.minecraftforge.net">the MDK</a> for the MC
|
||||
* version you're using.
|
||||
*/
|
||||
/// A small helper class to aid Forge modders in migrating from EventBus 6 to the new EventBus 7.
|
||||
///
|
||||
/// Refer to the [migration guide](https://gist.github.com/PaintNinja/ad82c224aecee25efac1ea3e2cf19b91)
|
||||
/// mentioned in the [Forge 1.21.6 changelog](https://files.minecraftforge.net) or
|
||||
/// [1.21.8 announcement](https://forums.minecraftforge.net/topic/159525-forge-581-minecraft-1218/) on the
|
||||
/// forums, or ask in [the Forge Discord](https://discord.minecraftforge.net) for help with migrating your mod
|
||||
/// to the new system.
|
||||
///
|
||||
/// You can also check the updated example code in [the MDK](https://files.minecraftforge.net) for the MC
|
||||
/// version you're using.
|
||||
///
|
||||
/// @deprecated This was intended as a temporary solution to help modders migrate to the new event system. It relies on
|
||||
/// JDK internals that may break without notice and will be removed in 26.4.
|
||||
/// Replace `MinecraftForge.EVENT_BUS.register(...)` with `BusGroup.DEFAULT.register(MethodHandles.lookup(), ...)`.
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public final class EventBusMigrationHelper {
|
||||
public static final EventBusMigrationHelper INSTANCE = new EventBusMigrationHelper(BusGroup.DEFAULT);
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ public class ForgeConfig {
|
||||
"A sane default is 1KB (1024), but may need to be expanded for larger modpacks.",
|
||||
"Forge will auto-adjust this if mods register their channels using our channel manager."
|
||||
)
|
||||
.translation("forge.configui.channellistlimit")
|
||||
.translation("forge.configgui.channellistlimit")
|
||||
.defineInRange("channelListLimit", 1024, 1, Long.MAX_VALUE);
|
||||
|
||||
builder.pop();
|
||||
|
||||
@@ -39,7 +39,12 @@ public class MinecraftForge {
|
||||
* <p>Events marked with {@link IModBusEvent} belong on the
|
||||
* {@linkplain FMLJavaModLoadingContext#getModBusGroup() mod BusGroup} and not on the
|
||||
* {@linkplain BusGroup#DEFAULT default BusGroup}.</p>
|
||||
*
|
||||
* @deprecated This was intended as a temporary solution to help modders migrate to the new event system.
|
||||
* It relies on JDK internals that may break without notice and will be removed in 26.4.
|
||||
* Replace `MinecraftForge.EVENT_BUS.register(...)` with `BusGroup.DEFAULT.register(MethodHandles.lookup(), ...)`.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public static final EventBusMigrationHelper EVENT_BUS = EventBusMigrationHelper.INSTANCE;
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
@@ -36,9 +36,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
* last known username.<br>
|
||||
* For convenience, {@link #getMap()} is provided to get an immutable copy of
|
||||
* the caches underlying map.
|
||||
*
|
||||
* @deprecated This class is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
* Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
* We may keep it or add it back in a future version if there is enough demand.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public final class UsernameCache {
|
||||
private static Map<UUID, String> map = new HashMap<>();
|
||||
private static HashMap<UUID, String> map = new HashMap<>();
|
||||
|
||||
private static final Path saveFile = FMLLoader.getGamePath().resolve("usernamecache.json");
|
||||
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package net.minecraftforge.common.extensions;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
@@ -23,6 +24,8 @@ import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraftforge.eventbus.api.bus.BusGroup;
|
||||
import net.minecraftforge.unsafe.UnsafeHacks;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
@@ -205,8 +208,21 @@ public interface IForgeGameTestHelper {
|
||||
* Registers an event listener that will be unregistered when the test is finished running.
|
||||
*/
|
||||
default void registerEventListener(Object handler) {
|
||||
var keys = MinecraftForge.EVENT_BUS.register(handler);
|
||||
self().addCleanup(_ -> MinecraftForge.EVENT_BUS.unregister(keys));
|
||||
final class JdkInternalLookup {
|
||||
private JdkInternalLookup() {}
|
||||
private static final MethodHandles.Lookup INSTANCE;
|
||||
static {
|
||||
try {
|
||||
var lookupField = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
|
||||
UnsafeHacks.setAccessible(lookupField);
|
||||
INSTANCE = (MethodHandles.Lookup) lookupField.get(null);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
var keys = BusGroup.DEFAULT.register(JdkInternalLookup.INSTANCE, handler);
|
||||
self().addCleanup(_ -> BusGroup.DEFAULT.unregister(keys));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,10 @@ import net.minecraft.client.renderer.block.dispatch.ModelState;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
|
||||
/// @deprecated This class is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
/// Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
/// We may keep it or add it back in a future version if there is enough demand.
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public class Properties {
|
||||
/**
|
||||
* Property indicating if the model should be rendered in the static renderer or in the TESR. AnimationTESR sets it to false.
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.jspecify.annotations.Nullable;
|
||||
* </ul>
|
||||
* Of course, nothing egregious will happen should a modder choose to use them for their own purposes.<br>
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public class BrainBuilder<E extends LivingEntity> {
|
||||
private final Collection<MemoryModuleType<?>> memoryTypes = new HashSet<>();
|
||||
private final Collection<SensorType<? extends Sensor<? super E>>> sensorTypes = new HashSet<>();
|
||||
|
||||
@@ -8,8 +8,15 @@ package net.minecraftforge.common.util;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
// Sorter to load nearby chunks first
|
||||
public class CenterChunkPosComparator implements java.util.Comparator<ChunkPos> {
|
||||
|
||||
/// @deprecated This class is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
/// Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
/// We may keep it or add it back in a future version if there is enough demand.
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public class CenterChunkPosComparator implements Comparator<ChunkPos> {
|
||||
private final int x;
|
||||
private final int z;
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ package net.minecraftforge.common.util;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Utility class for creating a nice human readable dump of binary data.
|
||||
*
|
||||
@@ -42,7 +44,7 @@ public class HexDumper {
|
||||
return inst.finish();
|
||||
}
|
||||
|
||||
private static class Instance {
|
||||
private static final class Instance {
|
||||
private static final String HEX = "0123456789ABCDEF";
|
||||
private final int marked;
|
||||
private final StringBuilder buf;
|
||||
@@ -57,8 +59,7 @@ public class HexDumper {
|
||||
+ (lines * 2) // \t and \n per line
|
||||
+ (marked == -1 ? 0 : lines)); // ' ' or < at the start of each line
|
||||
|
||||
for (int x = 0; x < ascii.length; x++)
|
||||
ascii[x] = ' ';
|
||||
Arrays.fill(ascii, ' ');
|
||||
}
|
||||
|
||||
public void add(byte data) {
|
||||
|
||||
@@ -12,6 +12,10 @@ import net.minecraft.world.item.ItemStackLinkedSet;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/// @deprecated This class is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
/// Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
/// We may keep it or add it back in a future version if there is enough demand.
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public class ItemStackMap {
|
||||
|
||||
public static <V> Map<ItemStack, V> createTypeAndTagLinkedMap() {
|
||||
|
||||
@@ -29,6 +29,10 @@ import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/// @deprecated This class is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
/// Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
/// We may keep it or add it back in a future version if there is enough demand.
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public class JsonUtils {
|
||||
// http://stackoverflow.com/questions/7706772/deserializing-immutablelist-using-gson/21677349#21677349
|
||||
public enum ImmutableListTypeAdapter implements JsonDeserializer<ImmutableList<?>>, JsonSerializer<ImmutableList<?>> {
|
||||
|
||||
@@ -15,9 +15,12 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Utility to format data into a textual (markdown-compliant) table.
|
||||
*/
|
||||
/// Utility to format data into a textual (markdown-compliant) table.
|
||||
///
|
||||
/// @deprecated This class is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
/// Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
/// We may keep it or add it back in a future version if there is enough demand.
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public class TextTable
|
||||
{
|
||||
public static Column column(String header)
|
||||
|
||||
@@ -705,8 +705,9 @@ public final class ForgeEventFactory {
|
||||
return EntityTeleportEvent.EnderPearl.BUS.post(event) ? null : event;
|
||||
}
|
||||
|
||||
public static EntityTeleportEvent.ChorusFruit onChorusFruitTeleport(LivingEntity entity, double targetX, double targetY, double targetZ) {
|
||||
return EntityTeleportEvent.ChorusFruit.BUS.fire(new EntityTeleportEvent.ChorusFruit(entity, targetX, targetY, targetZ));
|
||||
public static EntityTeleportEvent.@Nullable ChorusFruit onChorusFruitTeleport(LivingEntity entity, double targetX, double targetY, double targetZ) {
|
||||
var event = new EntityTeleportEvent.ChorusFruit(entity, targetX, targetY, targetZ);
|
||||
return EntityTeleportEvent.ChorusFruit.BUS.post(event) ? null : event;
|
||||
}
|
||||
|
||||
public static boolean onPermissionChanged(NameAndId gameProfile, @Nullable LevelBasedPermissionSet newLevel, PlayerList playerList) {
|
||||
|
||||
@@ -93,7 +93,12 @@ public sealed abstract class EntityTeleportEvent implements Cancellable, EntityE
|
||||
* This event is {@linkplain Cancellable cancelable}. If the event is cancelled, the entity will not be teleported.
|
||||
* <br>
|
||||
* This event is only fired on the {@link LogicalSide#SERVER} side.
|
||||
*
|
||||
* @deprecated This event is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
* Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
* We may keep it or add it back in a future version if there is enough demand.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public static final class EntityRandom extends EntityTeleportEvent {
|
||||
public static final CancellableEventBus<EntityRandom> BUS = CancellableEventBus.create(EntityRandom.class);
|
||||
|
||||
|
||||
@@ -24,7 +24,12 @@ import net.minecraftforge.eventbus.api.event.MutableEvent;
|
||||
* and replace the previously created Brain instance for the entity.<br>
|
||||
* <br>
|
||||
* This event is fired via the {@link ForgeHooks#onLivingMakeBrain(LivingEntity, Brain, Dynamic)}.<br>
|
||||
*
|
||||
* @deprecated This event is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
* Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
* We may keep it or add it back in a future version if there is enough demand.
|
||||
**/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public final class LivingMakeBrainEvent extends MutableEvent implements LivingEvent {
|
||||
public static final EventBus<LivingMakeBrainEvent> BUS = EventBus.create(LivingMakeBrainEvent.class);
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@ import net.minecraftforge.eventbus.api.bus.EventBus;
|
||||
import net.minecraftforge.eventbus.api.event.MutableEvent;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/// @deprecated This event is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
/// Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
/// We may keep it or add it back in a future version if there is enough demand.
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
@NullMarked
|
||||
public final class LivingPackSizeEvent extends MutableEvent implements LivingEvent, HasResult {
|
||||
public static final EventBus<LivingPackSizeEvent> BUS = EventBus.create(LivingPackSizeEvent.class);
|
||||
|
||||
@@ -7,20 +7,25 @@ package net.minecraftforge.event.entity.living;
|
||||
|
||||
import net.minecraft.world.entity.monster.Monster;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraftforge.common.extensions.IForgeItem;
|
||||
import net.minecraftforge.common.extensions.IForgeItemStack;
|
||||
import net.minecraftforge.eventbus.api.bus.CancellableEventBus;
|
||||
import net.minecraftforge.eventbus.api.event.RecordEvent;
|
||||
import net.minecraftforge.eventbus.api.event.characteristic.Cancellable;
|
||||
|
||||
/**
|
||||
* This event is fired on the forge bus before an Monster detects that a player is looking at them.
|
||||
* It will not be fired if the detection is already prevented by {@link IForgeItem#isEnderMask}
|
||||
* It will not be fired if the detection is already prevented by {@link IForgeItemStack#isMonsterDisguise(Player, Monster)}
|
||||
* <p>
|
||||
* This event is {@linkplain Cancellable cancellable}.
|
||||
* If this event is cancelled, the Monster will not target the player.
|
||||
*
|
||||
* @param getPlayer The player that is being checked.
|
||||
*
|
||||
* @deprecated This event is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
* Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
* We may keep it or add it back in a future version if there is enough demand.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public record MonsterDisguiseEvent(Monster getEntity, Player getPlayer) implements Cancellable, LivingEvent, RecordEvent {
|
||||
public static final CancellableEventBus<MonsterDisguiseEvent> BUS = CancellableEventBus.create(MonsterDisguiseEvent.class);
|
||||
}
|
||||
@@ -54,7 +54,12 @@ public sealed abstract class ZombieEvent implements EntityEvent, InheritableEven
|
||||
* <li>{@link Result#ALLOW} Zombie is summoned.</li>
|
||||
* <li>{@link Result#DENY} Zombie is not summoned.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @deprecated This event is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
* Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
* We may keep it or add it back in a future version if there is enough demand.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public static final class SummonAidEvent extends ZombieEvent implements HasResult {
|
||||
public static final EventBus<SummonAidEvent> BUS = EventBus.create(SummonAidEvent.class);
|
||||
|
||||
|
||||
@@ -22,7 +22,12 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
* This event is not {@linkplain Cancellable cancellable}.
|
||||
* <p>
|
||||
* This event is fired only on the {@linkplain net.minecraftforge.fml.LogicalSide#SERVER logical server}.
|
||||
*
|
||||
* @deprecated This event is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
* Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
* We may keep it or add it back in a future version if there is enough demand.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public final class AlterGroundEvent extends MutableEvent {
|
||||
public static final EventBus<AlterGroundEvent> BUS = EventBus.create(AlterGroundEvent.class);
|
||||
|
||||
|
||||
@@ -27,7 +27,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
* {@linkplain Result#DENY DENY} will prevent the sapling from growing.
|
||||
* <p>
|
||||
* This event is fired only on the {@linkplain net.minecraftforge.fml.LogicalSide#SERVER logical server}.
|
||||
*
|
||||
* @deprecated This event is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
* Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
* We may keep it or add it back in a future version if there is enough demand.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public final class BlockFeatureGrowEvent implements LevelEvent, HasResult {
|
||||
public static final EventBus<BlockFeatureGrowEvent> BUS = EventBus.create(BlockFeatureGrowEvent.class);
|
||||
|
||||
|
||||
@@ -68,7 +68,12 @@ public sealed interface ChunkEvent extends LevelEvent
|
||||
* the ChunkAccess isLightCorrect to true.<br>
|
||||
* <br>
|
||||
* The game test for this event is lighting_event_test in net.minecraftforge.debug.chunk<br>
|
||||
*
|
||||
* @deprecated This event is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
* Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
* We may keep it or add it back in a future version if there is enough demand.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
record LightingCalculated(ChunkAccess getChunk) implements ChunkEvent {
|
||||
public static final EventBus<ChunkEvent.LightingCalculated> BUS = EventBus.create(ChunkEvent.LightingCalculated.class);
|
||||
}
|
||||
|
||||
@@ -31,8 +31,13 @@ import org.jspecify.annotations.NullMarked;
|
||||
* @param getOldTicketLevel the previous ticket level the chunk had
|
||||
* @param getNewTicketLevel the new ticket level the chunk has
|
||||
* @param getChunkHolder the chunk that had its ticket level updated, may be null
|
||||
*
|
||||
* @deprecated This event is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
* Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
* We may keep it or add it back in a future version if there is enough demand.
|
||||
*/
|
||||
@NullMarked
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public record ChunkTicketLevelUpdatedEvent(
|
||||
ServerLevel getLevel,
|
||||
long getChunkPos,
|
||||
|
||||
@@ -14,6 +14,10 @@ import net.minecraftforge.network.ConnectionType;
|
||||
import net.minecraftforge.network.NetworkContext;
|
||||
import java.util.Locale;
|
||||
|
||||
/// @deprecated This class is scheduled for removal in 26.4 due to a lack of adoption by mods, in order to ease porting.
|
||||
/// Please reach out to the Forge team if you are relying on this and would like to see it remain in Forge.
|
||||
/// We may keep it or add it back in a future version if there is enough demand.
|
||||
@Deprecated(forRemoval = true, since = "26.4")
|
||||
public class TextComponentHelper {
|
||||
private TextComponentHelper() {}
|
||||
|
||||
|
||||
@@ -150,6 +150,10 @@
|
||||
"forge.configgui.removeErroringBlockEntities": "Remove Erroring Block Entities",
|
||||
"forge.configgui.fullBoundingBoxLadders.tooltip": "Set this to true to check the entire entity's collision bounding box for ladders instead of just the block they are in. Causes noticeable differences in mechanics so default is vanilla behavior. Default: false.",
|
||||
"forge.configgui.fullBoundingBoxLadders": "Full Bounding Box Ladders",
|
||||
"forge.configgui.permissionHandler.tooltip": "The permission handler used by the server. Defaults to forge:default_handler if no such handler with that name is registered.",
|
||||
"forge.configgui.permissionHandler": "Permission Handler",
|
||||
"forge.configgui.advertiseDedicatedServerToLan.tooltip": "Set this to true to enable advertising the dedicated server to local LAN clients so that it shows up in the Multiplayer screen automatically.",
|
||||
"forge.configgui.advertiseDedicatedServerToLan": "Advertise Dedicated Server to LAN",
|
||||
"forge.configgui.zombieBaseSummonChance.tooltip": "Base zombie summoning spawn chance. Allows changing the bonus zombie summoning mechanic.",
|
||||
"forge.configgui.zombieBaseSummonChance": "Zombie Summon Chance",
|
||||
"forge.configgui.zombieBabyChance.tooltip": "Chance that a zombie (or subclass) is a baby. Allows changing the zombie spawning mechanic.",
|
||||
@@ -202,6 +206,8 @@
|
||||
|
||||
"forge.configgui.channellistlimit": "Channel List Size Limit",
|
||||
"forge.configgui.channellistlimit.tooltip": "Maximum size to use to store the channel list for a network connection. Some malicious actors may use this to use up all your memory. A sane default is 1KB (1024), but may need to be expanded for larger modpacks.",
|
||||
"forge.configgui.migrationHelperMode": "Migration Helper Mode",
|
||||
"forge.configgui.migrationHelperMode.tooltip": "A config option to help developers find known legacy modded tags that have common convention equivalents when running on integrated server. Defaults to OFF.",
|
||||
"forge.server.channellistlimit.kick": "Received too many networking channels",
|
||||
|
||||
"forge.controlsgui.shift": "SHIFT + %s",
|
||||
|
||||
Reference in new issue
Block a user