First version
This commit is contained in:
parent
f314a4ccf8
commit
8b0a15413c
@ -12,5 +12,5 @@ halplibe_version=3.5.4
|
|||||||
|
|
||||||
# Mod
|
# Mod
|
||||||
mod_version=1.0.0
|
mod_version=1.0.0
|
||||||
mod_group=turniplabs
|
mod_group=alterdekim
|
||||||
mod_name=examplemod
|
mod_name=offlineskin
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package alterwain.offlineskin;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.ImageParser;
|
||||||
|
|
||||||
|
public interface ForceDownloadHandler {
|
||||||
|
boolean offlineSkinChanger$forceLoadDownloadableTexture(String url, String localTexture, ImageParser imageParser);
|
||||||
|
}
|
67
src/main/java/alterwain/offlineskin/GuiSkinChanger.java
Normal file
67
src/main/java/alterwain/offlineskin/GuiSkinChanger.java
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package alterwain.offlineskin;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.GuiButton;
|
||||||
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
|
import net.minecraft.core.lang.I18n;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
|
import static alterwain.offlineskin.OfflineSkinMod.configPath;
|
||||||
|
|
||||||
|
public class GuiSkinChanger extends GuiScreen {
|
||||||
|
|
||||||
|
private GuiButton buttonLoadSkin;
|
||||||
|
private GuiButton buttonLoadCape;
|
||||||
|
private GuiButton buttonClose;
|
||||||
|
|
||||||
|
|
||||||
|
public GuiSkinChanger(GuiScreen parent) {
|
||||||
|
super(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
I18n stringtranslate = I18n.getInstance();
|
||||||
|
this.controlList.clear();
|
||||||
|
this.controlList.add(this.buttonLoadSkin = new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + 12, stringtranslate.translateKey("gui.options.page.edit_skin.button.load_skin")));
|
||||||
|
this.controlList.add(this.buttonLoadCape = new GuiButton(1, this.width / 2 - 100, this.height / 4 - 10 + 50 + 18 + 20 + 4, 200, 20, stringtranslate.translateKey("gui.options.page.edit_skin.button.load_cape")));
|
||||||
|
this.controlList.add(this.buttonClose = new GuiButton(2, this.width / 2 - 100, this.height / 4 + 120 + 12, stringtranslate.translateKey("gui.options.page.edit_skin.button.close")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void buttonPressed(GuiButton button) {
|
||||||
|
try {
|
||||||
|
if (button.enabled) {
|
||||||
|
if (button.id == 2) {
|
||||||
|
this.mc.displayGuiScreen(this.getParentScreen());
|
||||||
|
} else if (button.id == 0) { // skin
|
||||||
|
File skin = OfflineSkinMod.chooseFile();
|
||||||
|
if (skin != null) {
|
||||||
|
OfflineSkinMod.skinImage = ImageIO.read(skin);
|
||||||
|
Files.copy(skin.toPath(), new File(configPath, "skin.png").toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
} else if (button.id == 1) { // cape
|
||||||
|
File cape = OfflineSkinMod.chooseFile();
|
||||||
|
if (cape != null) {
|
||||||
|
OfflineSkinMod.capeImage = ImageIO.read(cape);
|
||||||
|
Files.copy(cape.toPath(), new File(configPath, "cape.png").toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawScreen(int mouseX, int mouseY, float partialTick) {
|
||||||
|
I18n stringtranslate = I18n.getInstance();
|
||||||
|
this.drawDefaultBackground();
|
||||||
|
this.drawStringCentered(this.fontRenderer, stringtranslate.translateKey("gui.options.page.edit_skin.label.title"), this.width / 2, this.height / 4 - 60 + 20, 16777215);
|
||||||
|
super.drawScreen(mouseX, mouseY, partialTick);
|
||||||
|
}
|
||||||
|
}
|
97
src/main/java/alterwain/offlineskin/OfflineSkinMod.java
Normal file
97
src/main/java/alterwain/offlineskin/OfflineSkinMod.java
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package alterwain.offlineskin;
|
||||||
|
|
||||||
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
import net.minecraft.core.Global;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import turniplabs.halplibe.util.GameStartEntrypoint;
|
||||||
|
import turniplabs.halplibe.util.RecipeEntrypoint;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.filechooser.FileFilter;
|
||||||
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
public class OfflineSkinMod implements ModInitializer, GameStartEntrypoint, RecipeEntrypoint {
|
||||||
|
public static final String MOD_ID = "offlineskin";
|
||||||
|
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||||
|
|
||||||
|
public static File configPath = new File(Global.accessor.getMinecraftDir(), "config/offlineskin");
|
||||||
|
public static BufferedImage skinImage;
|
||||||
|
public static BufferedImage capeImage;
|
||||||
|
public static final Map<String, SkinConfig> skins = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitialize() {
|
||||||
|
LOGGER.info("ExampleMod initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeGameStart() {
|
||||||
|
configPath.mkdirs();
|
||||||
|
try {
|
||||||
|
if (new File(configPath, "skin.png").exists()) {
|
||||||
|
skinImage = ImageIO.read(new File(configPath, "skin.png"));
|
||||||
|
}
|
||||||
|
if (new File(configPath, "cape.png").exists()) {
|
||||||
|
capeImage = ImageIO.read(new File(configPath, "cape.png"));
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterGameStart() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRecipesReady() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initNamespaces() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File chooseFile() {
|
||||||
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
|
FileFilter filter = new FileNameExtensionFilter("PNG File","png");
|
||||||
|
fileChooser.addChoosableFileFilter(filter);
|
||||||
|
int returnValue = fileChooser.showOpenDialog(null);
|
||||||
|
if (returnValue == JFileChooser.APPROVE_OPTION) {
|
||||||
|
return fileChooser.getSelectedFile();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BufferedImage bytesToImage(byte[] b) {
|
||||||
|
try {
|
||||||
|
ByteArrayInputStream is = new ByteArrayInputStream(b);
|
||||||
|
return ImageIO.read(is);
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null; // TODO: read default skin from resources.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] imageToBytes(BufferedImage image) {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
try {
|
||||||
|
ImageIO.write(image, "png", baos);
|
||||||
|
} catch (IOException e) {
|
||||||
|
return new byte[1];
|
||||||
|
}
|
||||||
|
return baos.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
28
src/main/java/alterwain/offlineskin/SendInfo.java
Normal file
28
src/main/java/alterwain/offlineskin/SendInfo.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package alterwain.offlineskin;
|
||||||
|
|
||||||
|
import alterwain.offlineskin.packet.Packet246SkinSet;
|
||||||
|
import net.minecraft.server.entity.player.EntityPlayerMP;
|
||||||
|
|
||||||
|
public class SendInfo extends Thread {
|
||||||
|
|
||||||
|
private EntityPlayerMP player;
|
||||||
|
|
||||||
|
public SendInfo(EntityPlayerMP player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(3000);
|
||||||
|
OfflineSkinMod.skins.keySet().stream().filter(k -> !k.equals(player.username))
|
||||||
|
.forEach(k -> player.playerNetServerHandler.sendPacket(new Packet246SkinSet(k,
|
||||||
|
OfflineSkinMod.imageToBytes(OfflineSkinMod.skins.get(k).getSkin()),
|
||||||
|
OfflineSkinMod.imageToBytes(OfflineSkinMod.skins.get(k).getCape()),
|
||||||
|
OfflineSkinMod.skins.get(k).getModelType()
|
||||||
|
)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
src/main/java/alterwain/offlineskin/SendSet.java
Normal file
29
src/main/java/alterwain/offlineskin/SendSet.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package alterwain.offlineskin;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.EntityRenderDispatcher;
|
||||||
|
import net.minecraft.client.render.PlayerSkinParser;
|
||||||
|
|
||||||
|
public class SendSet extends Thread {
|
||||||
|
|
||||||
|
private final String username;
|
||||||
|
private final boolean isCape;
|
||||||
|
|
||||||
|
public SendSet(String username, boolean isCape) {
|
||||||
|
this.username = username;
|
||||||
|
this.isCape = isCape;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
Thread.sleep(2500);
|
||||||
|
if( isCape ) {
|
||||||
|
((ForceDownloadHandler) EntityRenderDispatcher.instance.renderEngine).offlineSkinChanger$forceLoadDownloadableTexture("offlineCapeLocal:" + this.username, null, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
((ForceDownloadHandler) EntityRenderDispatcher.instance.renderEngine).offlineSkinChanger$forceLoadDownloadableTexture("offlineSkinLocal:"+this.username, null, PlayerSkinParser.instance);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
src/main/java/alterwain/offlineskin/SkinConfig.java
Normal file
27
src/main/java/alterwain/offlineskin/SkinConfig.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package alterwain.offlineskin;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
public class SkinConfig {
|
||||||
|
private BufferedImage skin;
|
||||||
|
private BufferedImage cape;
|
||||||
|
private Boolean modelType;
|
||||||
|
|
||||||
|
public SkinConfig(BufferedImage skin, BufferedImage cape, Boolean modelType) {
|
||||||
|
this.skin = skin;
|
||||||
|
this.cape = cape;
|
||||||
|
this.modelType = modelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage getSkin() {
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage getCape() {
|
||||||
|
return cape;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getModelType() {
|
||||||
|
return modelType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package alterwain.offlineskin;
|
||||||
|
|
||||||
|
|
||||||
|
import alterwain.offlineskin.packet.Packet244SkinRequest;
|
||||||
|
|
||||||
|
public interface SkinRequestHandler {
|
||||||
|
void offlineSkinChanger$handleSkinRequest(Packet244SkinRequest request);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package alterwain.offlineskin;
|
||||||
|
|
||||||
|
import alterwain.offlineskin.packet.Packet245SkinResponse;
|
||||||
|
|
||||||
|
public interface SkinResponseHandler {
|
||||||
|
void offlineSkinChanger$handleSkinResponse(Packet245SkinResponse response);
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package alterwain.offlineskin.mixin;
|
||||||
|
|
||||||
|
import alterwain.offlineskin.OfflineSkinMod;
|
||||||
|
import alterwain.offlineskin.packet.Packet244SkinRequest;
|
||||||
|
import alterwain.offlineskin.packet.Packet245SkinResponse;
|
||||||
|
import alterwain.offlineskin.SkinRequestHandler;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.net.handler.NetClientHandler;
|
||||||
|
import net.minecraft.core.net.NetworkManager;
|
||||||
|
import net.minecraft.core.net.handler.NetHandler;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
@Mixin(NetClientHandler.class)
|
||||||
|
public abstract class NetClientHandlerMixin extends NetHandler implements SkinRequestHandler {
|
||||||
|
@Shadow @Final private NetworkManager netManager;
|
||||||
|
|
||||||
|
@Shadow @Final private Minecraft mc;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void offlineSkinChanger$handleSkinRequest(Packet244SkinRequest request) {
|
||||||
|
this.netManager.addToSendQueue(new Packet245SkinResponse(mc.thePlayer.username,
|
||||||
|
OfflineSkinMod.imageToBytes(OfflineSkinMod.skinImage),
|
||||||
|
OfflineSkinMod.imageToBytes(OfflineSkinMod.capeImage),
|
||||||
|
false));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package alterwain.offlineskin.mixin;
|
||||||
|
|
||||||
|
import alterwain.offlineskin.OfflineSkinMod;
|
||||||
|
import alterwain.offlineskin.SkinConfig;
|
||||||
|
import alterwain.offlineskin.SkinResponseHandler;
|
||||||
|
import alterwain.offlineskin.packet.Packet245SkinResponse;
|
||||||
|
import alterwain.offlineskin.packet.Packet246SkinSet;
|
||||||
|
import net.minecraft.server.net.handler.NetServerHandler;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
@Mixin(NetServerHandler.class)
|
||||||
|
public abstract class NetServerHandlerMixin extends net.minecraft.core.net.handler.NetHandler implements net.minecraft.core.net.ICommandListener,
|
||||||
|
SkinResponseHandler {
|
||||||
|
@Shadow
|
||||||
|
private net.minecraft.server.MinecraftServer mcServer;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void offlineSkinChanger$handleSkinResponse(Packet245SkinResponse response) {
|
||||||
|
OfflineSkinMod.skins.put(response.getUsername(), new SkinConfig(
|
||||||
|
OfflineSkinMod.bytesToImage(response.getSkin()),
|
||||||
|
OfflineSkinMod.bytesToImage(response.getCape()),
|
||||||
|
response.isModelType()
|
||||||
|
));
|
||||||
|
for( int i = 0; i < this.mcServer.playerList.playerEntities.size(); i++ ) {
|
||||||
|
this.mcServer.playerList.playerEntities.get(i)
|
||||||
|
.playerNetServerHandler
|
||||||
|
.sendPacket(new Packet246SkinSet(response.getUsername(), response.getSkin(), response.getCape(), response.isModelType()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package alterwain.offlineskin.mixin;
|
||||||
|
|
||||||
|
import alterwain.offlineskin.GuiSkinChanger;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.options.components.*;
|
||||||
|
import net.minecraft.client.gui.options.data.OptionsPages;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@Mixin(OptionsPages.class)
|
||||||
|
public abstract class OptionsPagesMixin {
|
||||||
|
@Final
|
||||||
|
@Shadow
|
||||||
|
@Mutable
|
||||||
|
private static Minecraft mc;
|
||||||
|
|
||||||
|
@Inject(method = "<clinit>", at = @At("TAIL"))
|
||||||
|
private static void modifyGeneralScreen(CallbackInfo ci) {
|
||||||
|
OptionsPages.GENERAL.withComponent(new ShortcutComponent("gui.options.page.general.button.edit_skin", () -> {
|
||||||
|
mc.displayGuiScreen(new GuiSkinChanger(mc.currentScreen));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
21
src/main/java/alterwain/offlineskin/mixin/PacketMixin.java
Normal file
21
src/main/java/alterwain/offlineskin/mixin/PacketMixin.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package alterwain.offlineskin.mixin;
|
||||||
|
|
||||||
|
import alterwain.offlineskin.packet.Packet244SkinRequest;
|
||||||
|
import alterwain.offlineskin.packet.Packet245SkinResponse;
|
||||||
|
import alterwain.offlineskin.packet.Packet246SkinSet;
|
||||||
|
import net.minecraft.core.net.packet.Packet;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
@Mixin(Packet.class)
|
||||||
|
public abstract class PacketMixin {
|
||||||
|
@Inject(method = "<clinit>", at = @At("TAIL"))
|
||||||
|
private static void modifyPacketsTable(CallbackInfo ci) {
|
||||||
|
Packet.addIdClassMapping(244, true, false, Packet244SkinRequest.class);
|
||||||
|
Packet.addIdClassMapping(245, false, true, Packet245SkinResponse.class);
|
||||||
|
Packet.addIdClassMapping(246, true, false, Packet246SkinSet.class);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
package alterwain.offlineskin.mixin;
|
||||||
|
|
||||||
|
import alterwain.offlineskin.OfflineSkinMod;
|
||||||
|
import alterwain.offlineskin.SendInfo;
|
||||||
|
import alterwain.offlineskin.packet.Packet244SkinRequest;
|
||||||
|
import alterwain.offlineskin.packet.Packet246SkinSet;
|
||||||
|
import net.minecraft.server.entity.player.EntityPlayerMP;
|
||||||
|
import net.minecraft.server.player.PlayerManager;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mixin(PlayerManager.class)
|
||||||
|
public abstract class PlayerManagerMixin {
|
||||||
|
|
||||||
|
@Shadow(remap = false)
|
||||||
|
@Final
|
||||||
|
public List<EntityPlayerMP> players;
|
||||||
|
|
||||||
|
@Inject(method = "addPlayer", at = @At("HEAD"), remap = false)
|
||||||
|
private void onAddPlayer(EntityPlayerMP player, CallbackInfo ci) {
|
||||||
|
player.playerNetServerHandler.sendPacket(new Packet244SkinRequest(true, true, false));
|
||||||
|
new SendInfo(player).start();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,168 @@
|
|||||||
|
package alterwain.offlineskin.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.ImageParser;
|
||||||
|
import net.minecraft.client.render.PlayerSkinParser;
|
||||||
|
import net.minecraft.client.render.block.model.BlockModel;
|
||||||
|
import net.minecraft.client.render.block.model.BlockModelDispatcher;
|
||||||
|
import net.minecraft.client.render.entity.LivingRenderer;
|
||||||
|
import net.minecraft.client.render.entity.PlayerRenderer;
|
||||||
|
import net.minecraft.client.render.model.ModelBase;
|
||||||
|
import net.minecraft.client.render.model.ModelBiped;
|
||||||
|
import net.minecraft.client.render.model.ModelPlayer;
|
||||||
|
import net.minecraft.core.block.Block;
|
||||||
|
import net.minecraft.core.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.core.item.Item;
|
||||||
|
import net.minecraft.core.item.ItemStack;
|
||||||
|
import net.minecraft.core.util.helper.MathHelper;
|
||||||
|
import org.lwjgl.opengl.GL11;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
@Mixin(PlayerRenderer.class)
|
||||||
|
public abstract class PlayerRendererMixin extends LivingRenderer<EntityPlayer> {
|
||||||
|
|
||||||
|
@Shadow(remap = false)
|
||||||
|
private ModelBiped modelBipedMain;
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow(remap = false)
|
||||||
|
private ModelPlayer modelSlim;
|
||||||
|
|
||||||
|
@Final
|
||||||
|
@Shadow(remap = false)
|
||||||
|
private ModelPlayer modelThick;
|
||||||
|
|
||||||
|
|
||||||
|
public PlayerRendererMixin(ModelBase model, float shadowSize) {
|
||||||
|
super(model, shadowSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadEntityTexture(EntityPlayer entity) {
|
||||||
|
this.loadDownloadableTexture("offlineSkinLocal:"+entity.username, entity.getEntityTexture(), PlayerSkinParser.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void drawFirstPersonHand(EntityPlayer player) {
|
||||||
|
player.skinURL = "offlineSkinLocal:"+player.username;
|
||||||
|
this.mainModel = player.slimModel ? this.modelSlim : this.modelThick;
|
||||||
|
this.modelBipedMain = player.slimModel ? this.modelSlim : this.modelThick;
|
||||||
|
this.modelBipedMain.onGround = 0.0F;
|
||||||
|
this.modelBipedMain.isRiding = false;
|
||||||
|
this.modelBipedMain.setRotationAngles(0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0625F);
|
||||||
|
this.modelBipedMain.bipedRightArm.render(0.0625F);
|
||||||
|
if (this.modelBipedMain instanceof ModelPlayer) {
|
||||||
|
((ModelPlayer)this.modelBipedMain).bipedRightArmOverlay.render(0.0625F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderSpecials(EntityPlayer entity, float f) {
|
||||||
|
ItemStack itemstack = entity.inventory.armorItemInSlot(3);
|
||||||
|
if (itemstack != null && itemstack.getItem().id < Block.blocksList.length) {
|
||||||
|
GL11.glPushMatrix();
|
||||||
|
this.modelBipedMain.bipedHead.postRender(0.0625F);
|
||||||
|
if (((BlockModel) BlockModelDispatcher.getInstance().getDispatch(Block.blocksList[itemstack.itemID])).shouldItemRender3d()) {
|
||||||
|
float f1 = 0.625F;
|
||||||
|
GL11.glTranslatef(0.0F, -0.25F, 0.0F);
|
||||||
|
GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F);
|
||||||
|
GL11.glScalef(f1, -f1, f1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderDispatcher.itemRenderer.renderItem(entity, itemstack);
|
||||||
|
GL11.glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean renderCape = this.loadDownloadableTexture("offlineCapeLocal:"+entity.username, (String)null, (ImageParser)null);
|
||||||
|
|
||||||
|
if (renderCape) {
|
||||||
|
GL11.glPushMatrix();
|
||||||
|
GL11.glTranslatef(0.0F, 0.0F, 0.125F);
|
||||||
|
double d = entity.field_20066_r + (entity.field_20063_u - entity.field_20066_r) * (double)f - (entity.xo + (entity.x - entity.xo) * (double)f);
|
||||||
|
double d1 = entity.field_20065_s + (entity.field_20062_v - entity.field_20065_s) * (double)f - (entity.yo + (entity.y - entity.yo) * (double)f);
|
||||||
|
double d2 = entity.field_20064_t + (entity.field_20061_w - entity.field_20064_t) * (double)f - (entity.zo + (entity.z - entity.zo) * (double)f);
|
||||||
|
float f8 = entity.prevRenderYawOffset + (entity.renderYawOffset - entity.prevRenderYawOffset) * f;
|
||||||
|
double d3 = (double) MathHelper.sin(f8 * 3.141593F / 180.0F);
|
||||||
|
double d4 = (double)(-MathHelper.cos(f8 * 3.141593F / 180.0F));
|
||||||
|
float f9 = (float)d1 * 10.0F;
|
||||||
|
if (f9 < -6.0F) {
|
||||||
|
f9 = -6.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f9 > 32.0F) {
|
||||||
|
f9 = 32.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
float f10 = (float)(d * d3 + d2 * d4) * 100.0F;
|
||||||
|
float f11 = (float)(d * d4 - d2 * d3) * 100.0F;
|
||||||
|
if (f10 < 0.0F) {
|
||||||
|
f10 = 0.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
float f12 = entity.field_775_e + (entity.field_774_f - entity.field_775_e) * f;
|
||||||
|
f9 += MathHelper.sin((entity.walkDistO + (entity.walkDist - entity.walkDistO) * f) * 6.0F) * 32.0F * f12;
|
||||||
|
if (entity.isSneaking()) {
|
||||||
|
f9 += 25.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL11.glRotatef(6.0F + f10 / 2.0F + f9, 1.0F, 0.0F, 0.0F);
|
||||||
|
GL11.glRotatef(f11 / 2.0F, 0.0F, 0.0F, 1.0F);
|
||||||
|
GL11.glRotatef(-f11 / 2.0F, 0.0F, 1.0F, 0.0F);
|
||||||
|
GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F);
|
||||||
|
this.modelBipedMain.renderCloak(0.0625F);
|
||||||
|
GL11.glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack itemstack1 = entity.inventory.getCurrentItem();
|
||||||
|
if (itemstack1 != null) {
|
||||||
|
GL11.glPushMatrix();
|
||||||
|
this.modelBipedMain.bipedRightArm.postRender(0.0625F);
|
||||||
|
GL11.glTranslatef(-0.0625F, 0.4375F, 0.0625F);
|
||||||
|
if (entity.fishEntity != null) {
|
||||||
|
itemstack1 = new ItemStack(Item.stick);
|
||||||
|
}
|
||||||
|
|
||||||
|
float f4;
|
||||||
|
if (itemstack1.itemID < Block.blocksList.length && ((BlockModel)BlockModelDispatcher.getInstance().getDispatch(Block.blocksList[itemstack1.itemID])).shouldItemRender3d()) {
|
||||||
|
f4 = 0.5F;
|
||||||
|
GL11.glTranslatef(0.0F, 0.1875F, -0.3125F);
|
||||||
|
f4 *= 0.75F;
|
||||||
|
GL11.glRotatef(20.0F, 1.0F, 0.0F, 0.0F);
|
||||||
|
GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F);
|
||||||
|
GL11.glScalef(f4, -f4, f4);
|
||||||
|
} else if (itemstack1.itemID == Item.toolBow.id) {
|
||||||
|
f4 = 0.625F;
|
||||||
|
GL11.glTranslatef(0.0F, 0.125F, 0.3125F);
|
||||||
|
GL11.glRotatef(-20.0F, 0.0F, 1.0F, 0.0F);
|
||||||
|
GL11.glScalef(f4, -f4, f4);
|
||||||
|
GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F);
|
||||||
|
GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F);
|
||||||
|
} else if (Item.itemsList[itemstack1.itemID].isFull3D()) {
|
||||||
|
f4 = 0.625F;
|
||||||
|
if (Item.itemsList[itemstack1.itemID].shouldRotateAroundWhenRendering()) {
|
||||||
|
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
|
||||||
|
GL11.glTranslatef(0.0F, -0.125F, 0.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Item.itemsList[itemstack1.itemID].shouldPointInFrontOfPlayer()) {
|
||||||
|
GL11.glRotatef(-20.0F, 0.0F, 1.0F, 0.0F);
|
||||||
|
GL11.glTranslatef(0.0F, -0.125F, 0.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
GL11.glTranslatef(0.0F, 0.1875F, 0.0F);
|
||||||
|
GL11.glScalef(f4, -f4, f4);
|
||||||
|
GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F);
|
||||||
|
GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F);
|
||||||
|
} else {
|
||||||
|
f4 = 0.375F;
|
||||||
|
GL11.glTranslatef(0.25F, 0.1875F, -0.1875F);
|
||||||
|
GL11.glScalef(f4, f4, f4);
|
||||||
|
GL11.glRotatef(60.0F, 0.0F, 0.0F, 1.0F);
|
||||||
|
GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F);
|
||||||
|
GL11.glRotatef(20.0F, 0.0F, 0.0F, 1.0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderDispatcher.itemRenderer.renderItem(entity, itemstack1);
|
||||||
|
GL11.glPopMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
107
src/main/java/alterwain/offlineskin/mixin/RenderEngineMixin.java
Normal file
107
src/main/java/alterwain/offlineskin/mixin/RenderEngineMixin.java
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package alterwain.offlineskin.mixin;
|
||||||
|
|
||||||
|
import alterwain.offlineskin.ForceDownloadHandler;
|
||||||
|
import alterwain.offlineskin.OfflineSkinMod;
|
||||||
|
import net.minecraft.client.render.DownloadedTexture;
|
||||||
|
import net.minecraft.client.render.ImageParser;
|
||||||
|
import net.minecraft.client.render.RenderEngine;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mixin(RenderEngine.class)
|
||||||
|
public abstract class RenderEngineMixin implements ForceDownloadHandler {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private Map<String, DownloadedTexture> downloadedTextures;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract int allocateAndSetupTexture(BufferedImage bufferedimage);
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract void bindTexture(int i);
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
public abstract int getTexture(String name);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean offlineSkinChanger$forceLoadDownloadableTexture(String url, String localTexture, ImageParser imageParser) {
|
||||||
|
DownloadedTexture texture = new DownloadedTexture(null, imageParser);
|
||||||
|
if( url.startsWith("offlineSkinLocal") ) {
|
||||||
|
if( OfflineSkinMod.skins.containsKey(url.substring(17)) ) {
|
||||||
|
texture.image = OfflineSkinMod.skins.get(url.substring(17)).getSkin();
|
||||||
|
} else {
|
||||||
|
texture.image = OfflineSkinMod.skinImage;
|
||||||
|
}
|
||||||
|
} else if( url.startsWith("offlineCapeLocal") ) {
|
||||||
|
if( OfflineSkinMod.skins.containsKey(url.substring(17))) {
|
||||||
|
texture.image = OfflineSkinMod.skins.get(url.substring(17)).getCape();
|
||||||
|
} else {
|
||||||
|
texture.image = OfflineSkinMod.capeImage;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
texture = new DownloadedTexture(url, imageParser);
|
||||||
|
}
|
||||||
|
this.downloadedTextures.put(url, texture);
|
||||||
|
|
||||||
|
|
||||||
|
if (texture.textureId < 0 && texture.image != null) {
|
||||||
|
texture.textureId = this.allocateAndSetupTexture(texture.image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture.textureId > 0) {
|
||||||
|
this.bindTexture(texture.textureId);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean loadDownloadableTexture(String url, String localTexture, ImageParser imageParser) {
|
||||||
|
if (url == null) {
|
||||||
|
if (localTexture != null) {
|
||||||
|
this.bindTexture(this.getTexture(localTexture));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DownloadedTexture texture = (DownloadedTexture)this.downloadedTextures.get(url);
|
||||||
|
if (texture == null) {
|
||||||
|
texture = new DownloadedTexture(null, imageParser);
|
||||||
|
if( url.startsWith("offlineSkinLocal") ) {
|
||||||
|
if( OfflineSkinMod.skins.containsKey(url.substring(17)) ) {
|
||||||
|
texture.image = OfflineSkinMod.skins.get(url.substring(17)).getSkin();
|
||||||
|
} else {
|
||||||
|
texture.image = OfflineSkinMod.skinImage;
|
||||||
|
}
|
||||||
|
} else if( url.startsWith("offlineCapeLocal") ) {
|
||||||
|
if( OfflineSkinMod.skins.containsKey(url.substring(17))) {
|
||||||
|
texture.image = OfflineSkinMod.skins.get(url.substring(17)).getCape();
|
||||||
|
} else {
|
||||||
|
texture.image = OfflineSkinMod.capeImage;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
texture = new DownloadedTexture(url, imageParser);
|
||||||
|
}
|
||||||
|
this.downloadedTextures.put(url, texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture.textureId < 0 && texture.image != null) {
|
||||||
|
texture.textureId = this.allocateAndSetupTexture(texture.image);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texture.textureId > 0) {
|
||||||
|
this.bindTexture(texture.textureId);
|
||||||
|
return true;
|
||||||
|
} else if (localTexture != null) {
|
||||||
|
this.bindTexture(this.getTexture(localTexture));
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package alterwain.offlineskin.packet;
|
||||||
|
|
||||||
|
import alterwain.offlineskin.SkinRequestHandler;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class Packet244SkinRequest extends Packet {
|
||||||
|
|
||||||
|
private boolean requestSkin;
|
||||||
|
private boolean requestCape;
|
||||||
|
private boolean requestModelType;
|
||||||
|
|
||||||
|
public Packet244SkinRequest() {}
|
||||||
|
|
||||||
|
public Packet244SkinRequest(boolean requestSkin, boolean requestCape, boolean requestModelType) {
|
||||||
|
this.requestSkin = requestSkin;
|
||||||
|
this.requestCape = requestCape;
|
||||||
|
this.requestModelType = requestModelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readPacketData(DataInputStream dis) throws IOException {
|
||||||
|
this.requestSkin = dis.readBoolean();
|
||||||
|
this.requestCape = dis.readBoolean();
|
||||||
|
this.requestModelType = dis.readBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writePacketData(DataOutputStream dos) throws IOException {
|
||||||
|
dos.writeBoolean(this.requestSkin);
|
||||||
|
dos.writeBoolean(this.requestCape);
|
||||||
|
dos.writeBoolean(this.requestModelType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processPacket(NetHandler netHandler) {
|
||||||
|
((SkinRequestHandler) netHandler).offlineSkinChanger$handleSkinRequest(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPacketSize() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
package alterwain.offlineskin.packet;
|
||||||
|
|
||||||
|
import alterwain.offlineskin.SkinResponseHandler;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class Packet245SkinResponse extends Packet {
|
||||||
|
private String username;
|
||||||
|
private byte[] skin;
|
||||||
|
private byte[] cape;
|
||||||
|
private boolean modelType;
|
||||||
|
|
||||||
|
public Packet245SkinResponse(String username, byte[] skin, byte[] cape, boolean modelType) {
|
||||||
|
this.username = username;
|
||||||
|
this.skin = skin;
|
||||||
|
this.cape = cape;
|
||||||
|
this.modelType = modelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packet245SkinResponse() {
|
||||||
|
this.username = "";
|
||||||
|
this.skin = new byte[0];
|
||||||
|
this.cape = new byte[0];
|
||||||
|
this.modelType = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readPacketData(DataInputStream dis) throws IOException {
|
||||||
|
int nameLen = dis.readInt();
|
||||||
|
byte[] ub = new byte[nameLen];
|
||||||
|
dis.read(ub);
|
||||||
|
this.username = new String(ub);
|
||||||
|
int skinLen = dis.readInt();
|
||||||
|
this.skin = new byte[skinLen];
|
||||||
|
dis.read(this.skin);
|
||||||
|
int capeLen = dis.readInt();
|
||||||
|
this.cape = new byte[capeLen];
|
||||||
|
dis.read(cape);
|
||||||
|
this.modelType = dis.readBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writePacketData(DataOutputStream dos) throws IOException {
|
||||||
|
dos.writeInt(username.length());
|
||||||
|
dos.write(username.getBytes());
|
||||||
|
dos.writeInt(skin.length);
|
||||||
|
dos.write(skin);
|
||||||
|
dos.writeInt(cape.length);
|
||||||
|
dos.write(cape);
|
||||||
|
dos.writeBoolean(modelType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processPacket(NetHandler netHandler) {
|
||||||
|
((SkinResponseHandler) netHandler).offlineSkinChanger$handleSkinResponse(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getSkin() {
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getCape() {
|
||||||
|
return cape;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isModelType() {
|
||||||
|
return modelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPacketSize() {
|
||||||
|
return skin.length+cape.length+username.length()+13;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package alterwain.offlineskin.packet;
|
||||||
|
|
||||||
|
import alterwain.offlineskin.OfflineSkinMod;
|
||||||
|
import alterwain.offlineskin.SendSet;
|
||||||
|
import alterwain.offlineskin.SkinConfig;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.render.EntityRenderDispatcher;
|
||||||
|
import net.minecraft.client.render.entity.PlayerRenderer;
|
||||||
|
import net.minecraft.core.entity.player.EntityPlayer;
|
||||||
|
import net.minecraft.core.net.handler.NetHandler;
|
||||||
|
import net.minecraft.core.net.packet.Packet;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class Packet246SkinSet extends Packet {
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
private byte[] skin;
|
||||||
|
private byte[] cape;
|
||||||
|
private boolean modelType;
|
||||||
|
|
||||||
|
public Packet246SkinSet(String username, byte[] skin, byte[] cape, boolean modelType) {
|
||||||
|
this.username = username;
|
||||||
|
this.skin = skin;
|
||||||
|
this.cape = cape;
|
||||||
|
this.modelType = modelType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packet246SkinSet() {
|
||||||
|
this.username = "";
|
||||||
|
this.skin = new byte[0];
|
||||||
|
this.cape = new byte[0];
|
||||||
|
this.modelType = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readPacketData(DataInputStream dis) throws IOException {
|
||||||
|
int nameLen = dis.readInt();
|
||||||
|
byte[] ub = new byte[nameLen];
|
||||||
|
dis.read(ub);
|
||||||
|
this.username = new String(ub);
|
||||||
|
int skinLen = dis.readInt();
|
||||||
|
this.skin = new byte[skinLen];
|
||||||
|
dis.read(this.skin);
|
||||||
|
int capeLen = dis.readInt();
|
||||||
|
this.cape = new byte[capeLen];
|
||||||
|
dis.read(cape);
|
||||||
|
this.modelType = dis.readBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writePacketData(DataOutputStream dos) throws IOException {
|
||||||
|
dos.writeInt(username.length());
|
||||||
|
dos.write(username.getBytes());
|
||||||
|
dos.writeInt(skin.length);
|
||||||
|
dos.write(skin);
|
||||||
|
dos.writeInt(cape.length);
|
||||||
|
dos.write(cape);
|
||||||
|
dos.writeBoolean(modelType);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processPacket(NetHandler netHandler) {
|
||||||
|
BufferedImage skin1 = OfflineSkinMod.bytesToImage(this.skin);
|
||||||
|
BufferedImage cape1 = OfflineSkinMod.bytesToImage(this.cape);
|
||||||
|
OfflineSkinMod.skins.put(this.username, new SkinConfig(skin1, cape1, this.modelType));
|
||||||
|
new SendSet(this.username, false).start();
|
||||||
|
new SendSet(this.username, true).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPacketSize() {
|
||||||
|
return skin.length+cape.length+username.length()+13;
|
||||||
|
}
|
||||||
|
}
|
@ -1,38 +0,0 @@
|
|||||||
package turniplabs.examplemod;
|
|
||||||
|
|
||||||
import net.fabricmc.api.ModInitializer;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import turniplabs.halplibe.helper.BlockBuilder;
|
|
||||||
import turniplabs.halplibe.util.GameStartEntrypoint;
|
|
||||||
import turniplabs.halplibe.util.RecipeEntrypoint;
|
|
||||||
|
|
||||||
|
|
||||||
public class ExampleMod implements ModInitializer, GameStartEntrypoint, RecipeEntrypoint {
|
|
||||||
public static final String MOD_ID = "examplemod";
|
|
||||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
|
||||||
@Override
|
|
||||||
public void onInitialize() {
|
|
||||||
LOGGER.info("ExampleMod initialized.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void beforeGameStart() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterGameStart() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRecipesReady() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void initNamespaces() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"required": true,
|
|
||||||
"minVersion": "0.8",
|
|
||||||
"package": "turniplabs.examplemod.mixin",
|
|
||||||
"compatibilityLevel": "JAVA_8",
|
|
||||||
"mixins": [
|
|
||||||
],
|
|
||||||
"client": [
|
|
||||||
],
|
|
||||||
"injectors": {
|
|
||||||
"defaultRequire": 1
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"schemaVersion": 1,
|
"schemaVersion": 1,
|
||||||
"id": "examplemod",
|
"id": "offlineskin",
|
||||||
"version": "${version}",
|
"version": "${version}",
|
||||||
|
|
||||||
"name": "Example Mod",
|
"name": "Offline Skins",
|
||||||
"description": "This mod aims to help new BTA modders.",
|
"description": "This mod allows you to change skin/cape without purchased Minecraft.",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Turnip Labs"
|
"alterwain"
|
||||||
],
|
],
|
||||||
"contact": {
|
"contact": {
|
||||||
"homepage": "",
|
"homepage": "https://github.com/alterdekim/OfflineSkinChanger",
|
||||||
"sources": ""
|
"sources": "https://github.com/alterdekim/OfflineSkinChanger"
|
||||||
},
|
},
|
||||||
|
|
||||||
"icon": "icon.png",
|
"icon": "icon.png",
|
||||||
@ -19,20 +19,20 @@
|
|||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"main": [
|
"main": [
|
||||||
"turniplabs.examplemod.ExampleMod"
|
"alterwain.offlineskin.OfflineSkinMod"
|
||||||
],
|
],
|
||||||
"beforeGameStart": [
|
"beforeGameStart": [
|
||||||
"turniplabs.examplemod.ExampleMod"
|
"alterwain.offlineskin.OfflineSkinMod"
|
||||||
],
|
],
|
||||||
"afterGameStart": [
|
"afterGameStart": [
|
||||||
"turniplabs.examplemod.ExampleMod"
|
"alterwain.offlineskin.OfflineSkinMod"
|
||||||
],
|
],
|
||||||
"recipesReady": [
|
"recipesReady": [
|
||||||
"turniplabs.examplemod.ExampleMod"
|
"alterwain.offlineskin.OfflineSkinMod"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"examplemod.mixins.json"
|
"offlineskin.mixins.json"
|
||||||
],
|
],
|
||||||
|
|
||||||
"depends": {
|
"depends": {
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 750 B |
5
src/main/resources/lang/offlineskin/en_US.lang
Normal file
5
src/main/resources/lang/offlineskin/en_US.lang
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
gui.options.page.general.button.edit_skin=Edit player\'s skin
|
||||||
|
gui.options.page.edit_skin.button.load_skin=Load skin
|
||||||
|
gui.options.page.edit_skin.button.load_cape=Load cape
|
||||||
|
gui.options.page.edit_skin.button.close=Close
|
||||||
|
gui.options.page.edit_skin.label.title=Change skin/cape
|
20
src/main/resources/offlineskin.mixins.json
Normal file
20
src/main/resources/offlineskin.mixins.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"required": true,
|
||||||
|
"minVersion": "0.8",
|
||||||
|
"package": "alterwain.offlineskin.mixin",
|
||||||
|
"compatibilityLevel": "JAVA_8",
|
||||||
|
"mixins": [
|
||||||
|
"NetClientHandlerMixin",
|
||||||
|
"NetServerHandlerMixin",
|
||||||
|
"OptionsPagesMixin",
|
||||||
|
"PacketMixin",
|
||||||
|
"PlayerManagerMixin",
|
||||||
|
"PlayerRendererMixin",
|
||||||
|
"RenderEngineMixin"
|
||||||
|
],
|
||||||
|
"client": [
|
||||||
|
],
|
||||||
|
"injectors": {
|
||||||
|
"defaultRequire": 1
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user