Fixed a lot of Vector3 clone issues
This commit is contained in:
parent
0231e7ab68
commit
c5bad9c491
19 changed files with 569 additions and 560 deletions
|
@ -1 +1 @@
|
|||
Subproject commit ca595286ebfe50a12300ba8490266aadce44c86d
|
||||
Subproject commit 688cfc13e8d045a25924c81c2e130dce1d3f842a
|
|
@ -29,6 +29,7 @@ package org.modstats;
|
|||
|
||||
public interface IModstatsReporter
|
||||
{
|
||||
public void registerMod(Object mod);
|
||||
public void doManualCheck();
|
||||
public void registerMod(Object mod);
|
||||
|
||||
public void doManualCheck();
|
||||
}
|
||||
|
|
|
@ -32,83 +32,86 @@ import java.util.Map;
|
|||
|
||||
public class ModVersionData
|
||||
{
|
||||
public String prefix;
|
||||
public String name;
|
||||
public String version;
|
||||
public String downloadUrl;
|
||||
public String changeLogUrl;
|
||||
|
||||
public Map<String, String> extraFields;
|
||||
|
||||
|
||||
public ModVersionData()
|
||||
{
|
||||
extraFields = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
public ModVersionData(String prefix, String name, String version)
|
||||
{
|
||||
this.prefix = prefix;
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
extraFields = new HashMap<String, String>();
|
||||
}
|
||||
public String prefix;
|
||||
public String name;
|
||||
public String version;
|
||||
public String downloadUrl;
|
||||
public String changeLogUrl;
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((changeLogUrl == null) ? 0 : changeLogUrl.hashCode());
|
||||
result = prime * result + ((downloadUrl == null) ? 0 : downloadUrl.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
|
||||
result = prime * result + ((version == null) ? 0 : version.hashCode());
|
||||
return result;
|
||||
}
|
||||
public Map<String, String> extraFields;
|
||||
|
||||
public ModVersionData()
|
||||
{
|
||||
extraFields = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
public ModVersionData(String prefix, String name, String version)
|
||||
{
|
||||
this.prefix = prefix;
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
extraFields = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((changeLogUrl == null) ? 0 : changeLogUrl.hashCode());
|
||||
result = prime * result + ((downloadUrl == null) ? 0 : downloadUrl.hashCode());
|
||||
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||
result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
|
||||
result = prime * result + ((version == null) ? 0 : version.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ModVersionData other = (ModVersionData) obj;
|
||||
if (changeLogUrl == null)
|
||||
{
|
||||
if (other.changeLogUrl != null)
|
||||
return false;
|
||||
}
|
||||
else if (!changeLogUrl.equals(other.changeLogUrl))
|
||||
return false;
|
||||
if (downloadUrl == null)
|
||||
{
|
||||
if (other.downloadUrl != null)
|
||||
return false;
|
||||
}
|
||||
else if (!downloadUrl.equals(other.downloadUrl))
|
||||
return false;
|
||||
if (name == null)
|
||||
{
|
||||
if (other.name != null)
|
||||
return false;
|
||||
}
|
||||
else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (prefix == null)
|
||||
{
|
||||
if (other.prefix != null)
|
||||
return false;
|
||||
}
|
||||
else if (!prefix.equals(other.prefix))
|
||||
return false;
|
||||
if (version == null)
|
||||
{
|
||||
if (other.version != null)
|
||||
return false;
|
||||
}
|
||||
else if (!version.equals(other.version))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
ModVersionData other = (ModVersionData) obj;
|
||||
if (changeLogUrl == null)
|
||||
{
|
||||
if (other.changeLogUrl != null)
|
||||
return false;
|
||||
} else if (!changeLogUrl.equals(other.changeLogUrl))
|
||||
return false;
|
||||
if (downloadUrl == null)
|
||||
{
|
||||
if (other.downloadUrl != null)
|
||||
return false;
|
||||
} else if (!downloadUrl.equals(other.downloadUrl))
|
||||
return false;
|
||||
if (name == null)
|
||||
{
|
||||
if (other.name != null)
|
||||
return false;
|
||||
} else if (!name.equals(other.name))
|
||||
return false;
|
||||
if (prefix == null)
|
||||
{
|
||||
if (other.prefix != null)
|
||||
return false;
|
||||
} else if (!prefix.equals(other.prefix))
|
||||
return false;
|
||||
if (version == null)
|
||||
{
|
||||
if (other.version != null)
|
||||
return false;
|
||||
} else if (!version.equals(other.version))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -37,28 +37,28 @@ import cpw.mods.fml.common.FMLLog;
|
|||
@Cancelable
|
||||
public class ModsUpdateEvent extends Event
|
||||
{
|
||||
private List<ModVersionData> updatedMods;
|
||||
|
||||
public ModsUpdateEvent()
|
||||
{
|
||||
updatedMods = new LinkedList<ModVersionData>();
|
||||
}
|
||||
|
||||
public void add(ModVersionData data)
|
||||
{
|
||||
if(!updatedMods.contains(data))
|
||||
{
|
||||
updatedMods.add(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.info("ModsUpdateEvent shouldn't have same mods data", data);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ModVersionData> getUpdatedMods()
|
||||
{
|
||||
return updatedMods;
|
||||
}
|
||||
|
||||
private List<ModVersionData> updatedMods;
|
||||
|
||||
public ModsUpdateEvent()
|
||||
{
|
||||
updatedMods = new LinkedList<ModVersionData>();
|
||||
}
|
||||
|
||||
public void add(ModVersionData data)
|
||||
{
|
||||
if (!updatedMods.contains(data))
|
||||
{
|
||||
updatedMods.add(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.info("ModsUpdateEvent shouldn't have same mods data", data);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ModVersionData> getUpdatedMods()
|
||||
{
|
||||
return updatedMods;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,23 +34,26 @@ import java.lang.annotation.Target;
|
|||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ModstatInfo
|
||||
public @interface ModstatInfo
|
||||
{
|
||||
/**
|
||||
* Modstats mod prefix.
|
||||
* @return
|
||||
*/
|
||||
public String prefix();
|
||||
|
||||
/**
|
||||
* Mod name. Use this if your mod doesn't have @Mod annotation
|
||||
* @return
|
||||
*/
|
||||
public String name() default "";
|
||||
/**
|
||||
* Modstats mod prefix.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String prefix();
|
||||
|
||||
/**
|
||||
* Mod version. Use this if your mod doesn't have @Mod annotation
|
||||
* @return
|
||||
*/
|
||||
public String version() default "";
|
||||
/**
|
||||
* Mod name. Use this if your mod doesn't have @Mod annotation
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String name() default "";
|
||||
|
||||
/**
|
||||
* Mod version. Use this if your mod doesn't have @Mod annotation
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String version() default "";
|
||||
}
|
||||
|
|
|
@ -31,59 +31,61 @@ import cpw.mods.fml.common.FMLLog;
|
|||
|
||||
public class Modstats
|
||||
{
|
||||
private static final Modstats INSTANCE = new Modstats();
|
||||
private static final String CLASS_TEMPLATE = "org.modstats.reporter.v%d.Reporter";
|
||||
private IModstatsReporter reporter;
|
||||
private static final Modstats INSTANCE = new Modstats();
|
||||
private static final String CLASS_TEMPLATE = "org.modstats.reporter.v%d.Reporter";
|
||||
private IModstatsReporter reporter;
|
||||
|
||||
private Modstats()
|
||||
{
|
||||
reporter = locateReporter();
|
||||
}
|
||||
|
||||
public IModstatsReporter getReporter()
|
||||
{
|
||||
return reporter;
|
||||
}
|
||||
|
||||
private IModstatsReporter locateReporter()
|
||||
{
|
||||
int i = 1;
|
||||
Class<?> latest = null;
|
||||
while (i < 100)
|
||||
{
|
||||
try
|
||||
{
|
||||
Class<?> candidate = Class.forName(String.format(CLASS_TEMPLATE, i));
|
||||
if (IModstatsReporter.class.isAssignableFrom(candidate))
|
||||
{
|
||||
latest = candidate;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (latest == null)
|
||||
{
|
||||
FMLLog.warning("Modstats reporter class not found.");
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
return (IModstatsReporter) latest.newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.warning("Modstats reporter class can't be instantiated.");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Modstats instance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private Modstats()
|
||||
{
|
||||
reporter = locateReporter();
|
||||
}
|
||||
|
||||
public IModstatsReporter getReporter()
|
||||
{
|
||||
return reporter;
|
||||
}
|
||||
|
||||
private IModstatsReporter locateReporter()
|
||||
{
|
||||
int i=1;
|
||||
Class<?> latest = null;
|
||||
while(i<100)
|
||||
{
|
||||
try
|
||||
{
|
||||
Class<?> candidate = Class.forName(String.format(CLASS_TEMPLATE, i));
|
||||
if(IModstatsReporter.class.isAssignableFrom(candidate))
|
||||
{
|
||||
latest = candidate;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(latest == null)
|
||||
{
|
||||
FMLLog.warning("Modstats reporter class not found.");
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
return (IModstatsReporter)latest.newInstance();
|
||||
} catch (Exception e)
|
||||
{
|
||||
FMLLog.warning("Modstats reporter class can't be instantiated.");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Modstats instance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,38 +36,38 @@ import cpw.mods.fml.common.Loader;
|
|||
|
||||
public class Config
|
||||
{
|
||||
private static final String CONFIG_NAME = "modstats.cfg";
|
||||
|
||||
public boolean allowUpdates;
|
||||
public boolean betaNotifications;
|
||||
public boolean forCurrentMinecraftVersion;
|
||||
public boolean logOnly;
|
||||
|
||||
public Config()
|
||||
{
|
||||
File configLocation = new File(Loader.instance().getConfigDir(), CONFIG_NAME);
|
||||
Configuration configuration = new Configuration(configLocation);
|
||||
configuration.load();
|
||||
|
||||
Property prop = configuration.get("updates", "AllowUpdates", true);
|
||||
prop.comment = "Allow to send current mod versions to the server and check for updates.\nIt allows to mod authors to see mod's popularity. Please don't disable it without necessity";
|
||||
allowUpdates = prop.getBoolean(true);
|
||||
|
||||
prop = configuration.get("updates", "LogOnly", false);
|
||||
prop.comment = "Don't display chat message, just add message to the log.";
|
||||
logOnly = prop.getBoolean(false);
|
||||
|
||||
prop = configuration.get("updates", "BetaNotifications", false);
|
||||
prop.comment = "Set true to receive notifications about beta versions. Otherwise you will only receive information about stable versions";
|
||||
betaNotifications = prop.getBoolean(false);
|
||||
|
||||
prop = configuration.get("updates", "ForCurrentMinecraftVersion", false);
|
||||
prop.comment = "Check for updates only for current MC version.\nEx:if you have MC 1.4.2 and ForCurrentMinecraftVersion is true, then you wouldn't receive notifications about versions for MC 1.4.5";
|
||||
forCurrentMinecraftVersion = prop.getBoolean(false);
|
||||
|
||||
configuration.save();
|
||||
|
||||
FMLLog.info("[Modstats] Config loaded. allowUpdates: %b, betaNotification: %b, strict: %b", allowUpdates, betaNotifications, forCurrentMinecraftVersion);
|
||||
}
|
||||
private static final String CONFIG_NAME = "modstats.cfg";
|
||||
|
||||
public boolean allowUpdates;
|
||||
public boolean betaNotifications;
|
||||
public boolean forCurrentMinecraftVersion;
|
||||
public boolean logOnly;
|
||||
|
||||
public Config()
|
||||
{
|
||||
File configLocation = new File(Loader.instance().getConfigDir(), CONFIG_NAME);
|
||||
Configuration configuration = new Configuration(configLocation);
|
||||
configuration.load();
|
||||
|
||||
Property prop = configuration.get("updates", "AllowUpdates", true);
|
||||
prop.comment = "Allow to send current mod versions to the server and check for updates.\nIt allows to mod authors to see mod's popularity. Please don't disable it without necessity";
|
||||
allowUpdates = prop.getBoolean(true);
|
||||
|
||||
prop = configuration.get("updates", "LogOnly", false);
|
||||
prop.comment = "Don't display chat message, just add message to the log.";
|
||||
logOnly = prop.getBoolean(false);
|
||||
|
||||
prop = configuration.get("updates", "BetaNotifications", false);
|
||||
prop.comment = "Set true to receive notifications about beta versions. Otherwise you will only receive information about stable versions";
|
||||
betaNotifications = prop.getBoolean(false);
|
||||
|
||||
prop = configuration.get("updates", "ForCurrentMinecraftVersion", false);
|
||||
prop.comment = "Check for updates only for current MC version.\nEx:if you have MC 1.4.2 and ForCurrentMinecraftVersion is true, then you wouldn't receive notifications about versions for MC 1.4.5";
|
||||
forCurrentMinecraftVersion = prop.getBoolean(false);
|
||||
|
||||
configuration.save();
|
||||
|
||||
FMLLog.info("[Modstats] Config loaded. allowUpdates: %b, betaNotification: %b, strict: %b", allowUpdates, betaNotifications, forCurrentMinecraftVersion);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,229 +66,231 @@ import cpw.mods.fml.common.versioning.ComparableVersion;
|
|||
|
||||
class DataSender extends Thread
|
||||
{
|
||||
private static final String urlAutoTemplate = "http://modstats.org/api/v1/report?mc=%s&user=%s&data=%s&sign=%s&beta=%b&strict=%b";
|
||||
private static final String urlManualTemplate = "http://modstats.org/api/v1/check?mc=%s&user=%s&data=%s&sign=%s&beta=%b&strict=%b";
|
||||
|
||||
private final Reporter reporter;
|
||||
public final boolean manual;
|
||||
|
||||
public DataSender(Reporter reporter, boolean manual)
|
||||
{
|
||||
this.reporter = reporter;
|
||||
this.manual = manual;
|
||||
}
|
||||
|
||||
private String toHexString(byte[] bytes) {
|
||||
char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
int v;
|
||||
for ( int j = 0; j < bytes.length; j++ ) {
|
||||
v = bytes[j] & 0xFF;
|
||||
hexChars[j*2] = hexArray[v/16];
|
||||
hexChars[j*2 + 1] = hexArray[v%16];
|
||||
}
|
||||
return new String(hexChars);
|
||||
}
|
||||
|
||||
private String getPlayerId() throws IOException
|
||||
{
|
||||
File statDir = new File(FMLClientHandler.instance().getClient().mcDataDir, "stats");
|
||||
if(!statDir.exists())
|
||||
{
|
||||
statDir.mkdirs();
|
||||
}
|
||||
String mac = "";
|
||||
try
|
||||
{
|
||||
InetAddress address = InetAddress.getLocalHost();
|
||||
NetworkInterface ni = NetworkInterface.getByInetAddress(address);
|
||||
byte[] macArray = ni.getHardwareAddress();
|
||||
if(macArray != null)
|
||||
{
|
||||
mac = toHexString(macArray);
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
}
|
||||
File uidFile = new File(statDir, "player.uid");
|
||||
if(uidFile.exists() && uidFile.canRead() && uidFile.length() == 32+mac.length())
|
||||
{
|
||||
String data = Files.toString(uidFile, Charsets.US_ASCII);
|
||||
String storedMac = data.substring(32);
|
||||
if(storedMac.equalsIgnoreCase(mac))
|
||||
return data.substring(0, 32);
|
||||
}
|
||||
uidFile.createNewFile();
|
||||
if(uidFile.canWrite())
|
||||
{
|
||||
String uid = UUID.randomUUID().toString().replace("-", "");
|
||||
FileOutputStream output = new FileOutputStream(uidFile);
|
||||
output.write((uid+mac).getBytes());
|
||||
output.close();
|
||||
return uid;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private String getSignature(String data)
|
||||
{
|
||||
return Hashing.md5().hashString(data).toString();
|
||||
}
|
||||
|
||||
private String getData()
|
||||
{
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (Map.Entry<String, ModVersionData> item : reporter.registeredMods.entrySet())
|
||||
{
|
||||
b.append(item.getKey()).append("+").append(item.getValue().version).append("$");
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private boolean checkIsNewer(String current, String received)
|
||||
{
|
||||
return new ComparableVersion(received).compareTo(new ComparableVersion(current)) > 0;
|
||||
}
|
||||
|
||||
|
||||
private void parseResponse(String response)
|
||||
{
|
||||
try
|
||||
{
|
||||
JsonRootNode json = (new JdomParser()).parse(response);
|
||||
//empty result
|
||||
if(!json.isNode("mods"))
|
||||
{
|
||||
FMLLog.info("[Modstats] Empty result");
|
||||
return;
|
||||
}
|
||||
List<JsonNode> modList = json.getArrayNode("mods");
|
||||
ModsUpdateEvent event = new ModsUpdateEvent();
|
||||
for (JsonNode modObject : modList)
|
||||
{
|
||||
String prefix = modObject.getStringValue("code");
|
||||
if(!reporter.registeredMods.containsKey(prefix))
|
||||
{
|
||||
FMLLog.warning("[Modstats] Extra mod '%s' in service response", prefix);
|
||||
continue;
|
||||
}
|
||||
String version = modObject.getStringValue("ver");
|
||||
if(version==null || version.equals(reporter.registeredMods.get(prefix).version))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(checkIsNewer(reporter.registeredMods.get(prefix).version, version))
|
||||
{
|
||||
ModVersionData data = new ModVersionData(prefix, reporter.registeredMods.get(prefix).name, version);
|
||||
Map<JsonStringNode, JsonNode> fields = modObject.getFields();
|
||||
for (Map.Entry<JsonStringNode, JsonNode> entry : fields.entrySet())
|
||||
{
|
||||
String fieldName = entry.getKey().getText();
|
||||
if(fieldName.equals("code") || fieldName.equals("ver"))
|
||||
continue;
|
||||
if(!(entry.getValue() instanceof JsonStringNode))
|
||||
{
|
||||
FMLLog.warning(String.format("[Modstats] Too complex data in response for field '%s'.", fieldName));
|
||||
continue;
|
||||
}
|
||||
String value = ((JsonStringNode)entry.getValue()).getText();
|
||||
if(fieldName.equals("chlog"))
|
||||
{
|
||||
data.changeLogUrl = value;
|
||||
}
|
||||
else if(fieldName.equals("link"))
|
||||
{
|
||||
data.downloadUrl = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.extraFields.put(fieldName, value);
|
||||
}
|
||||
}
|
||||
event.add(data);
|
||||
}
|
||||
|
||||
}
|
||||
if(event.getUpdatedMods().size() > 0)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
}
|
||||
if(!event.isCanceled() && event.getUpdatedMods().size() > 0)
|
||||
{
|
||||
List<ModVersionData> updatedModsToOutput = event.getUpdatedMods();
|
||||
StringBuilder builder = new StringBuilder("Updates found: ");
|
||||
Iterator<ModVersionData> iterator = updatedModsToOutput.iterator();
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
ModVersionData modVersionData = iterator.next();
|
||||
builder.append(modVersionData.name)
|
||||
.append(" (")
|
||||
.append(modVersionData.version)
|
||||
.append(")")
|
||||
.append(iterator.hasNext()?",":".");
|
||||
}
|
||||
FMLLog.info("[Modstats] %s", builder.toString());
|
||||
if(!reporter.config.logOnly && FMLCommonHandler.instance().getSide().isClient())
|
||||
{
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
int maxTries = 30;
|
||||
while(mc.thePlayer==null && maxTries>0)
|
||||
{
|
||||
try
|
||||
{
|
||||
sleep(1000);
|
||||
} catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
maxTries--;
|
||||
}
|
||||
if(mc.thePlayer != null)
|
||||
{
|
||||
mc.thePlayer.addChatMessage(builder.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (InvalidSyntaxException e)
|
||||
{
|
||||
FMLLog.warning("[Modstats] Can't parse response: '%s'.", e.getMessage());
|
||||
}
|
||||
}
|
||||
private static final String urlAutoTemplate = "http://modstats.org/api/v1/report?mc=%s&user=%s&data=%s&sign=%s&beta=%b&strict=%b";
|
||||
private static final String urlManualTemplate = "http://modstats.org/api/v1/check?mc=%s&user=%s&data=%s&sign=%s&beta=%b&strict=%b";
|
||||
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
String data = getData();
|
||||
String playerId = getPlayerId();
|
||||
String hash = getSignature(playerId+"!"+data);
|
||||
String template = manual?urlManualTemplate:urlAutoTemplate;
|
||||
String mcVersion = new CallableMinecraftVersion(null).minecraftVersion();
|
||||
URL url = new URL(String.format(template, mcVersion, playerId, data, hash, reporter.config.betaNotifications, reporter.config.forCurrentMinecraftVersion));
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setConnectTimeout(5000);
|
||||
connection.setReadTimeout(5000);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String line;
|
||||
String out = "";
|
||||
while ((line = reader.readLine()) != null) {
|
||||
//in most cases it will contain just one line
|
||||
out += line;
|
||||
}
|
||||
reader.close();
|
||||
parseResponse(out);
|
||||
} catch (MalformedURLException e)
|
||||
{
|
||||
FMLLog.warning("[Modstats] Invalid stat report url");
|
||||
} catch (IOException e)
|
||||
{
|
||||
FMLLog.info("[Modstats] Stat wasn't reported '"+e.getMessage()+"'");
|
||||
} catch(Exception e)
|
||||
{
|
||||
FMLLog.warning("[Modstats] Something wrong: "+e.toString());
|
||||
}
|
||||
}
|
||||
private final Reporter reporter;
|
||||
public final boolean manual;
|
||||
|
||||
public DataSender(Reporter reporter, boolean manual)
|
||||
{
|
||||
this.reporter = reporter;
|
||||
this.manual = manual;
|
||||
}
|
||||
|
||||
private String toHexString(byte[] bytes)
|
||||
{
|
||||
char[] hexArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
int v;
|
||||
for (int j = 0; j < bytes.length; j++)
|
||||
{
|
||||
v = bytes[j] & 0xFF;
|
||||
hexChars[j * 2] = hexArray[v / 16];
|
||||
hexChars[j * 2 + 1] = hexArray[v % 16];
|
||||
}
|
||||
return new String(hexChars);
|
||||
}
|
||||
|
||||
private String getPlayerId() throws IOException
|
||||
{
|
||||
File statDir = new File(FMLClientHandler.instance().getClient().mcDataDir, "stats");
|
||||
if (!statDir.exists())
|
||||
{
|
||||
statDir.mkdirs();
|
||||
}
|
||||
String mac = "";
|
||||
try
|
||||
{
|
||||
InetAddress address = InetAddress.getLocalHost();
|
||||
NetworkInterface ni = NetworkInterface.getByInetAddress(address);
|
||||
byte[] macArray = ni.getHardwareAddress();
|
||||
if (macArray != null)
|
||||
{
|
||||
mac = toHexString(macArray);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
File uidFile = new File(statDir, "player.uid");
|
||||
if (uidFile.exists() && uidFile.canRead() && uidFile.length() == 32 + mac.length())
|
||||
{
|
||||
String data = Files.toString(uidFile, Charsets.US_ASCII);
|
||||
String storedMac = data.substring(32);
|
||||
if (storedMac.equalsIgnoreCase(mac))
|
||||
return data.substring(0, 32);
|
||||
}
|
||||
uidFile.createNewFile();
|
||||
if (uidFile.canWrite())
|
||||
{
|
||||
String uid = UUID.randomUUID().toString().replace("-", "");
|
||||
FileOutputStream output = new FileOutputStream(uidFile);
|
||||
output.write((uid + mac).getBytes());
|
||||
output.close();
|
||||
return uid;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private String getSignature(String data)
|
||||
{
|
||||
return Hashing.md5().hashString(data).toString();
|
||||
}
|
||||
|
||||
private String getData()
|
||||
{
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (Map.Entry<String, ModVersionData> item : reporter.registeredMods.entrySet())
|
||||
{
|
||||
b.append(item.getKey()).append("+").append(item.getValue().version).append("$");
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private boolean checkIsNewer(String current, String received)
|
||||
{
|
||||
return new ComparableVersion(received).compareTo(new ComparableVersion(current)) > 0;
|
||||
}
|
||||
|
||||
private void parseResponse(String response)
|
||||
{
|
||||
try
|
||||
{
|
||||
JsonRootNode json = (new JdomParser()).parse(response);
|
||||
// empty result
|
||||
if (!json.isNode("mods"))
|
||||
{
|
||||
FMLLog.info("[Modstats] Empty result");
|
||||
return;
|
||||
}
|
||||
List<JsonNode> modList = json.getArrayNode("mods");
|
||||
ModsUpdateEvent event = new ModsUpdateEvent();
|
||||
for (JsonNode modObject : modList)
|
||||
{
|
||||
String prefix = modObject.getStringValue("code");
|
||||
if (!reporter.registeredMods.containsKey(prefix))
|
||||
{
|
||||
FMLLog.warning("[Modstats] Extra mod '%s' in service response", prefix);
|
||||
continue;
|
||||
}
|
||||
String version = modObject.getStringValue("ver");
|
||||
if (version == null || version.equals(reporter.registeredMods.get(prefix).version))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (checkIsNewer(reporter.registeredMods.get(prefix).version, version))
|
||||
{
|
||||
ModVersionData data = new ModVersionData(prefix, reporter.registeredMods.get(prefix).name, version);
|
||||
Map<JsonStringNode, JsonNode> fields = modObject.getFields();
|
||||
for (Map.Entry<JsonStringNode, JsonNode> entry : fields.entrySet())
|
||||
{
|
||||
String fieldName = entry.getKey().getText();
|
||||
if (fieldName.equals("code") || fieldName.equals("ver"))
|
||||
continue;
|
||||
if (!(entry.getValue() instanceof JsonStringNode))
|
||||
{
|
||||
FMLLog.warning(String.format("[Modstats] Too complex data in response for field '%s'.", fieldName));
|
||||
continue;
|
||||
}
|
||||
String value = ((JsonStringNode) entry.getValue()).getText();
|
||||
if (fieldName.equals("chlog"))
|
||||
{
|
||||
data.changeLogUrl = value;
|
||||
}
|
||||
else if (fieldName.equals("link"))
|
||||
{
|
||||
data.downloadUrl = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.extraFields.put(fieldName, value);
|
||||
}
|
||||
}
|
||||
event.add(data);
|
||||
}
|
||||
|
||||
}
|
||||
if (event.getUpdatedMods().size() > 0)
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
}
|
||||
if (!event.isCanceled() && event.getUpdatedMods().size() > 0)
|
||||
{
|
||||
List<ModVersionData> updatedModsToOutput = event.getUpdatedMods();
|
||||
StringBuilder builder = new StringBuilder("Updates found: ");
|
||||
Iterator<ModVersionData> iterator = updatedModsToOutput.iterator();
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
ModVersionData modVersionData = iterator.next();
|
||||
builder.append(modVersionData.name).append(" (").append(modVersionData.version).append(")").append(iterator.hasNext() ? "," : ".");
|
||||
}
|
||||
FMLLog.info("[Modstats] %s", builder.toString());
|
||||
if (!reporter.config.logOnly && FMLCommonHandler.instance().getSide().isClient())
|
||||
{
|
||||
Minecraft mc = FMLClientHandler.instance().getClient();
|
||||
int maxTries = 30;
|
||||
while (mc.thePlayer == null && maxTries > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
sleep(1000);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
maxTries--;
|
||||
}
|
||||
if (mc.thePlayer != null)
|
||||
{
|
||||
mc.thePlayer.addChatMessage(builder.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (InvalidSyntaxException e)
|
||||
{
|
||||
FMLLog.warning("[Modstats] Can't parse response: '%s'.", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
String data = getData();
|
||||
String playerId = getPlayerId();
|
||||
String hash = getSignature(playerId + "!" + data);
|
||||
String template = manual ? urlManualTemplate : urlAutoTemplate;
|
||||
String mcVersion = new CallableMinecraftVersion(null).minecraftVersion();
|
||||
URL url = new URL(String.format(template, mcVersion, playerId, data, hash, reporter.config.betaNotifications, reporter.config.forCurrentMinecraftVersion));
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setConnectTimeout(5000);
|
||||
connection.setReadTimeout(5000);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String line;
|
||||
String out = "";
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
// in most cases it will contain just one line
|
||||
out += line;
|
||||
}
|
||||
reader.close();
|
||||
parseResponse(out);
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
FMLLog.warning("[Modstats] Invalid stat report url");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
FMLLog.info("[Modstats] Stat wasn't reported '" + e.getMessage() + "'");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.warning("[Modstats] Something wrong: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,104 +42,101 @@ import cpw.mods.fml.common.FMLCommonHandler;
|
|||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Mod;
|
||||
|
||||
|
||||
public class Reporter implements IModstatsReporter
|
||||
{
|
||||
|
||||
public Map<String, ModVersionData> registeredMods;
|
||||
private DataSender sender;
|
||||
public Config config;
|
||||
|
||||
/**
|
||||
* At least one auto check was completed successfully
|
||||
*/
|
||||
private boolean checkedAuto;
|
||||
public Map<String, ModVersionData> registeredMods;
|
||||
private DataSender sender;
|
||||
public Config config;
|
||||
|
||||
public Reporter()
|
||||
{
|
||||
checkedAuto = false;
|
||||
registeredMods = new ConcurrentHashMap<String, ModVersionData>(2, 0.9f, 1);
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
config = new Config();
|
||||
}
|
||||
|
||||
|
||||
private void startCheck(boolean manual)
|
||||
{
|
||||
if(!config.allowUpdates)
|
||||
return;
|
||||
//only manual check is allowed on servers
|
||||
if(!FMLCommonHandler.instance().getSide().isClient() && !manual)
|
||||
return;
|
||||
if(registeredMods.isEmpty())
|
||||
return;
|
||||
DataSender currentSender = sender;
|
||||
if(!manual && checkedAuto)
|
||||
return;
|
||||
if(currentSender!=null && (currentSender.manual == false || manual))
|
||||
return;
|
||||
currentSender = new DataSender(this, manual);
|
||||
currentSender.start();
|
||||
sender = currentSender;
|
||||
|
||||
}
|
||||
|
||||
@ForgeSubscribe
|
||||
public void worldLoad(WorldEvent.Load event)
|
||||
{
|
||||
startCheck(false);
|
||||
}
|
||||
/**
|
||||
* At least one auto check was completed successfully
|
||||
*/
|
||||
private boolean checkedAuto;
|
||||
|
||||
|
||||
@Override
|
||||
public void registerMod(Object mod)
|
||||
{
|
||||
if(!config.allowUpdates)
|
||||
return;
|
||||
if(mod == null)
|
||||
{
|
||||
FMLLog.warning("[Modstats] Can't register null mod.");
|
||||
return;
|
||||
}
|
||||
ModstatInfo info = mod.getClass().getAnnotation(ModstatInfo.class);
|
||||
if(info == null)
|
||||
{
|
||||
FMLLog.warning("[Modstats] ModstatsInfo annotation not found for given mod.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(info.prefix() == null || info.prefix().equals(""))
|
||||
{
|
||||
FMLLog.warning("[Modstats] Mod prefix can't be empty.");
|
||||
return;
|
||||
}
|
||||
Mod modData = mod.getClass().getAnnotation(Mod.class);
|
||||
ModVersionData data;
|
||||
if(modData == null)
|
||||
{
|
||||
if(info.name() == null || info.name().equals(""))
|
||||
{
|
||||
FMLLog.warning("[Modstats] Mod name can't be empty.");
|
||||
return;
|
||||
}
|
||||
if(info.version() == null || info.version().equals(""))
|
||||
{
|
||||
FMLLog.warning("[Modstats] Mod version can't be empty.");
|
||||
return;
|
||||
}
|
||||
data = new ModVersionData(info.prefix(), info.name(), info.version());
|
||||
}
|
||||
else
|
||||
{
|
||||
data = new ModVersionData(info.prefix(), modData.name(), modData.version());
|
||||
}
|
||||
registeredMods.put(info.prefix(), data);
|
||||
}
|
||||
public Reporter()
|
||||
{
|
||||
checkedAuto = false;
|
||||
registeredMods = new ConcurrentHashMap<String, ModVersionData>(2, 0.9f, 1);
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
config = new Config();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doManualCheck()
|
||||
{
|
||||
startCheck(true);
|
||||
}
|
||||
private void startCheck(boolean manual)
|
||||
{
|
||||
if (!config.allowUpdates)
|
||||
return;
|
||||
// only manual check is allowed on servers
|
||||
if (!FMLCommonHandler.instance().getSide().isClient() && !manual)
|
||||
return;
|
||||
if (registeredMods.isEmpty())
|
||||
return;
|
||||
DataSender currentSender = sender;
|
||||
if (!manual && checkedAuto)
|
||||
return;
|
||||
if (currentSender != null && (currentSender.manual == false || manual))
|
||||
return;
|
||||
currentSender = new DataSender(this, manual);
|
||||
currentSender.start();
|
||||
sender = currentSender;
|
||||
|
||||
}
|
||||
|
||||
@ForgeSubscribe
|
||||
public void worldLoad(WorldEvent.Load event)
|
||||
{
|
||||
startCheck(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerMod(Object mod)
|
||||
{
|
||||
if (!config.allowUpdates)
|
||||
return;
|
||||
if (mod == null)
|
||||
{
|
||||
FMLLog.warning("[Modstats] Can't register null mod.");
|
||||
return;
|
||||
}
|
||||
ModstatInfo info = mod.getClass().getAnnotation(ModstatInfo.class);
|
||||
if (info == null)
|
||||
{
|
||||
FMLLog.warning("[Modstats] ModstatsInfo annotation not found for given mod.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.prefix() == null || info.prefix().equals(""))
|
||||
{
|
||||
FMLLog.warning("[Modstats] Mod prefix can't be empty.");
|
||||
return;
|
||||
}
|
||||
Mod modData = mod.getClass().getAnnotation(Mod.class);
|
||||
ModVersionData data;
|
||||
if (modData == null)
|
||||
{
|
||||
if (info.name() == null || info.name().equals(""))
|
||||
{
|
||||
FMLLog.warning("[Modstats] Mod name can't be empty.");
|
||||
return;
|
||||
}
|
||||
if (info.version() == null || info.version().equals(""))
|
||||
{
|
||||
FMLLog.warning("[Modstats] Mod version can't be empty.");
|
||||
return;
|
||||
}
|
||||
data = new ModVersionData(info.prefix(), info.name(), info.version());
|
||||
}
|
||||
else
|
||||
{
|
||||
data = new ModVersionData(info.prefix(), modData.name(), modData.version());
|
||||
}
|
||||
registeredMods.put(info.prefix(), data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doManualCheck()
|
||||
{
|
||||
startCheck(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public class ClientProxy extends CommonProxy
|
|||
MinecraftForge.EVENT_BUS.register(SoundHandler.INSTANCE);
|
||||
|
||||
RenderingRegistry.registerBlockHandler(BlockRenderingHandler.INSTANCE);
|
||||
|
||||
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityTesla.class, new RenderTesla());
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMultimeter.class, new RenderMultimeter());
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityEMContractor.class, new RenderEMContractor());
|
||||
|
|
|
@ -149,10 +149,10 @@ public class PacketHandler implements IPacketHandler
|
|||
{
|
||||
PacketDispatcher.sendPacketToAllPlayers(getTileEntityPacket(tileEntity, dataValues));
|
||||
}
|
||||
|
||||
|
||||
public static void sendTileEntityPacketToPlayer(TileEntity tileEntity, EntityPlayer player, Object... dataValues)
|
||||
{
|
||||
((EntityPlayerMP)player).playerNetServerHandler.sendPacketToPlayer(getTileEntityPacket(tileEntity, dataValues));
|
||||
((EntityPlayerMP) player).playerNetServerHandler.sendPacketToPlayer(getTileEntityPacket(tileEntity, dataValues));
|
||||
}
|
||||
|
||||
public static Packet250CustomPayload getTileEntityPacket(TileEntity tileEntity, Object... dataValues)
|
||||
|
|
|
@ -27,6 +27,7 @@ import resonantinduction.multimeter.TileEntityMultimeter;
|
|||
import resonantinduction.tesla.BlockTesla;
|
||||
import resonantinduction.tesla.TileEntityTesla;
|
||||
import resonantinduction.wire.BlockWire;
|
||||
import resonantinduction.wire.EnumWire;
|
||||
import resonantinduction.wire.ItemBlockWire;
|
||||
import resonantinduction.wire.TileEntityWire;
|
||||
import universalelectricity.core.item.IItemElectric;
|
||||
|
@ -231,6 +232,15 @@ public class ResonantInduction
|
|||
|
||||
/** EM Contractor */
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(blockEMContractor, " I ", "GCG", "WWW", 'W', Block.wood, 'C', emptyCapacitor, 'G', Item.ingotGold, 'I', Item.ingotIron));
|
||||
|
||||
/** Wires **/
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockWire, 1, EnumWire.COPPER.ordinal()), "MMM", 'M', "ingotCopper"));
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockWire, 1, EnumWire.TIN.ordinal()), "MMM", 'M', "ingotTin"));
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockWire, 1, EnumWire.IRON.ordinal()), "MMM", 'M', Item.ingotIron));
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockWire, 1, EnumWire.ALUMINUM.ordinal()), "MMM", 'M', "ingotAluminum"));
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockWire, 1, EnumWire.SILVER.ordinal()), "MMM", 'M', "ingotSilver"));
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockWire, 1, EnumWire.SUPERCONDUCTOR.ordinal()), "MMM", 'M', "ingotSuperconductor"));
|
||||
|
||||
}
|
||||
|
||||
public static int loadLanguages(String languagePath, String[] languageSupported)
|
||||
|
|
|
@ -329,6 +329,7 @@ public class TileEntityBattery extends TileEntityUniversalElectrical implements
|
|||
return removed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMaxEnergyStored()
|
||||
{
|
||||
if (!worldObj.isRemote)
|
||||
|
@ -354,6 +355,7 @@ public class TileEntityBattery extends TileEntityUniversalElectrical implements
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getEnergyStored()
|
||||
{
|
||||
if (!worldObj.isRemote)
|
||||
|
|
|
@ -49,7 +49,7 @@ public class PathfinderEMContractor
|
|||
this.results = new ArrayList<Vector3>();
|
||||
}
|
||||
|
||||
public boolean find(Vector3 start)
|
||||
public boolean find(final Vector3 start)
|
||||
{
|
||||
this.openSet.add(start);
|
||||
this.gScore.put(start, 0d);
|
||||
|
@ -62,7 +62,7 @@ public class PathfinderEMContractor
|
|||
ForgeDirection direction = ForgeDirection.getOrientation(i);
|
||||
Vector3 neighbor = this.target.clone().translate(new Vector3(direction.offsetX, direction.offsetY, direction.offsetZ));
|
||||
|
||||
if (!TileEntityEMContractor.canBePath(this.world, neighbor, this.target))
|
||||
if (!TileEntityEMContractor.canBePath(this.world, neighbor))
|
||||
{
|
||||
blockCount++;
|
||||
}
|
||||
|
@ -106,10 +106,9 @@ public class PathfinderEMContractor
|
|||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
ForgeDirection direction = ForgeDirection.getOrientation(i);
|
||||
Vector3 neighbor = currentNode.clone().modifyPositionFromSide(direction);
|
||||
|
||||
Vector3 neighbor = currentNode.clone().translate(new Vector3(direction.offsetX, direction.offsetY, direction.offsetZ));
|
||||
|
||||
if (TileEntityEMContractor.canBePath(this.world, neighbor, this.target))
|
||||
if (TileEntityEMContractor.canBePath(this.world, neighbor))
|
||||
{
|
||||
double tentativeG = this.gScore.get(currentNode) + currentNode.distance(neighbor);
|
||||
|
||||
|
|
|
@ -22,12 +22,6 @@ public class ThreadPathfinding extends Thread
|
|||
this.setPriority(Thread.MIN_PRIORITY);
|
||||
}
|
||||
|
||||
public ThreadPathfinding find()
|
||||
{
|
||||
this.run();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
|
|
|
@ -148,16 +148,16 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements IPacke
|
|||
{
|
||||
for (int i = 0; i < this.pathfinder.results.size(); i++)
|
||||
{
|
||||
Vector3 result = this.pathfinder.results.get(i);
|
||||
Vector3 result = this.pathfinder.results.get(i).clone();
|
||||
|
||||
if (TileEntityEMContractor.canBePath(this.worldObj, result, new Vector3(this.linked)))
|
||||
if (TileEntityEMContractor.canBePath(this.worldObj, result))
|
||||
{
|
||||
if (i - 1 >= 0)
|
||||
{
|
||||
Vector3 prevResult = this.pathfinder.results.get(i - 1);
|
||||
ResonantInduction.proxy.renderElectricShock(this.worldObj, prevResult.translate(0.5), result.translate(0.5), TileEntityTesla.dyeColors[dyeID]);
|
||||
Vector3 prevResult = this.pathfinder.results.get(i - 1).clone();
|
||||
ResonantInduction.proxy.renderElectricShock(this.worldObj, prevResult.clone().translate(0.5), result.clone().translate(0.5), TileEntityTesla.dyeColors[dyeID]);
|
||||
|
||||
Vector3 difference = prevResult.difference(result);
|
||||
Vector3 difference = prevResult.clone().difference(result);
|
||||
final ForgeDirection direction = difference.toForgeDirection();
|
||||
|
||||
AxisAlignedBB bounds = AxisAlignedBB.getAABBPool().getAABB(result.x, result.y, result.z, result.x + 1, result.y + 1, result.z + 1);
|
||||
|
@ -204,7 +204,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements IPacke
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean canBePath(World world, Vector3 position, Vector3 target)
|
||||
public static boolean canBePath(World world, Vector3 position)
|
||||
{
|
||||
Block block = Block.blocksList[position.getBlockID(world)];
|
||||
return block == null || (block instanceof BlockSnow || block instanceof BlockVine || block instanceof BlockLadder);
|
||||
|
@ -448,7 +448,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements IPacke
|
|||
super.readFromNBT(nbt);
|
||||
this.suck = nbt.getBoolean("suck");
|
||||
this.dyeID = nbt.getInteger("dyeID");
|
||||
this.tempLinkVector = new Vector3(nbt.getInteger("link_x"), nbt.getInteger("link_y"), nbt.getInteger("link_z"));
|
||||
this.tempLinkVector = new Vector3(nbt.getCompoundTag("link"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -460,9 +460,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements IPacke
|
|||
|
||||
if (this.linked != null)
|
||||
{
|
||||
nbt.setInteger("link_x", this.linked.xCoord);
|
||||
nbt.setInteger("link_y", this.linked.yCoord);
|
||||
nbt.setInteger("link_z", this.linked.zCoord);
|
||||
nbt.setCompoundTag("link", new Vector3(this.linked).writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -494,6 +492,7 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements IPacke
|
|||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet getDescriptionPacket()
|
||||
{
|
||||
if (this.linked != null)
|
||||
|
@ -532,12 +531,12 @@ public class TileEntityEMContractor extends TileEntityAdvanced implements IPacke
|
|||
{
|
||||
if (this.linked != null)
|
||||
{
|
||||
Vector3 start = new Vector3(this).translate(new Vector3(this.getDirection()));
|
||||
Vector3 target = new Vector3(this.linked).translate(new Vector3(this.linked.getDirection()));
|
||||
Vector3 start = new Vector3(this).modifyPositionFromSide(this.getDirection());
|
||||
Vector3 target = new Vector3(this.linked).modifyPositionFromSide(this.linked.getDirection());
|
||||
|
||||
if (start.distance(target) < ResonantInduction.MAX_CONTRACTOR_DISTANCE)
|
||||
{
|
||||
if (TileEntityEMContractor.canBePath(this.worldObj, start, new Vector3(this.linked)) && TileEntityEMContractor.canBePath(this.worldObj, target, new Vector3(this.linked)))
|
||||
if (TileEntityEMContractor.canBePath(this.worldObj, start) && TileEntityEMContractor.canBePath(this.worldObj, target))
|
||||
{
|
||||
this.thread = new ThreadPathfinding(new PathfinderEMContractor(this.worldObj, target), start);
|
||||
this.thread.start();
|
||||
|
|
|
@ -82,9 +82,7 @@ public abstract class ItemCoordLink extends ItemBase
|
|||
|
||||
public void clearLink(ItemStack itemStack)
|
||||
{
|
||||
itemStack.getTagCompound().removeTag("bindX");
|
||||
itemStack.getTagCompound().removeTag("bindY");
|
||||
itemStack.getTagCompound().removeTag("bindZ");
|
||||
itemStack.getTagCompound().removeTag("position");
|
||||
itemStack.getTagCompound().removeTag("dimID");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -373,7 +373,7 @@ public class FXElectricBolt extends EntityFX
|
|||
|
||||
public BoltPoint(Vector3 base, Vector3 offset)
|
||||
{
|
||||
super(base.translate(offset));
|
||||
super(base.clone().translate(offset));
|
||||
this.base = base;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
@ -415,7 +415,7 @@ public class FXElectricBolt extends EntityFX
|
|||
this.alpha = alpha;
|
||||
this.id = id;
|
||||
this.splitID = splitID;
|
||||
this.difference = this.end.difference(this.start);
|
||||
this.difference = this.end.clone().difference(this.start);
|
||||
}
|
||||
|
||||
public void recalculate()
|
||||
|
@ -424,7 +424,7 @@ public class FXElectricBolt extends EntityFX
|
|||
{
|
||||
Vector3 prevDiffNorm = this.prev.difference.clone().normalize();
|
||||
Vector3 diffNorm = this.difference.clone().normalize();
|
||||
this.prevDiff = diffNorm.translate(prevDiffNorm).normalize();
|
||||
this.prevDiff = diffNorm.clone().translate(prevDiffNorm).normalize();
|
||||
this.sinPrev = Math.sin(diffNorm.anglePreNorm(prevDiffNorm.scale(-1)) / 2);
|
||||
}
|
||||
else
|
||||
|
@ -437,7 +437,7 @@ public class FXElectricBolt extends EntityFX
|
|||
{
|
||||
Vector3 nextDiffNorm = this.next.difference.clone().normalize();
|
||||
Vector3 diffNorm = this.difference.clone().normalize();
|
||||
this.nextDiff = diffNorm.translate(nextDiffNorm).normalize();
|
||||
this.nextDiff = diffNorm.clone().translate(nextDiffNorm).normalize();
|
||||
this.sinNext = Math.sin(diffNorm.anglePreNorm(nextDiffNorm.scale(-1)) / 2);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -7,7 +7,6 @@ import net.minecraft.entity.player.EntityPlayer;
|
|||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Icon;
|
||||
import resonantinduction.ResonantInduction;
|
||||
import universalelectricity.core.electricity.ElectricityDisplay;
|
||||
import universalelectricity.core.electricity.ElectricityDisplay.ElectricUnit;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
|
|
Loading…
Reference in a new issue