Use reflection to improve Spout custom block support - fixes StainedGlass
This commit is contained in:
parent
417b8d6e31
commit
d85e810322
1 changed files with 124 additions and 54 deletions
|
|
@ -5,14 +5,20 @@ import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
import org.dynmap.Log;
|
import org.dynmap.Log;
|
||||||
import org.getspout.spoutapi.block.design.BlockDesign;
|
import org.getspout.spoutapi.block.design.BlockDesign;
|
||||||
|
import org.getspout.spoutapi.block.design.GenericBlockDesign;
|
||||||
|
import org.getspout.spoutapi.block.design.GenericCuboidBlockDesign;
|
||||||
|
import org.getspout.spoutapi.block.design.Texture;
|
||||||
import org.getspout.spoutapi.material.CustomBlock;
|
import org.getspout.spoutapi.material.CustomBlock;
|
||||||
import org.getspout.spoutapi.material.MaterialData;
|
import org.getspout.spoutapi.material.MaterialData;
|
||||||
|
|
||||||
|
|
@ -23,9 +29,38 @@ import org.getspout.spoutapi.material.MaterialData;
|
||||||
* directory of downloaded image files (texturepacks/standard/spout/plugin.blockid.png)
|
* directory of downloaded image files (texturepacks/standard/spout/plugin.blockid.png)
|
||||||
*/
|
*/
|
||||||
public class SpoutPluginBlocks {
|
public class SpoutPluginBlocks {
|
||||||
|
private Field textXPosField; /* float[][] textXPos */
|
||||||
|
private Field textYPosField; /* float[][] textYPos */
|
||||||
|
|
||||||
|
private boolean initSpoutAccess() {
|
||||||
|
boolean success = false;
|
||||||
|
try {
|
||||||
|
textXPosField = GenericBlockDesign.class.getDeclaredField("textXPos");
|
||||||
|
textXPosField.setAccessible(true);
|
||||||
|
textYPosField = GenericBlockDesign.class.getDeclaredField("textYPos");
|
||||||
|
textYPosField.setAccessible(true);
|
||||||
|
success = true;
|
||||||
|
} catch (NoSuchFieldException nsfx) {
|
||||||
|
Log.severe("Cannot access needed Spout custom block fields!");
|
||||||
|
Log.severe(nsfx);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
private void addDefaultBlock(StringBuilder sb, CustomBlock blk) {
|
||||||
|
if(blk.isOpaque())
|
||||||
|
sb.append("block:id=" + blk.getCustomId() + ",data=*,allfaces=1\n");
|
||||||
|
else
|
||||||
|
sb.append("block:id=" + blk.getCustomId() + ",allfaces=12049,transparency=TRANSPARENT\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Process spout blocks - return true if something changed */
|
/* Process spout blocks - return true if something changed */
|
||||||
public boolean processSpoutBlocks(File datadir) {
|
public boolean processSpoutBlocks(File datadir) {
|
||||||
|
if(textYPosField == null) {
|
||||||
|
if(initSpoutAccess() == false)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
HashMap<String, String> texturelist = new HashMap<String, String>();
|
||||||
|
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
File f = new File(datadir, "texturepacks/standard/spout");
|
File f = new File(datadir, "texturepacks/standard/spout");
|
||||||
if(f.exists() == false)
|
if(f.exists() == false)
|
||||||
|
|
@ -38,68 +73,103 @@ public class SpoutPluginBlocks {
|
||||||
for(CustomBlock b : cb) {
|
for(CustomBlock b : cb) {
|
||||||
BlockDesign bd = b.getBlockDesign();
|
BlockDesign bd = b.getBlockDesign();
|
||||||
String blkid = bd.getTexturePlugin() + "." + b.getName();
|
String blkid = bd.getTexturePlugin() + "." + b.getName();
|
||||||
File imgfile = new File(f, blkid + ".png");
|
/* If not GenericCubiodBlockDesign, we don't handle it */
|
||||||
BufferedImage img = null;
|
if((bd instanceof GenericCuboidBlockDesign) == false) {
|
||||||
boolean urlloaded = false;
|
Log.info("Block " + blkid + " not suppored - only cubiod blocks");
|
||||||
String txname = bd.getTexureURL();
|
addDefaultBlock(sb, b);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Get texture info */
|
||||||
|
Texture txt = bd.getTexture();
|
||||||
|
int w = txt.getWidth();
|
||||||
|
int h = txt.getHeight();
|
||||||
|
int sz = txt.getSpriteSize();
|
||||||
|
GenericCuboidBlockDesign gbd = (GenericCuboidBlockDesign)bd;
|
||||||
|
int[] txtidx = new int[6];
|
||||||
|
/* Fetch quad fields - figure out which texture for which side */
|
||||||
try {
|
try {
|
||||||
URL url = new URL(txname);
|
float[][] textXPos = (float[][])textXPosField.get(gbd);
|
||||||
img = ImageIO.read(url); /* Load skin for player */
|
float[][] textYPos = (float[][])textYPosField.get(gbd);
|
||||||
urlloaded = true;
|
/* Quads on cuboid are bottom, west, south, east, north, top */
|
||||||
} catch (IOException iox) {
|
for(int i = 0; i < 6; i++) {
|
||||||
if(txname.startsWith("http") == false) { /* Not URL - try file */
|
float minx = 1.0F;
|
||||||
File tf = new File(txname);
|
float miny = 1.0F;
|
||||||
if(tf.exists() == false) {
|
for(int j = 0; j < 4; j++) {
|
||||||
/* Horrible hack - try to find temp file (some SpoutMaterials versions) */
|
minx = Math.min(minx, textXPos[i][j]);
|
||||||
try {
|
miny = Math.min(miny, textYPos[i][j]);
|
||||||
File tmpf = File.createTempFile("dynmap", "test");
|
|
||||||
|
|
||||||
tf = new File(tmpf.getParent(), txname);
|
|
||||||
tmpf.delete();
|
|
||||||
} catch (IOException iox2) {}
|
|
||||||
}
|
}
|
||||||
if(tf.exists()) {
|
txtidx[i] = (int)((minx * w)/sz) + (w/sz)*(int)((miny * h)/sz);
|
||||||
try {
|
}
|
||||||
img = ImageIO.read(tf);
|
} catch (Exception iax) {
|
||||||
urlloaded = true;
|
addDefaultBlock(sb, b);
|
||||||
} catch (IOException iox3) {
|
continue;
|
||||||
|
}
|
||||||
|
String txname = bd.getTexureURL();
|
||||||
|
|
||||||
|
String txtid = texturelist.get(txname); /* Get texture */
|
||||||
|
if(txtid == null) { /* Not found yet */
|
||||||
|
File imgfile = new File(f, blkid + ".png");
|
||||||
|
BufferedImage img = null;
|
||||||
|
boolean urlloaded = false;
|
||||||
|
try {
|
||||||
|
URL url = new URL(txname);
|
||||||
|
img = ImageIO.read(url); /* Load skin for player */
|
||||||
|
urlloaded = true;
|
||||||
|
} catch (IOException iox) {
|
||||||
|
if(txname.startsWith("http") == false) { /* Not URL - try file */
|
||||||
|
File tf = new File(txname);
|
||||||
|
if(tf.exists() == false) {
|
||||||
|
/* Horrible hack - try to find temp file (some SpoutMaterials versions) */
|
||||||
|
try {
|
||||||
|
File tmpf = File.createTempFile("dynmap", "test");
|
||||||
|
|
||||||
|
tf = new File(tmpf.getParent(), txname);
|
||||||
|
tmpf.delete();
|
||||||
|
} catch (IOException iox2) {}
|
||||||
|
}
|
||||||
|
if(tf.exists()) {
|
||||||
|
try {
|
||||||
|
img = ImageIO.read(tf);
|
||||||
|
urlloaded = true;
|
||||||
|
} catch (IOException iox3) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(img == null) {
|
||||||
|
Log.severe("Error loading texture for custom block '" + blkid + "' (" + b.getCustomId() + ") from " + txname + "(" + iox.getMessage() + ")");
|
||||||
|
if(imgfile.exists()) {
|
||||||
|
try {
|
||||||
|
img = ImageIO.read(imgfile); /* Load existing */
|
||||||
|
Log.info("Loaded cached texture file for " + blkid);
|
||||||
|
} catch (IOException iox2) {
|
||||||
|
Log.severe("Error loading cached texture file for " + blkid + " - " + iox2.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(img == null) {
|
if(img != null) {
|
||||||
Log.severe("Error loading texture for custom block '" + blkid + "' (" + b.getCustomId() + ") from " + bd.getTexureURL() + "(" + iox.getMessage() + ")");
|
try {
|
||||||
if(imgfile.exists()) {
|
if(urlloaded)
|
||||||
try {
|
ImageIO.write(img, "png", imgfile);
|
||||||
img = ImageIO.read(imgfile); /* Load existing */
|
} catch (IOException iox) {
|
||||||
Log.info("Loaded cached texture file for " + blkid);
|
Log.severe("Error writing " + blkid + ".png");
|
||||||
} catch (IOException iox2) {
|
} finally {
|
||||||
Log.severe("Error loading cached texture file for " + blkid + " - " + iox2.getMessage());
|
img.flush();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
String tfid = "txtid" + texturelist.size();
|
||||||
|
sb.append("texturefile:id=" + tfid + ",filename=spout/" + blkid + ".png,xcount=" + w/h + ",ycount=1\n");
|
||||||
|
texturelist.put(txname, tfid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(img != null) {
|
String txfileid = texturelist.get(txname);
|
||||||
try {
|
if(txfileid != null) {
|
||||||
if(urlloaded)
|
blks.add(b);
|
||||||
ImageIO.write(img, "png", imgfile);
|
|
||||||
blks.add(b);
|
sb.append("block:id=" + b.getCustomId() + ",data=*,bottom=" + txtidx[0] + ",west=" +txtidx[1] + ",south=" + txtidx[2] + ",east=" + txtidx[3] + ",north="+txtidx[4]+",top="+txtidx[5]);
|
||||||
int w = img.getWidth();
|
if(b.isOpaque() == false)
|
||||||
int h = img.getHeight();
|
sb.append(",transparency=TRANSPARENT");
|
||||||
/* If width >= 6 times height, we're using custom for each side */
|
sb.append(",txtid=" + txfileid + "\n");
|
||||||
sb.append("texturefile:id=" + blkid + ",filename=spout/" + blkid + ".png,xcount=" + w/h + ",ycount=1\n");
|
cnt++;
|
||||||
if(w >= (6*h)) {
|
|
||||||
sb.append("block:id=" + b.getCustomId() + ",data=*,bottom=0,north=1,south=2,east=3,west=4,top=5,txtid=" + blkid + "\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sb.append("block:id=" + b.getCustomId() + ",data=*,allfaces=0,txtid=" + blkid + "\n");
|
|
||||||
}
|
|
||||||
cnt++;
|
|
||||||
} catch (IOException iox) {
|
|
||||||
Log.severe("Error writing " + blkid + ".png");
|
|
||||||
} finally {
|
|
||||||
img.flush();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String rslt = sb.toString();
|
String rslt = sb.toString();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue