fix: Should fix the disconnect issue when pretty much all existing spell packs are present in the game
Mods were registering spells on the client and server side in a different order (perhaps related to the OS), causing a mismatch in spell networkIDs. This will ensure that spells are sorted alphabetically and redistributes a new ID.
This commit is contained in:
@@ -20,6 +20,7 @@ import electroblob.wizardry.registry.WizardryItems;
|
|||||||
import electroblob.wizardry.registry.WizardryLoot;
|
import electroblob.wizardry.registry.WizardryLoot;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
|
import electroblob.wizardry.util.SpellNetworkIDSorter;
|
||||||
import electroblob.wizardry.util.SpellProperties;
|
import electroblob.wizardry.util.SpellProperties;
|
||||||
import electroblob.wizardry.util.WandHelper;
|
import electroblob.wizardry.util.WandHelper;
|
||||||
import electroblob.wizardry.worldgen.WorldGenCrystalFlower;
|
import electroblob.wizardry.worldgen.WorldGenCrystalFlower;
|
||||||
@@ -202,6 +203,8 @@ public class Wizardry {
|
|||||||
public void postInit(FMLPostInitializationEvent event){
|
public void postInit(FMLPostInitializationEvent event){
|
||||||
proxy.initialiseLayers();
|
proxy.initialiseLayers();
|
||||||
proxy.initialiseAnimations();
|
proxy.initialiseAnimations();
|
||||||
|
|
||||||
|
SpellNetworkIDSorter.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
|||||||
private static int nextSpellId = 0;
|
private static int nextSpellId = 0;
|
||||||
/** The spell's integer ID, mainly used for networking. */
|
/** The spell's integer ID, mainly used for networking. */
|
||||||
// This was added after I learnt the hard way why you can't assume Forge's registry IDs are sequential...
|
// This was added after I learnt the hard way why you can't assume Forge's registry IDs are sequential...
|
||||||
private final int id;
|
private int id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor should be called from any subclasses, either feeding in the constants directly or through their
|
* This constructor should be called from any subclasses, either feeding in the constants directly or through their
|
||||||
@@ -225,6 +225,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
|||||||
this.icon = new ResourceLocation(modID, "textures/spells/" + name + ".png");
|
this.icon = new ResourceLocation(modID, "textures/spells/" + name + ".png");
|
||||||
this.sounds = createSounds();
|
this.sounds = createSounds();
|
||||||
this.id = nextSpellId++;
|
this.id = nextSpellId++;
|
||||||
|
Wizardry.logger.debug("Registering spell " + this.unlocalisedName +" with networkID " + id);
|
||||||
this.items(WizardryItems.spell_book, WizardryItems.scroll);
|
this.items(WizardryItems.spell_book, WizardryItems.scroll);
|
||||||
this.npcSelector((e, o) -> false);
|
this.npcSelector((e, o) -> false);
|
||||||
}
|
}
|
||||||
@@ -560,6 +561,11 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sets the networkID of this spell. Do not call this or it will cause all packets to fail. */
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the {@code ResourceLocation} for this spell's icon. */
|
/** Returns the {@code ResourceLocation} for this spell's icon. */
|
||||||
public final ResourceLocation getIcon(){
|
public final ResourceLocation getIcon(){
|
||||||
return icon;
|
return icon;
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package electroblob.wizardry.util;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
|
import electroblob.wizardry.spell.Spell;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class which ensures that all spellpack spell networkIDs are distributed in alphabetical order. Introducing this was necessary as mods (especially with
|
||||||
|
* (load-after) dependencies were not always registering their spells in the exact same order. This is definitely
|
||||||
|
*/
|
||||||
|
public class SpellNetworkIDSorter {
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
|
||||||
|
//reorder network IDs based on addon modids. This is necessary as modloading order doesn't seem to be guaranteed to match between various servers and clients
|
||||||
|
Wizardry.logger.debug("Reordering all spell NetworkIDs based on addon modid alphabetical order");
|
||||||
|
|
||||||
|
// the first available ID after all default spells
|
||||||
|
int nextSpellId = (int) Spell.getAllSpells().stream().filter(spell -> spell.getRegistryName().getNamespace().equals(Wizardry.MODID)).count() + 1;
|
||||||
|
List<Spell> addonSpells = Spell.getAllSpells().stream().filter(spell -> !spell.getRegistryName().getNamespace().equals(Wizardry.MODID)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// sorting spells
|
||||||
|
addonSpells.sort(Comparator.comparing((Spell o) -> o.getRegistryName().toString()));
|
||||||
|
for (Spell spell : addonSpells) {
|
||||||
|
Wizardry.logger.debug("Updating networkID of spell " + spell.getRegistryName().toString() + " from " + spell.networkID() + " to " + nextSpellId);
|
||||||
|
spell.setId(nextSpellId++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user