-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #33 from UselessBullets/ModListPacket
ModVersionHelper
- Loading branch information
Showing
11 changed files
with
339 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
src/main/java/turniplabs/halplibe/helper/ModVersionHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package turniplabs.halplibe.helper; | ||
|
||
import net.fabricmc.loader.api.FabricLoader; | ||
import net.fabricmc.loader.api.ModContainer; | ||
import net.fabricmc.loader.api.Version; | ||
import net.minecraft.client.Minecraft; | ||
import net.minecraft.core.Global; | ||
import turniplabs.halplibe.HalpLibe; | ||
import turniplabs.halplibe.util.version.EnumModList; | ||
import turniplabs.halplibe.util.version.ModInfo; | ||
import turniplabs.halplibe.util.version.PacketModList; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class ModVersionHelper { | ||
protected static boolean isDev = FabricLoader.getInstance().isDevelopmentEnvironment(); | ||
protected static List<ModInfo> localMods = new ArrayList<>(); | ||
protected static List<ModInfo> serverMods = null; | ||
static { | ||
for (ModContainer modContainer: FabricLoader.getInstance().getAllMods()) { | ||
if (modContainer.getMetadata().getType().equals("fabric") && !modContainer.getMetadata().getId().equals("fabricloader")){ | ||
localMods.add(new ModInfo(modContainer)); | ||
} | ||
} | ||
} | ||
public static void initialize(){} | ||
|
||
/** | ||
* @return List of mods installed in the current environment. | ||
*/ | ||
public static List<ModInfo> getLocalModlist(){ | ||
return localMods; | ||
} | ||
|
||
/** | ||
* @return List of mods from the current server, returns null if not connected to a server or the server does not support the mod list packet. | ||
*/ | ||
public static List<ModInfo> getServerModlist(){ | ||
if (isClientOfServer()){ | ||
return serverMods; | ||
} | ||
return null; | ||
} | ||
/** | ||
* @return Returns local mods when in single player or called from the server, returns server mods when a client of server | ||
*/ | ||
public static List<ModInfo> getActiveModlist(){ | ||
if (isClientOfServer()){ | ||
return getServerModlist(); | ||
} | ||
return getLocalModlist(); | ||
} | ||
|
||
/** | ||
* @return Returns true only if the player is currently connected to a server. | ||
*/ | ||
public static boolean isClientOfServer(){ | ||
if (Global.isServer){ | ||
return false; | ||
} | ||
Minecraft mc = Minecraft.getMinecraft(Minecraft.class); | ||
return mc.theWorld != null && mc.theWorld.isClientSide; | ||
} | ||
/** | ||
* @return Returns true if the mod is present in the active mod list | ||
*/ | ||
public static boolean isModPresent(String modIdToCheck){ | ||
return isModPresent(modIdToCheck, EnumModList.ACTIVE); | ||
} | ||
/** | ||
* @return Returns true if the mod is present in the specified mod list | ||
*/ | ||
public static boolean isModPresent(String modIdToCheck, EnumModList modList){ | ||
return getModInfo(modIdToCheck, modList) != null; | ||
} | ||
/** | ||
* @return Returns 0 if versions match exactly, returns a positive integer when mod has a greater version number, returns a negative integer when a mod has a smaller version number, returns null if mod is not present or comparison fails. | ||
*/ | ||
public static Integer isVersionPresent(String modIdToCheck, Version version){ | ||
return isVersionPresent(modIdToCheck, version, EnumModList.ACTIVE); | ||
} | ||
/** | ||
* @return Returns 0 if versions match exactly, returns a positive integer when mod has a greater version number, returns a negative integer when a mod has a smaller version number, returns null if mod is not present or comparison fails. | ||
*/ | ||
public static Integer isVersionPresent(String modIdToCheck, Version version, EnumModList modList){ | ||
ModInfo modInfo = getModInfo(modIdToCheck, modList); | ||
if (modInfo == null) return null; | ||
return modInfo.version.compareTo(version); | ||
} | ||
/** | ||
* @return Returns the specified mod info if present, returns null if not present | ||
*/ | ||
public static ModInfo getModInfo(String modId, EnumModList modList){ | ||
List<ModInfo> modInfoList = getModList(modList); | ||
if (modInfoList == null) return null; | ||
for (ModInfo info: modInfoList) { | ||
if (info.id.equals(modId)) return info; | ||
} | ||
return null; | ||
} | ||
/** | ||
* @return Returns the specified mod list. | ||
*/ | ||
public static List<ModInfo> getModList(EnumModList modList){ | ||
switch (modList){ | ||
case LOCAL: | ||
return getLocalModlist(); | ||
case SERVER: | ||
return getServerModlist(); | ||
case ACTIVE: | ||
return getActiveModlist(); | ||
default: | ||
return null; | ||
} | ||
} | ||
protected static void handleModListPacket(PacketModList packetModList){ | ||
serverMods = packetModList.modInfos; | ||
if (isDev){ | ||
printModList(); | ||
} | ||
|
||
} | ||
protected static void printModList(){ | ||
HalpLibe.LOGGER.info("Server Mod List"); | ||
if (getServerModlist() != null){ | ||
for (ModInfo info: getServerModlist()) { | ||
HalpLibe.LOGGER.info(info.id + " " + info.version); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
src/main/java/turniplabs/halplibe/mixin/mixins/version/NetClientHandlerMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package turniplabs.halplibe.mixin.mixins.version; | ||
|
||
import net.minecraft.client.net.handler.NetClientHandler; | ||
import net.minecraft.core.net.handler.NetHandler; | ||
import net.minecraft.core.net.packet.Packet2Handshake; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Unique; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
import turniplabs.halplibe.HalpLibe; | ||
import turniplabs.halplibe.helper.ModVersionHelper; | ||
import turniplabs.halplibe.util.version.IVersionPackets; | ||
import turniplabs.halplibe.util.version.PacketModList; | ||
|
||
import java.lang.reflect.Field; | ||
import java.lang.reflect.Method; | ||
|
||
@Mixin(value = NetClientHandler.class, remap = false) | ||
public abstract class NetClientHandlerMixin extends NetHandler implements IVersionPackets { | ||
@Unique | ||
public void handleModList(PacketModList packetModList) { | ||
try { | ||
Method m = ModVersionHelper.class.getDeclaredMethod("handleModListPacket", PacketModList.class); | ||
m.setAccessible(true); | ||
m.invoke(null, packetModList); | ||
m.setAccessible(false); | ||
} catch (Throwable err) { | ||
err.printStackTrace(); | ||
} | ||
} | ||
@Inject(method = "handleHandshake(Lnet/minecraft/core/net/packet/Packet2Handshake;)V", at = @At("HEAD")) | ||
private void resetServerModlist(Packet2Handshake packet2handshake, CallbackInfo ci){ | ||
try { | ||
Field m = ModVersionHelper.class.getDeclaredField("serverMods"); | ||
m.setAccessible(true); | ||
m.set(null, null); | ||
m.setAccessible(false); | ||
} catch (Throwable err) { | ||
err.printStackTrace(); | ||
} | ||
HalpLibe.LOGGER.info(String.valueOf(ModVersionHelper.getServerModlist() == null)); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/turniplabs/halplibe/mixin/mixins/version/NetHandlerMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package turniplabs.halplibe.mixin.mixins.version; | ||
|
||
import net.minecraft.core.net.handler.NetHandler; | ||
import net.minecraft.core.net.packet.Packet; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.Shadow; | ||
import org.spongepowered.asm.mixin.Unique; | ||
import turniplabs.halplibe.util.version.IVersionPackets; | ||
import turniplabs.halplibe.util.version.PacketModList; | ||
@Mixin(value = NetHandler.class, remap = false) | ||
public abstract class NetHandlerMixin implements IVersionPackets { | ||
@Shadow public abstract void handleInvalidPacket(Packet packet); | ||
|
||
@Unique | ||
public void handleModList(PacketModList packetModList) { | ||
handleInvalidPacket(packetModList); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/turniplabs/halplibe/mixin/mixins/version/NetLoginHandlerMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package turniplabs.halplibe.mixin.mixins.version; | ||
|
||
import net.minecraft.core.net.packet.Packet1Login; | ||
import net.minecraft.server.entity.player.EntityPlayerMP; | ||
import net.minecraft.server.net.handler.NetLoginHandler; | ||
import org.spongepowered.asm.mixin.Mixin; | ||
import org.spongepowered.asm.mixin.injection.At; | ||
import org.spongepowered.asm.mixin.injection.Inject; | ||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; | ||
import turniplabs.halplibe.helper.ModVersionHelper; | ||
import turniplabs.halplibe.util.version.PacketModList; | ||
|
||
@Mixin(value = NetLoginHandler.class, remap = false) | ||
public class NetLoginHandlerMixin { | ||
@Inject(method = "doLogin(Lnet/minecraft/core/net/packet/Packet1Login;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/net/handler/NetServerHandler;sendPacket(Lnet/minecraft/core/net/packet/Packet;)V", ordinal = 6, shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD) | ||
private void modlistPacket(Packet1Login packet1login, CallbackInfo ci, EntityPlayerMP entityplayermp){ | ||
entityplayermp.playerNetServerHandler.sendPacket(new PacketModList(ModVersionHelper.getLocalModlist())); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/turniplabs/halplibe/util/version/EnumModList.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package turniplabs.halplibe.util.version; | ||
|
||
public enum EnumModList { | ||
LOCAL, | ||
SERVER, | ||
ACTIVE; | ||
} |
5 changes: 5 additions & 0 deletions
5
src/main/java/turniplabs/halplibe/util/version/IVersionPackets.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package turniplabs.halplibe.util.version; | ||
|
||
public interface IVersionPackets { | ||
void handleModList(PacketModList packetModList); | ||
} |
51 changes: 51 additions & 0 deletions
51
src/main/java/turniplabs/halplibe/util/version/ModInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package turniplabs.halplibe.util.version; | ||
|
||
import net.fabricmc.loader.api.ModContainer; | ||
import net.fabricmc.loader.api.Version; | ||
import net.fabricmc.loader.impl.util.version.StringVersion; | ||
|
||
import java.io.DataInputStream; | ||
import java.io.DataOutputStream; | ||
import java.io.IOException; | ||
|
||
public class ModInfo { | ||
public String id; | ||
public Version version; | ||
public ModInfo(DataInputStream dataInputStream) throws IOException { | ||
unpack(dataInputStream); | ||
} | ||
public ModInfo(ModContainer container){ | ||
this(container.getMetadata().getId(), container.getMetadata().getVersion()); | ||
} | ||
public ModInfo(String id, Version version){ | ||
if (id.equals("")){ | ||
id = "Unknown ID"; | ||
} | ||
this.id = id; | ||
if (version.getFriendlyString().equals("")){ | ||
version = new StringVersion("-1.-1.-1"); | ||
} | ||
this.version = version; | ||
} | ||
public void pack(DataOutputStream dos) throws IOException { | ||
dos.writeChars(id); | ||
dos.writeChar(3); | ||
dos.writeChars(version.getFriendlyString()); | ||
dos.writeChar(3); | ||
} | ||
public void unpack(DataInputStream dis) throws IOException { | ||
id = readString(dis); | ||
version = new StringVersion(readString(dis)); | ||
} | ||
public String readString(DataInputStream dis) throws IOException { | ||
char data = 0; | ||
StringBuilder stringBuilder = new StringBuilder(); | ||
while (data != 3){ | ||
data = dis.readChar(); | ||
if (data != 3){ | ||
stringBuilder.append(data); | ||
} | ||
} | ||
return stringBuilder.toString(); | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
src/main/java/turniplabs/halplibe/util/version/PacketModList.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package turniplabs.halplibe.util.version; | ||
|
||
import net.minecraft.core.net.handler.NetHandler; | ||
import net.minecraft.core.net.packet.Packet; | ||
|
||
import java.io.DataInputStream; | ||
import java.io.DataOutputStream; | ||
import java.io.IOException; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class PacketModList extends Packet { | ||
public List<ModInfo> modInfos = new ArrayList<>(); | ||
public PacketModList(){ | ||
|
||
} | ||
public PacketModList(List<ModInfo> modInfos){ | ||
this.modInfos = modInfos; | ||
} | ||
@Override | ||
public void readPacketData(DataInputStream dataInputStream) throws IOException { | ||
this.modInfos = new ArrayList<>(); | ||
char data = 0; | ||
while (data != 127){ | ||
modInfos.add(new ModInfo(dataInputStream)); | ||
data = dataInputStream.readChar(); | ||
} | ||
} | ||
|
||
@Override | ||
public void writePacketData(DataOutputStream dataOutputStream) throws IOException { | ||
int size = modInfos.size(); | ||
for (int i = 0; i < size; i++) { | ||
modInfos.get(i).pack(dataOutputStream); | ||
if (i == size -1){ | ||
dataOutputStream.writeChar(127); | ||
} else { | ||
dataOutputStream.writeChar(3); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void processPacket(NetHandler netHandler) { | ||
((IVersionPackets)netHandler).handleModList(this); | ||
} | ||
|
||
@Override | ||
public int getPacketSize() { | ||
return 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters