144 lines
5.8 KiB
Java
144 lines
5.8 KiB
Java
package org.dynmap;
|
|
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.net.URL;
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.Event.Type;
|
|
import org.bukkit.event.player.PlayerListener;
|
|
import org.bukkit.event.player.PlayerLoginEvent;
|
|
import org.dynmap.MapType.ImageFormat;
|
|
import org.dynmap.debug.Debug;
|
|
import org.dynmap.utils.DynmapBufferedImage;
|
|
import org.dynmap.utils.FileLockManager;
|
|
|
|
/**
|
|
* Listen for player logins, and process player faces by fetching skins *
|
|
*/
|
|
public class PlayerFaces {
|
|
private DynmapPlugin plugin;
|
|
private File facesdir;
|
|
private File faces8x8dir;
|
|
private File faces16x16dir;
|
|
private File faces32x32dir;
|
|
|
|
|
|
private class LoadPlayerImages implements Runnable {
|
|
public String playername;
|
|
public LoadPlayerImages(String playername) {
|
|
this.playername = playername;
|
|
}
|
|
public void run() {
|
|
BufferedImage img = null;
|
|
try {
|
|
URL url = new URL("http://s3.amazonaws.com/MinecraftSkins/" + playername + ".png");
|
|
img = ImageIO.read(url); /* Load skin for player */
|
|
} catch (IOException iox) {
|
|
Debug.debug("Error loading skin for '" + playername + "' - " + iox);
|
|
}
|
|
if(img == null) {
|
|
try {
|
|
InputStream in = getClass().getResourceAsStream("/char.png");
|
|
img = ImageIO.read(in); /* Load generic skin for player */
|
|
in.close();
|
|
} catch (IOException iox) {
|
|
Debug.debug("Error loading default skin for '" + playername + "' - " + iox);
|
|
}
|
|
}
|
|
if(img == null) { /* No image to process? Quit */
|
|
return;
|
|
}
|
|
int[] faceaccessory = new int[64]; /* 8x8 of face accessory */
|
|
/* Get buffered image for face at 8x8 */
|
|
DynmapBufferedImage face8x8 = DynmapBufferedImage.allocateBufferedImage(8, 8);
|
|
img.getRGB(8, 8, 8, 8, face8x8.argb_buf, 0, 8); /* Read face from image */
|
|
img.getRGB(40, 8, 8, 8, faceaccessory, 0, 8); /* Read face accessory from image */
|
|
/* Apply accessory to face: see if anything is transparent (if so, apply accessory */
|
|
boolean transp = false;
|
|
for(int i = 0; i < 64; i++) {
|
|
if((faceaccessory[i] & 0xFF000000) == 0) {
|
|
transp = true;
|
|
break;
|
|
}
|
|
}
|
|
if(transp) {
|
|
for(int i = 0; i < 64; i++) {
|
|
if((faceaccessory[i] & 0xFF000000) != 0)
|
|
face8x8.argb_buf[i] = faceaccessory[i];
|
|
}
|
|
}
|
|
/* Write 8x8 file */
|
|
File img_8x8 = new File(faces8x8dir, playername + ".png");
|
|
FileLockManager.getWriteLock(img_8x8);
|
|
try {
|
|
FileLockManager.imageIOWrite(face8x8.buf_img, ImageFormat.FORMAT_PNG, img_8x8);
|
|
} catch (IOException iox) {
|
|
Log.severe("Cannot write player icon " + img_8x8.getPath());
|
|
}
|
|
FileLockManager.releaseWriteLock(img_8x8);
|
|
/* Make 16x16 version */
|
|
DynmapBufferedImage face16x16 = DynmapBufferedImage.allocateBufferedImage(16, 16);
|
|
for(int i = 0; i < 16; i++) {
|
|
for(int j = 0; j < 16; j++) {
|
|
face16x16.argb_buf[i*16+j] = face8x8.argb_buf[(i/2)*8 + (j/2)];
|
|
}
|
|
}
|
|
/* Write 16x16 file */
|
|
File img_16x16 = new File(faces16x16dir, playername + ".png");
|
|
FileLockManager.getWriteLock(img_16x16);
|
|
try {
|
|
FileLockManager.imageIOWrite(face16x16.buf_img, ImageFormat.FORMAT_PNG, img_16x16);
|
|
} catch (IOException iox) {
|
|
Log.severe("Cannot write player icon " + img_16x16.getPath());
|
|
}
|
|
FileLockManager.releaseWriteLock(img_16x16);
|
|
DynmapBufferedImage.freeBufferedImage(face16x16);
|
|
|
|
/* Make 32x32 version */
|
|
DynmapBufferedImage face32x32 = DynmapBufferedImage.allocateBufferedImage(32, 32);
|
|
for(int i = 0; i < 32; i++) {
|
|
for(int j = 0; j < 32; j++) {
|
|
face32x32.argb_buf[i*32+j] = face8x8.argb_buf[(i/4)*8 + (j/4)];
|
|
}
|
|
}
|
|
/* Write 32x32 file */
|
|
File img_32x32 = new File(faces32x32dir, playername + ".png");
|
|
FileLockManager.getWriteLock(img_32x32);
|
|
try {
|
|
FileLockManager.imageIOWrite(face32x32.buf_img, ImageFormat.FORMAT_PNG, img_32x32);
|
|
} catch (IOException iox) {
|
|
Log.severe("Cannot write player icon " + img_32x32.getPath());
|
|
}
|
|
FileLockManager.releaseWriteLock(img_32x32);
|
|
DynmapBufferedImage.freeBufferedImage(face32x32);
|
|
|
|
DynmapBufferedImage.freeBufferedImage(face8x8);
|
|
/* TODO: signal update for player icon to client */
|
|
}
|
|
}
|
|
private class LoginListener extends PlayerListener {
|
|
@Override
|
|
public void onPlayerLogin(PlayerLoginEvent event) {
|
|
MapManager.scheduleDelayedJob(new LoadPlayerImages(event.getPlayer().getName()), 0);
|
|
}
|
|
}
|
|
public PlayerFaces(DynmapPlugin plugin) {
|
|
this.plugin = plugin;
|
|
plugin.registerEvent(Type.PLAYER_LOGIN, new LoginListener());
|
|
facesdir = new File(plugin.tilesDirectory, "faces");
|
|
facesdir.mkdirs(); /* Make sure directory exists */
|
|
faces8x8dir = new File(facesdir, "8x8");
|
|
faces8x8dir.mkdirs();
|
|
faces16x16dir = new File(facesdir, "16x16");
|
|
faces16x16dir.mkdirs();
|
|
faces32x32dir = new File(facesdir, "32x32");
|
|
faces32x32dir.mkdirs();
|
|
}
|
|
|
|
|
|
}
|