Fix up all the things. Removed SidedProvider because it served no real purpose anymore.

Signed-off-by: cpw <cpw+github@weeksfamily.ca>
This commit is contained in:
cpw 2020-08-31 21:00:44 -04:00
parent 16b82bb97b
commit 2e42340dfa
No known key found for this signature in database
GPG Key ID: 8EB3DF749553B1B7
20 changed files with 282 additions and 204 deletions

View File

@ -16,7 +16,7 @@
this.field_71459_aj = p_i45547_1_.field_178741_d.field_178756_a;
this.field_238175_ae_ = !p_i45547_1_.field_178741_d.field_239099_d_;
this.field_238176_af_ = !p_i45547_1_.field_178741_d.field_239100_e_;
@@ -416,14 +416,15 @@
@@ -416,13 +416,13 @@
this.field_195558_d.func_216526_a(this.field_71474_y.field_74350_i);
this.field_71417_B = new MouseHelper(this);
@ -29,11 +29,9 @@
this.field_110451_am = new SimpleReloadableResourceManager(ResourcePackType.CLIENT_RESOURCES);
+ net.minecraftforge.fml.client.ClientModLoader.begin(this, this.field_110448_aq, this.field_110451_am, this.field_195554_ax);
this.field_110448_aq.func_198983_a();
+ DatapackCodec.field_234880_a_.addModPacks(net.minecraftforge.common.ForgeHooks.getModPacks());
this.field_71474_y.func_198017_a(this.field_110448_aq);
this.field_135017_as = new LanguageManager(this.field_71474_y.field_74363_ab);
this.field_110451_am.func_219534_a(this.field_135017_as);
@@ -463,6 +464,7 @@
@@ -463,6 +463,7 @@
this.func_193986_ar();
this.field_110451_am.func_219534_a(this.field_193995_ae);
this.field_71452_i = new ParticleManager(this.field_71441_e, this.field_71446_o);
@ -41,7 +39,7 @@
this.field_110451_am.func_219534_a(this.field_71452_i);
this.field_213272_aL = new PaintingSpriteUploader(this.field_71446_o);
this.field_110451_am.func_219534_a(this.field_213272_aL);
@@ -470,7 +472,8 @@
@@ -470,7 +471,8 @@
this.field_110451_am.func_219534_a(this.field_213273_aM);
this.field_241557_ar_ = new GPUWarning();
this.field_110451_am.func_219534_a(this.field_241557_ar_);
@ -51,7 +49,7 @@
this.field_184132_p = new DebugRenderer(this);
RenderSystem.setErrorCallback(this::func_195545_a);
if (this.field_71474_y.field_74353_u && !this.field_195558_d.func_198113_j()) {
@@ -482,11 +485,6 @@
@@ -482,11 +484,6 @@
this.field_195558_d.func_224798_d(this.field_71474_y.field_225307_E);
this.field_195558_d.func_227801_c_();
this.func_213226_a();
@ -63,7 +61,7 @@
ResourceLoadProgressGui.func_212970_a(this);
List<IResourcePack> list = this.field_110448_aq.func_232623_f_();
@@ -495,7 +493,14 @@
@@ -495,7 +492,14 @@
if (SharedConstants.field_206244_b) {
this.func_213256_aB();
}
@ -79,7 +77,7 @@
});
}, false));
}
@@ -534,7 +539,7 @@
@@ -534,7 +538,7 @@
}
private void func_229988_a_(Throwable p_229988_1_) {
@ -88,7 +86,7 @@
ITextComponent itextcomponent;
if (p_229988_1_ instanceof SimpleReloadableResourceManager.FailedPackException) {
itextcomponent = new StringTextComponent(((SimpleReloadableResourceManager.FailedPackException)p_229988_1_).func_241203_a().func_195762_a());
@@ -618,7 +623,7 @@
@@ -618,7 +622,7 @@
return Stream.of(Registry.field_212630_s.func_177774_c(p_213251_0_.func_77973_b()));
});
SearchTreeReloadable<ItemStack> searchtreereloadable = new SearchTreeReloadable<>((p_213235_0_) -> {
@ -97,7 +95,7 @@
});
NonNullList<ItemStack> nonnulllist = NonNullList.func_191196_a();
@@ -688,13 +693,13 @@
@@ -688,13 +692,13 @@
Bootstrap.func_179870_a(p_71377_0_.func_71502_e());
if (p_71377_0_.func_71497_f() != null) {
Bootstrap.func_179870_a("#@!@# Game crashed! Crash report saved to: #@!@# " + p_71377_0_.func_71497_f());
@ -114,7 +112,7 @@
}
}
@@ -703,6 +708,7 @@
@@ -703,6 +707,7 @@
return this.field_71474_y.field_211842_aO;
}
@ -122,7 +120,7 @@
public CompletableFuture<Void> func_213237_g() {
if (this.field_213276_aV != null) {
return this.field_213276_aV;
@@ -791,10 +797,6 @@
@@ -791,10 +796,6 @@
}
public void func_147108_a(@Nullable Screen p_147108_1_) {
@ -133,7 +131,7 @@
if (p_147108_1_ == null && this.field_71441_e == null) {
p_147108_1_ = new MainMenuScreen();
} else if (p_147108_1_ == null && this.field_71439_g.func_233643_dh_()) {
@@ -805,6 +807,14 @@
@@ -805,6 +806,14 @@
}
}
@ -148,7 +146,7 @@
if (p_147108_1_ instanceof MainMenuScreen || p_147108_1_ instanceof MultiplayerScreen) {
this.field_71474_y.field_74330_P = false;
this.field_71456_v.func_146158_b().func_146231_a(true);
@@ -936,11 +946,13 @@
@@ -936,11 +945,13 @@
RenderSystem.enableCull();
this.field_71424_I.func_76319_b();
if (!this.field_71454_w) {
@ -162,7 +160,7 @@
}
if (this.field_238174_aV_ != null) {
@@ -1039,7 +1051,7 @@
@@ -1039,7 +1050,7 @@
Framebuffer framebuffer = this.func_147110_a();
framebuffer.func_216491_a(this.field_195558_d.func_198109_k(), this.field_195558_d.func_198091_l(), field_142025_a);
@ -171,7 +169,7 @@
this.field_71417_B.func_198021_g();
}
@@ -1227,11 +1239,21 @@
@@ -1227,11 +1238,21 @@
if (p_147115_1_ && this.field_71476_x != null && this.field_71476_x.func_216346_c() == RayTraceResult.Type.BLOCK) {
BlockRayTraceResult blockraytraceresult = (BlockRayTraceResult)this.field_71476_x;
BlockPos blockpos = blockraytraceresult.func_216350_a();
@ -195,7 +193,7 @@
}
}
@@ -1250,6 +1272,8 @@
@@ -1250,6 +1271,8 @@
}
} else if (!this.field_71439_g.func_184838_M()) {
@ -204,7 +202,7 @@
switch(this.field_71476_x.func_216346_c()) {
case ENTITY:
this.field_71442_b.func_78764_a(this.field_71439_g, ((EntityRayTraceResult)this.field_71476_x).func_216348_a());
@@ -1257,7 +1281,7 @@
@@ -1257,7 +1280,7 @@
case BLOCK:
BlockRayTraceResult blockraytraceresult = (BlockRayTraceResult)this.field_71476_x;
BlockPos blockpos = blockraytraceresult.func_216350_a();
@ -213,7 +211,7 @@
this.field_71442_b.func_180511_b(blockpos, blockraytraceresult.func_216354_b());
break;
}
@@ -1267,8 +1291,10 @@
@@ -1267,8 +1290,10 @@
}
this.field_71439_g.func_184821_cY();
@ -224,7 +222,7 @@
this.field_71439_g.func_184609_a(Hand.MAIN_HAND);
}
}
@@ -1283,6 +1309,11 @@
@@ -1283,6 +1308,11 @@
}
for(Hand hand : Hand.values()) {
@ -236,7 +234,7 @@
ItemStack itemstack = this.field_71439_g.func_184586_b(hand);
if (this.field_71476_x != null) {
switch(this.field_71476_x.func_216346_c()) {
@@ -1296,6 +1327,7 @@
@@ -1296,6 +1326,7 @@
if (actionresulttype.func_226246_a_()) {
if (actionresulttype.func_226247_b_()) {
@ -244,7 +242,7 @@
this.field_71439_g.func_184609_a(hand);
}
@@ -1308,6 +1340,7 @@
@@ -1308,6 +1339,7 @@
ActionResultType actionresulttype1 = this.field_71442_b.func_217292_a(this.field_71439_g, this.field_71441_e, hand, blockraytraceresult);
if (actionresulttype1.func_226246_a_()) {
if (actionresulttype1.func_226247_b_()) {
@ -252,7 +250,7 @@
this.field_71439_g.func_184609_a(hand);
if (!itemstack.func_190926_b() && (itemstack.func_190916_E() != i || this.field_71442_b.func_78758_h())) {
this.field_71460_t.field_78516_c.func_187460_a(hand);
@@ -1323,6 +1356,9 @@
@@ -1323,6 +1355,9 @@
}
}
@ -262,7 +260,7 @@
if (!itemstack.func_190926_b()) {
ActionResultType actionresulttype2 = this.field_71442_b.func_187101_a(this.field_71439_g, this.field_71441_e, hand);
if (actionresulttype2.func_226246_a_()) {
@@ -1349,6 +1385,8 @@
@@ -1349,6 +1384,8 @@
--this.field_71467_ac;
}
@ -271,7 +269,7 @@
this.field_71424_I.func_76320_a("gui");
if (!this.field_71445_n) {
this.field_71456_v.func_73831_a();
@@ -1465,6 +1503,8 @@
@@ -1465,6 +1502,8 @@
this.field_71424_I.func_219895_b("keyboard");
this.field_195559_v.func_204870_b();
this.field_71424_I.func_76319_b();
@ -280,7 +278,7 @@
}
private void func_184117_aA() {
@@ -1696,7 +1736,12 @@
@@ -1696,7 +1735,12 @@
networkmanager.func_150719_a(new ClientLoginNetHandler(networkmanager, this, (Screen)null, (p_229998_0_) -> {
}));
networkmanager.func_179290_a(new CHandshakePacket(socketaddress.toString(), 0, ProtocolType.LOGIN));
@ -294,7 +292,7 @@
this.field_71453_ak = networkmanager;
} else {
this.func_241559_a_(p_238195_6_, p_238195_1_, flag, () -> {
@@ -1770,6 +1815,7 @@
@@ -1770,6 +1814,7 @@
}
public void func_71403_a(ClientWorld p_71403_1_) {
@ -302,7 +300,7 @@
WorkingScreen workingscreen = new WorkingScreen();
workingscreen.func_200210_a(new TranslationTextComponent("connect.joining"));
this.func_213241_c(workingscreen);
@@ -1801,10 +1847,12 @@
@@ -1801,10 +1846,12 @@
IntegratedServer integratedserver = this.field_71437_Z;
this.field_71437_Z = null;
this.field_71460_t.func_190564_k();
@ -315,7 +313,7 @@
if (integratedserver != null) {
this.field_71424_I.func_76320_a("waitForServer");
@@ -1819,6 +1867,7 @@
@@ -1819,6 +1866,7 @@
this.field_71456_v.func_181029_i();
this.field_71422_O = null;
this.field_71455_al = false;
@ -323,7 +321,7 @@
this.field_213274_aO.func_216815_b();
}
@@ -1849,6 +1898,7 @@
@@ -1849,6 +1897,7 @@
this.field_71452_i.func_78870_a(p_213257_1_);
TileEntityRendererDispatcher.field_147556_a.func_147543_a(p_213257_1_);
this.func_230150_b_();
@ -331,7 +329,7 @@
}
public boolean func_238216_r_() {
@@ -1894,112 +1944,9 @@
@@ -1894,112 +1943,9 @@
private void func_147112_ai() {
if (this.field_71476_x != null && this.field_71476_x.func_216346_c() != RayTraceResult.Type.MISS) {
@ -447,7 +445,7 @@
}
}
@@ -2081,6 +2028,7 @@
@@ -2081,6 +2027,7 @@
return field_71432_P;
}
@ -455,7 +453,7 @@
public CompletableFuture<Void> func_213245_w() {
return this.func_213169_a(this::func_213237_g).thenCompose((p_229993_0_) -> {
return p_229993_0_;
@@ -2388,7 +2336,7 @@
@@ -2388,7 +2335,7 @@
supplier = func_228022_c_(supplier);
}
@ -464,7 +462,7 @@
}
private static Supplier<IResourcePack> func_228021_b_(Supplier<IResourcePack> p_228021_0_) {
@@ -2407,6 +2355,14 @@
@@ -2407,6 +2354,14 @@
this.field_175617_aL.func_229355_a_(p_228020_1_);
}

View File

@ -13,3 +13,14 @@
return this.field_85075_d.length;
}
}
@@ -158,6 +160,10 @@
return this.field_85075_d;
}
+ public void applyStackTrace(Throwable t) {
+ this.field_85075_d = t.getStackTrace();
+ }
+
public static void func_175750_a(CrashReportCategory p_175750_0_, BlockPos p_175750_1_, @Nullable BlockState p_175750_2_) {
if (p_175750_2_ != null) {
p_175750_0_.func_189529_a("Block", p_175750_2_::toString);

View File

@ -26,7 +26,7 @@
+ Collection<Path> existingPacks = optionset.valuesOf(existing).stream().map(Paths::get).collect(Collectors.toList());
+ java.util.Set<String> mods = new java.util.HashSet<>(optionset.valuesOf(mod));
+ boolean isFlat = mods.isEmpty() || optionset.has(flat);
+ net.minecraftforge.fml.ModLoader.get().runDataGenerator(mods, path, inputs, existingPacks, flag2, flag1, flag3, flag4, flag5, isFlat);
+ net.minecraftforge.fml.DatagenModLoader.begin(mods, path, inputs, existingPacks, flag2, flag1, flag3, flag4, flag5, isFlat);
+ if (mods.contains("minecraft") || mods.isEmpty())
+ func_200264_a(isFlat ? path : path.resolve("minecraft"), inputs, flag1, flag2, flag3, flag4, flag5).func_200392_c();
} else {

View File

@ -20,7 +20,7 @@
this.field_199807_b = p_i49381_1_.toArray((p_209360_0_) -> {
return new Ingredient.IItemList[p_209360_0_];
});
+ this.isSimple = !net.minecraftforge.fml.ModLoader.isDataGenRunning() && !Arrays.stream(field_199807_b).anyMatch(list -> list.func_199799_a().stream().anyMatch(stack -> stack.func_77973_b().func_77645_m()));
+ this.isSimple = !net.minecraftforge.fml.DatagenModLoader.isRunningDataGen() && !Arrays.stream(field_199807_b).anyMatch(list -> list.func_199799_a().stream().anyMatch(stack -> stack.func_77973_b().func_77645_m()));
+ Ingredient.INSTANCES.add(this);
}

View File

@ -1,13 +1,18 @@
package net.minecraftforge.event;
import com.google.common.collect.ImmutableList;
import net.minecraft.profiler.IProfiler;
import net.minecraft.resources.DataPackRegistries;
import net.minecraft.resources.IFutureReloadListener;
import net.minecraft.resources.IResourceManager;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.ModLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
/**
* The main ResourceManager is recreated on each reload, through {@link DataPackRegistries}'s creation.
@ -30,7 +35,7 @@ public class AddReloadListenerEvent extends Event
*/
public void addListener(IFutureReloadListener listener)
{
listeners.add(listener);
listeners.add(new WrappedStateAwareListener(listener));
}
public List<IFutureReloadListener> getListeners()
@ -42,4 +47,19 @@ public class AddReloadListenerEvent extends Event
{
return dataPackRegistries;
}
private static class WrappedStateAwareListener implements IFutureReloadListener {
private final IFutureReloadListener wrapped;
private WrappedStateAwareListener(final IFutureReloadListener wrapped) {
this.wrapped = wrapped;
}
@Override
public CompletableFuture<Void> reload(final IStage stage, final IResourceManager resourceManager, final IProfiler preparationsProfiler, final IProfiler reloadProfiler, final Executor backgroundExecutor, final Executor gameExecutor) {
if (ModLoader.isLoadingStateValid())
return wrapped.reload(stage, resourceManager, preparationsProfiler, reloadProfiler, backgroundExecutor, gameExecutor);
else
return CompletableFuture.completedFuture(null);
}
}
}

View File

@ -0,0 +1,34 @@
package net.minecraftforge.fml;
import net.minecraft.util.registry.Bootstrap;
import net.minecraftforge.client.model.generators.ExistingFileHelper;
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Set;
public class DatagenModLoader {
private static final Logger LOGGER = LogManager.getLogger();
private static GatherDataEvent.DataGeneratorConfig dataGeneratorConfig;
private static ExistingFileHelper existingFileHelper;
private static boolean runningDataGen;
public static boolean isRunningDataGen() {
return runningDataGen;
}
public static void begin(final Set<String> mods, final Path path, final java.util.Collection<Path> inputs, Collection<Path> existingPacks, final boolean serverGenerators, final boolean clientGenerators, final boolean devToolGenerators, final boolean reportsGenerator, final boolean structureValidator, final boolean flat) {
if (mods.contains("minecraft") && mods.size() == 1) return;
LOGGER.info("Initializing Data Gatherer for mods {}", mods);
runningDataGen = true;
Bootstrap.register();
dataGeneratorConfig = new GatherDataEvent.DataGeneratorConfig(mods, path, inputs, serverGenerators, clientGenerators, devToolGenerators, reportsGenerator, structureValidator, flat);
existingFileHelper = new ExistingFileHelper(existingPacks, structureValidator);
ModLoader.get().gatherAndInitializeMods(ModWorkManager.syncExecutor(), ModWorkManager.parallelExecutor(), ()->{});
ModLoader.get().runEventGenerator(mc->new GatherDataEvent(mc, dataGeneratorConfig.makeGenerator(p->dataGeneratorConfig.isFlat() ? p : p.resolve(mc.getModId()), dataGeneratorConfig.getMods().contains(mc.getModId())), dataGeneratorConfig, existingFileHelper));
dataGeneratorConfig.runAll();
}
}

View File

@ -21,11 +21,7 @@ package net.minecraftforge.fml;
import static net.minecraftforge.fml.Logging.LOADING;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.Executor;
@ -33,6 +29,7 @@ import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import net.minecraftforge.fml.event.lifecycle.ParallelDispatchEvent;
import net.minecraftforge.fml.javafmlmod.FMLModContainer;
import org.apache.commons.lang3.time.StopWatch;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -97,6 +94,20 @@ public class DeferredWorkQueue
return CompletableFuture.supplyAsync(work, r->tasks.add(new TaskInfo(modInfo, r)));
}
/**
* DEPRECATED FOR REMOVAL. Use {@link ParallelDispatchEvent#enqueueWork(Runnable)} or {@link ParallelDispatchEvent#enqueueWork(Supplier)}
*
* @param workToEnqueue Runnable to execute later
* @return a completable future
*/
@Deprecated
public static CompletableFuture<Void> runLater(Runnable workToEnqueue) {
return
Optional.ofNullable(ModLoadingContext.get().getActiveContainer().modLoadingStage.getDeferredWorkQueue())
.map(wq->wq.enqueueWork(ModLoadingContext.get().getActiveContainer().modInfo, workToEnqueue))
.orElseGet(()->CompletableFuture.completedFuture(null));
}
static class TaskInfo
{
public final IModInfo owner;

View File

@ -19,6 +19,7 @@
package net.minecraftforge.fml;
import com.google.common.base.CharMatcher;
import net.minecraftforge.fml.loading.StringUtils;
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
import org.apache.commons.lang3.text.ExtendedMessageFormat;
@ -33,14 +34,22 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.regex.Pattern;
import static net.minecraftforge.fml.Logging.CORE;
//TODO, this should be re-evaluated now that ITextComponents are passed everywhere instaed of strings.
public class ForgeI18n {
private static final Logger LOGGER = LogManager.getLogger();
// From FontRenderer.renderCharAtPos
private static final String ALLOWED_CHARS = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000";
private static final CharMatcher DISALLOWED_CHAR_MATCHER = CharMatcher.anyOf(ALLOWED_CHARS).negate();
private static Map<String,String> i18n;
private static Map<String,FormatFactory> customFactories;
// From StringUtils
private static final Pattern PATTERN_CONTROL_CODE = Pattern.compile("(?i)\\u00A7[0-9A-FK-OR]");
static {
customFactories = new HashMap<>();
@ -102,6 +111,16 @@ public class ForgeI18n {
return extendedMessageFormat.format(args);
}
public static String stripSpecialChars(String message)
{
// We can't handle many unicode points in the splash renderer
return DISALLOWED_CHAR_MATCHER.removeFrom(stripControlCodes(message));
}
public static String stripControlCodes(String text) {
return PATTERN_CONTROL_CODE.matcher(text).replaceAll("");
}
public static class CustomReadOnlyFormat extends Format {
private final BiConsumer<StringBuffer, Object> formatter;

View File

@ -112,8 +112,7 @@ public class ModLoader
private final List<ModLoadingException> loadingExceptions;
private final List<ModLoadingWarning> loadingWarnings;
private GatherDataEvent.DataGeneratorConfig dataGeneratorConfig;
private ExistingFileHelper existingFileHelper;
private boolean loadingStateValid;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private final Optional<Consumer<String>> statusConsumer = StartupMessageManager.modLoaderConsumer();
@ -162,6 +161,7 @@ public class ModLoader
* @param periodicTask Optional periodic task to perform on the main thread while other activities run
*/
public void gatherAndInitializeMods(final ModWorkManager.DrivenExecutor syncExecutor, final Executor parallelExecutor, final Runnable periodicTask) {
loadingStateValid = true;
statusConsumer.ifPresent(c->c.accept("Waiting for scan to complete"));
FMLLoader.backgroundScanHandler.waitForScanToComplete(periodicTask);
statusConsumer.ifPresent(c->c.accept("Loading mods"));
@ -174,6 +174,7 @@ public class ModLoader
if (!this.loadingExceptions.isEmpty()) {
LOGGER.fatal(CORE, "Error during pre-loading phase", loadingExceptions.get(0));
modList.setLoadedMods(Collections.emptyList());
loadingStateValid = false;
throw new LoadingFailedException(loadingExceptions);
}
statusConsumer.ifPresent(c->c.accept("Building Mod List"));
@ -185,6 +186,7 @@ public class ModLoader
if (!loadingExceptions.isEmpty()) {
LOGGER.fatal(CORE, "Failed to initialize mod containers", loadingExceptions.get(0));
modList.setLoadedMods(Collections.emptyList());
loadingStateValid = false;
throw new LoadingFailedException(loadingExceptions);
}
modList.setLoadedMods(modContainers);
@ -225,21 +227,29 @@ public class ModLoader
}
private void dispatchAndHandleError(ModLoadingStage state, ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor, final Runnable ticker) {
if (!isLoadingStateValid()) {
LOGGER.error("Cowardly refusing to process mod state change request from {}", state);
return;
}
waitForTransition(state, syncExecutor, ticker, state.buildTransition(syncExecutor, parallelExecutor));
}
private void dispatchAndHandleError(ModLoadingStage state, ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor, final Runnable ticker, Function<Executor, CompletableFuture<Void>> preSyncTask, Function<Executor, CompletableFuture<Void>> postSyncTask) {
if (!isLoadingStateValid()) {
LOGGER.error("Cowardly refusing to process mod state change request from {}", state);
return;
}
waitForTransition(state, syncExecutor, ticker, state.buildTransition(syncExecutor, parallelExecutor, preSyncTask, postSyncTask));
}
private void waitForTransition(final ModLoadingStage state, final ModWorkManager.DrivenExecutor syncExecutor, final Runnable ticker, final CompletableFuture<List<Throwable>> transition) {
while (!transition.isDone()) {
ticker.run();
syncExecutor.drive();
syncExecutor.drive(ticker);
}
try {
transition.join();
} catch (CompletionException e) {
loadingStateValid = false;
Throwable t = e.getCause();
final List<Throwable> notModLoading = Arrays.stream(t.getSuppressed())
.filter(obj -> !(obj instanceof ModLoadingException))
@ -292,7 +302,27 @@ public class ModLoader
}
}
/**
* @return If the current mod loading state is valid. Use if you interact with vanilla systems directly during loading
* and don't want to cause extraneous crashes due to trying to do things that aren't possible in a "broken load"
*/
public static boolean isLoadingStateValid() {
return get().loadingStateValid;
}
public <T extends Event & IModBusEvent> void runEventGenerator(Function<ModContainer, T> generator) {
if (!loadingStateValid) {
LOGGER.error("Cowardly refusing to send event generator to a broken mod state");
return;
}
ModList.get().forEachModContainer((id, mc) -> mc.acceptEvent(generator.apply(mc)));
}
public <T extends Event & IModBusEvent> void postEvent(T e) {
if (!loadingStateValid) {
LOGGER.error("Cowardly refusing to send event {} to a broken mod state", e.getClass().getName());
return;
}
ModList.get().forEachModContainer((id, mc) -> mc.acceptEvent(e));
}
@ -311,20 +341,4 @@ public class ModLoader
public static boolean isDataGenRunning () {
return runningDataGen;
}
public void runDataGenerator(final Set<String> mods, final Path path, final Collection<Path> inputs, Collection<Path> existingPacks, final boolean serverGenerators, final boolean clientGenerators, final boolean devToolGenerators, final boolean reportsGenerator, final boolean structureValidator, final boolean flat) {
// if (mods.contains("minecraft") && mods.size() == 1) return;
// LOGGER.info("Initializing Data Gatherer for mods {}", mods);
// runningDataGen = true;
// Bootstrap.register();
// dataGeneratorConfig = new GatherDataEvent.DataGeneratorConfig(mods, path, inputs, serverGenerators, clientGenerators, devToolGenerators, reportsGenerator, structureValidator, flat);
// existingFileHelper = new ExistingFileHelper(existingPacks, structureValidator);
// gatherAndInitializeMods(() -> {});
// dispatchAndHandleError(LifecycleEventProvider.GATHERDATA, Runnable::run, () -> {});
// dataGeneratorConfig.runAll();
}
public Function<ModContainer, ModLifecycleEvent> getDataGeneratorEvent() {
return mc -> new GatherDataEvent(mc, dataGeneratorConfig.makeGenerator(p->dataGeneratorConfig.isFlat() ? p : p.resolve(mc.getModId()), dataGeneratorConfig.getMods().contains(mc.getModId())), dataGeneratorConfig, existingFileHelper);
}
}

View File

@ -28,6 +28,7 @@ public class ModLoadingContext
{
private static ThreadLocal<ModLoadingContext> context = ThreadLocal.withInitial(ModLoadingContext::new);
private Object languageExtension;
private ModLoadingStage stage;
public static ModLoadingContext get() {
return context.get();

View File

@ -20,7 +20,9 @@
package net.minecraftforge.fml;
import com.google.common.collect.Streams;
import net.minecraft.util.StringUtils;
import net.minecraftforge.fml.loading.EarlyLoadingException;
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
import net.minecraftforge.forgespi.language.IModInfo;
import java.util.Arrays;
@ -79,4 +81,11 @@ public class ModLoadingException extends RuntimeException
public String getMessage() {
return formatToString();
}
public IModInfo getModInfo() {
return modInfo;
}
public String getCleanMessage() {
return ForgeI18n.stripControlCodes(formatToString());
}
}

View File

@ -57,14 +57,14 @@ public enum ModLoadingStage
ENQUEUE_IMC(InterModEnqueueEvent.class),
PROCESS_IMC(InterModProcessEvent.class),
COMPLETE(FMLLoadCompleteEvent.class),
DONE(),
GATHERDATA();
DONE();
private final Supplier<Stream<EventGenerator<?>>> eventFunctionStream;
private final EventDispatcher<?> eventManager;
private final Optional<Class<? extends ParallelDispatchEvent>> parallelEventClass;
private final ThreadSelector threadSelector;
private final BiFunction<Executor, CompletableFuture<List<Throwable>>, CompletableFuture<List<Throwable>>> finalActivityGenerator;
private DeferredWorkQueue deferredWorkQueue;
ModLoadingStage(Class<? extends ParallelDispatchEvent> parallelClass) {
final EventGenerator<?> event = EventGenerator.fromFunction(LamdbaExceptionUtils.rethrowFunction((ModContainer mc) -> parallelClass.getConstructor(ModContainer.class).newInstance(mc)));
@ -72,7 +72,7 @@ public enum ModLoadingStage
this.threadSelector = ThreadSelector.PARALLEL;
this.eventManager = EventDispatcher.identity();
this.parallelEventClass = Optional.of(parallelClass);
final DeferredWorkQueue deferredWorkQueue = new DeferredWorkQueue(this, parallelClass);
deferredWorkQueue = new DeferredWorkQueue(this, parallelClass);
this.finalActivityGenerator = (e, prev) -> prev.thenApplyAsync((List<Throwable> t) -> {
deferredWorkQueue.runTasks();
return t;
@ -145,6 +145,10 @@ public enum ModLoadingStage
}
}
public DeferredWorkQueue getDeferredWorkQueue() {
return deferredWorkQueue;
}
public interface EventGenerator<T extends Event & IModBusEvent> extends Function<ModContainer, T> {
static <FN extends Event & IModBusEvent> EventGenerator<FN> fromFunction(Function<ModContainer, FN> fn) {
return fn::apply;

View File

@ -17,10 +17,10 @@ public class ModWorkManager {
boolean selfDriven();
boolean driveOne();
default void drive() {
default void drive(Runnable ticker) {
if (!selfDriven()) {
while (driveOne())
;
ticker.run();
}
}
}

View File

@ -1,78 +0,0 @@
/*
* Minecraft Forge
* Copyright (c) 2016-2020.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.fml;
import net.minecraft.client.Minecraft;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.client.ClientHooks;
import net.minecraftforge.fml.loading.FMLEnvironment;
import java.util.function.Function;
import java.util.function.Supplier;
public enum SidedProvider
{
// All of these need to be careful not to directly dereference the client and server elements in their signatures
DATAFIXER(
c->c.get().getDataFixer(),
s->s.get().getDataFixer(),
()-> { throw new UnsupportedOperationException(); }),
STRIPCHARS(
(Function<Supplier<Minecraft>, Function<String, String>>)c-> ClientHooks::stripSpecialChars,
s-> str->str,
()-> str->str);
private static Supplier<Minecraft> client;
private static Supplier<DedicatedServer> server;
public static void setClient(Supplier<Minecraft> client)
{
SidedProvider.client = client;
}
public static void setServer(Supplier<DedicatedServer> server)
{
SidedProvider.server = server;
}
private final Function<Supplier<Minecraft>, ?> clientSide;
private final Function<Supplier<DedicatedServer>, ?> serverSide;
private final Supplier<?> testSide;
<T> SidedProvider(Function<Supplier<Minecraft>, T> clientSide, Function<Supplier<DedicatedServer>, T> serverSide, Supplier<T> testSide)
{
this.clientSide = clientSide;
this.serverSide = serverSide;
this.testSide = testSide;
}
@SuppressWarnings("unchecked")
public <T> T get() {
if (FMLEnvironment.dist == Dist.CLIENT) {
return (T)this.clientSide.apply(client);
}
else if (FMLEnvironment.dist == Dist.DEDICATED_SERVER) {
return (T)this.serverSide.apply(server);
}
else {
return (T)this.testSide.get();
}
}
}

View File

@ -75,9 +75,6 @@ public class ClientHooks
{
private static final Logger LOGGER = LogManager.getLogger();
private static final Marker CLIENTHOOKS = MarkerManager.getMarker("CLIENTHOOKS");
// From FontRenderer.renderCharAtPos
private static final String ALLOWED_CHARS = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000";
private static final CharMatcher DISALLOWED_CHAR_MATCHER = CharMatcher.anyOf(ALLOWED_CHARS).negate();
private static final ResourceLocation iconSheet = new ResourceLocation(ForgeVersion.MOD_ID, "textures/gui/icons.png");
@Nullable
@ -197,12 +194,6 @@ public class ClientHooks
}
public static String stripSpecialChars(String message)
{
// We can't handle many unicode points in the splash renderer
return DISALLOWED_CHAR_MATCHER.removeFrom(net.minecraft.util.StringUtils.stripControlCodes(message));
}
private static SetMultimap<String,ResourceLocation> missingTextures = HashMultimap.create();
private static Set<String> badTextureDomains = Sets.newHashSet();
private static Table<String, String, Set<ResourceLocation>> brokenTextures = HashBasedTable.create();

View File

@ -22,32 +22,40 @@ package net.minecraftforge.fml.client;
import static net.minecraftforge.fml.Logging.CORE;
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraft.resources.IFutureReloadListener;
import net.minecraft.resources.IPackNameDecorator;
import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.resources.IResourceManager;
import net.minecraft.resources.ResourcePackInfo;
import net.minecraft.resources.ResourcePackList;
import net.minecraft.util.datafix.codec.DatapackCodec;
import net.minecraftforge.fml.BrandingControl;
import net.minecraftforge.fml.LoadingFailedException;
import net.minecraftforge.fml.LogicalSidedProvider;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.ModLoader;
import net.minecraftforge.fml.ModLoadingStage;
import net.minecraftforge.fml.ModLoadingWarning;
import net.minecraftforge.fml.ModWorkManager;
import net.minecraftforge.fml.SidedProvider;
import net.minecraftforge.fml.VersionChecker;
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -80,22 +88,41 @@ public class ClientModLoader
private static final Logger LOGGER = LogManager.getLogger();
private static boolean loading;
private static Minecraft mc;
private static boolean loadingComplete;
private static LoadingFailedException error;
private static EarlyLoaderGUI earlyLoaderGUI;
private static class SpacedRunnable implements Runnable {
static final long NANO_SLEEP_TIME = TimeUnit.MILLISECONDS.toNanos(50);
private final Runnable wrapped;
private long lastRun;
private SpacedRunnable(final Runnable wrapped) {
this.wrapped = wrapped;
this.lastRun = System.nanoTime() - NANO_SLEEP_TIME;
}
@Override
public void run() {
if (System.nanoTime() - this.lastRun > NANO_SLEEP_TIME) {
wrapped.run();
this.lastRun = System.nanoTime();
}
}
}
public static void begin(final Minecraft minecraft, final ResourcePackList<ClientResourcePackInfo> defaultResourcePacks, final IReloadableResourceManager mcResourceManager, DownloadingPackFinder metadataSerializer)
{
// force log4j to shutdown logging in a shutdown hook. This is because we disable default shutdown hook so the server properly logs it's shutdown
Runtime.getRuntime().addShutdownHook(new Thread(LogManager::shutdown));
loading = true;
ClientModLoader.mc = minecraft;
SidedProvider.setClient(()->minecraft);
LogicalSidedProvider.setClient(()->minecraft);
LanguageHook.loadForgeAndMCLangs();
earlyLoaderGUI = new EarlyLoaderGUI(minecraft.getMainWindow());
createRunnableWithCatch(()->ModLoader.get().gatherAndInitializeMods(ModWorkManager.syncExecutor(), ModWorkManager.parallelExecutor(), earlyLoaderGUI::renderTick)).run();
createRunnableWithCatch(()->ModLoader.get().gatherAndInitializeMods(ModWorkManager.syncExecutor(), ModWorkManager.parallelExecutor(), new SpacedRunnable(earlyLoaderGUI::renderTick))).run();
if (error == null) {
ResourcePackLoader.loadResourcePacks(defaultResourcePacks, ClientModLoader::buildPackFinder);
DatapackCodec.field_234880_a_.addModPacks(ResourcePackLoader.getPackNames());
mcResourceManager.addReloadListener(ClientModLoader::onResourceReload);
mcResourceManager.addReloadListener(BrandingControl.resourceManagerReloadListener());
ModelLoaderRegistry.init();
@ -110,10 +137,10 @@ public class ClientModLoader
private static Runnable createRunnableWithCatch(Runnable r) {
return ()-> {
if (loadingComplete) return;
try {
r.run();
} catch (LoadingFailedException e) {
MinecraftForge.EVENT_BUS.shutdown();
if (error == null) error = e;
}
};
@ -121,7 +148,7 @@ public class ClientModLoader
private static void startModLoading(ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor) {
earlyLoaderGUI.handleElsewhere();
createRunnableWithCatch(() -> ModLoader.get().loadMods(syncExecutor, parallelExecutor, executor -> CompletableFuture.runAsync(ClientModLoader::preSidedRunnable, executor), executor -> CompletableFuture.runAsync(ClientModLoader::postSidedRunnable, executor), ()->{})).run();
createRunnableWithCatch(() -> ModLoader.get().loadMods(syncExecutor, parallelExecutor, executor -> CompletableFuture.runAsync(ClientModLoader::preSidedRunnable, executor), executor -> CompletableFuture.runAsync(ClientModLoader::postSidedRunnable, executor), new SpacedRunnable(earlyLoaderGUI::renderTick))).run();
}
private static void postSidedRunnable() {
@ -135,15 +162,15 @@ public class ClientModLoader
private static void finishModLoading(ModWorkManager.DrivenExecutor syncExecutor, Executor parallelExecutor)
{
createRunnableWithCatch(() -> ModLoader.get().finishMods(syncExecutor, parallelExecutor, ()->{})).run();
createRunnableWithCatch(() -> ModLoader.get().finishMods(syncExecutor, parallelExecutor, new SpacedRunnable(earlyLoaderGUI::renderTick))).run();
loading = false;
loadingComplete = true;
// reload game settings on main thread
syncExecutor.execute(()->mc.gameSettings.loadOptions());
}
public static VersionChecker.Status checkForUpdates()
{
boolean anyOutdated = ModList.get().getMods().stream()
.map(VersionChecker::getResult)
.map(result -> result.status)
@ -173,6 +200,24 @@ public class ClientModLoader
if (error == null) {
// We can finally start the forge eventbus up
MinecraftForge.EVENT_BUS.start();
} else {
final CrashReport crashReport = CrashReport.makeCrashReport(new Exception("Mod Loading has failed"), "Mod loading error has occurred");
error.getErrors().forEach(mle -> {
final CrashReportCategory category = crashReport.makeCategory(mle.getModInfo().getModId());
category.applyStackTrace(mle.getCause());
category.addDetail("Failure message", mle.getCleanMessage());
category.addDetail("Exception message", mle.getCause().toString());
category.addDetail("Mod Version", mle.getModInfo().getVersion().toString());
category.addDetail("Mod Issue URL", ((ModFileInfo)mle.getModInfo().getOwningFile()).getConfigElement("issueTrackerURL").orElse("NOT PROVIDED"));
});
final File file1 = new File(mc.gameDir, "crash-reports");
final File file2 = new File(file1, "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-client.txt");
if (crashReport.saveToFile(file2)) {
LOGGER.fatal("Crash report saved to {}", crashReport.getFile());
} else {
LOGGER.fatal("Failed to save crash report");
}
System.out.print(crashReport.getCompleteReport());
}
if (error != null || !warnings.isEmpty()) {
mc.displayGuiScreen(new LoadingErrorScreen(error, warnings));

View File

@ -22,6 +22,7 @@ package net.minecraftforge.fml.event.lifecycle;
import cpw.mods.modlauncher.api.LamdbaExceptionUtils;
import net.minecraft.data.DataGenerator;
import net.minecraftforge.client.model.generators.ExistingFileHelper;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.fml.ModContainer;
import java.nio.file.Path;
@ -33,19 +34,25 @@ import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
public class GatherDataEvent extends ModLifecycleEvent
public class GatherDataEvent extends Event implements IModBusEvent
{
private final DataGenerator dataGenerator;
private final DataGeneratorConfig config;
private final ExistingFileHelper existingFileHelper;
public GatherDataEvent(final ModContainer modContainer, final DataGenerator dataGenerator, final DataGeneratorConfig dataGeneratorConfig, ExistingFileHelper existingFileHelper)
private final ModContainer modContainer;
public GatherDataEvent(final ModContainer mc, final DataGenerator dataGenerator, final DataGeneratorConfig dataGeneratorConfig, ExistingFileHelper existingFileHelper)
{
super(modContainer);
this.modContainer = mc;
this.dataGenerator = dataGenerator;
this.config = dataGeneratorConfig;
this.existingFileHelper = existingFileHelper;
}
public ModContainer getModContainer() {
return this.modContainer;
}
public DataGenerator getGenerator() { return this.dataGenerator; }
public ExistingFileHelper getExistingFileHelper() { return existingFileHelper; }
public boolean includeServer() { return this.config.server; }

View File

@ -54,16 +54,16 @@ public class ResourcePackLoader
public static <T extends ResourcePackInfo> void loadResourcePacks(ResourcePackList<T> resourcePacks, BiFunction<Map<ModFile, ? extends ModFileResourcePack>, BiConsumer<? super ModFileResourcePack, T>, IPackInfoFinder> packFinder) {
resourcePackList = resourcePacks;
modResourcePacks = ModList.get().getModFiles().stream().
filter(mf->!Objects.equals(mf.getModLoader(),"minecraft")).
map(mf -> new ModFileResourcePack(mf.getFile())).
collect(Collectors.toMap(ModFileResourcePack::getModFile, Function.identity(), (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }, LinkedHashMap::new));
modResourcePacks = ModList.get().getModFiles().stream()
.filter(mf->!Objects.equals(mf.getModLoader(),"minecraft"))
.map(mf -> new ModFileResourcePack(mf.getFile()))
.collect(Collectors.toMap(ModFileResourcePack::getModFile, Function.identity(), (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }, LinkedHashMap::new));
resourcePacks.addPackFinder(new LambdaFriendlyPackFinder(packFinder.apply(modResourcePacks, ModFileResourcePack::setPackInfo)));
}
public static List<String> getPackNames()
{
return modResourcePacks.values().stream().map(pack -> pack.getPackInfo().getName()).collect(Collectors.toList());
return ModList.get().applyForEachModFile(mf->"mod:"+mf.getModInfos().get(0).getModId()).filter(n->!n.equals("mod:minecraft")).collect(Collectors.toList());
}
public static <V> Comparator<Map.Entry<String,V>> getSorter() {

View File

@ -31,14 +31,12 @@ import java.util.function.BiConsumer;
import java.util.function.Consumer;
import net.minecraft.resources.IPackNameDecorator;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.world.storage.FolderName;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.LogicalSidedProvider;
import net.minecraftforge.fml.ModLoader;
import net.minecraftforge.fml.ModLoadingStage;
import net.minecraftforge.fml.ModLoadingWarning;
import net.minecraftforge.fml.SidedProvider;
import net.minecraftforge.fml.network.ConnectionType;
import net.minecraftforge.fml.network.FMLNetworkConstants;
import net.minecraftforge.fml.network.FMLStatusPing;
@ -92,7 +90,6 @@ public class ServerLifecycleHooks
currentServer = server;
currentServer.getServerStatusResponse().setForgeData(new FMLStatusPing()); //gathers NetworkRegistry data
// on the dedi server we need to force the stuff to setup properly
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, ()->()->SidedProvider.setServer(()->(DedicatedServer)server));
LogicalSidedProvider.setServer(()->server);
ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.SERVER, getServerConfigPath(server));
return !MinecraftForge.EVENT_BUS.post(new FMLServerAboutToStartEvent(server));
@ -185,30 +182,6 @@ public class ServerLifecycleHooks
public static void handleExit(int retVal)
{
/*
CountDownLatch latch = exitLatch;
if (latch != null)
{
try
{
LOGGER.info("Waiting for the server to terminate/save.");
if (!latch.await(10, TimeUnit.SECONDS))
{
LOGGER.warn("The server didn't stop within 10 seconds, exiting anyway.");
}
else
{
LOGGER.info("Server terminated.");
}
}
catch (InterruptedException e)
{
LOGGER.warn("Interrupted wait, exiting.");
}
}
*/
System.exit(retVal);
}
@ -235,5 +208,4 @@ public class ServerLifecycleHooks
consumer.accept(packInfo);
}
}
}

View File

@ -19,17 +19,23 @@
package net.minecraftforge.fml.server;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.LoadingFailedException;
import net.minecraftforge.fml.LogicalSidedProvider;
import net.minecraftforge.fml.ModLoader;
import net.minecraftforge.fml.ModLoadingWarning;
import net.minecraftforge.fml.ModWorkManager;
import net.minecraftforge.fml.SidedProvider;
import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import static net.minecraftforge.fml.loading.LogMarkers.LOADING;
@ -39,20 +45,34 @@ public class ServerModLoader
private static boolean hasErrors = false;
public static void load() {
SidedProvider.setServer(()-> {
throw new IllegalStateException("Unable to access server yet");
});
LogicalSidedProvider.setServer(()-> {
throw new IllegalStateException("Unable to access server yet");
});
LanguageHook.loadForgeAndMCLangs();
try {
ModLoader.get().gatherAndInitializeMods(ModWorkManager.syncExecutor(), ModWorkManager.parallelExecutor(), ()->{});
ModLoader.get().loadMods(ModWorkManager.syncExecutor(), ModWorkManager.parallelExecutor(), null, null, ()->{});
ModLoader.get().loadMods(ModWorkManager.syncExecutor(), ModWorkManager.parallelExecutor(), e-> CompletableFuture.runAsync(()->{}, e), e->CompletableFuture.runAsync(()->{}, e), ()->{});
ModLoader.get().finishMods(ModWorkManager.syncExecutor(), ModWorkManager.parallelExecutor(), ()->{});
} catch (LoadingFailedException e) {
} catch (LoadingFailedException error) {
ServerModLoader.hasErrors = true;
throw e;
final CrashReport crashReport = CrashReport.makeCrashReport(error, "Mod loading error has occurred");
error.getErrors().forEach(mle -> {
final CrashReportCategory category = crashReport.makeCategory(mle.getModInfo().getModId());
category.applyStackTrace(mle.getCause());
category.addDetail("Failure message", mle.getCleanMessage());
category.addDetail("Exception message", mle.getCause().toString());
category.addDetail("Mod Version", mle.getModInfo().getVersion().toString());
category.addDetail("Mod Issue URL", ((ModFileInfo)mle.getModInfo().getOwningFile()).getConfigElement("issueTrackerURL").orElse("NOT PROVIDED"));
});
final File file1 = new File("crash-reports");
final File file2 = new File(file1, "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt");
if (crashReport.saveToFile(file2)) {
LOGGER.fatal("Crash report saved to {}", file2);
} else {
LOGGER.fatal("Failed to save crash report");
}
System.out.print(crashReport.getCompleteReport());
throw error;
}
List<ModLoadingWarning> warnings = ModLoader.get().getWarnings();
if (!warnings.isEmpty()) {