Minecraft 1.7.2 setting textures efficiently - java

I set textures in each individual file, this is the non efficient way to set it
this.setUnlocalizedName("ItemName");
this.setTextureName("MyModName:ItemName");
This way made sense to me, but didn't work:
this.setUnlocalizedName("ItemName");
this.setTextureName(OtherClassName.MODID + ":" + this.getUnlocalizedName());
the 'OtherClassName.MODID' is referring to a variable in another class that contains 'MyModName'
The this.getUnlocalizedName() gets the UnlocalizedName that has been declared, 'ItemName'
Any help? I am not sure why it doesn't work.

getUnlocalizedName is slightly weird - it returns the string you passed into setUnlocalizedName, but with "item." at the start. The joys of working with deobfuscated code...
This would work:
String name = "ItemName";
this.setUnlocalizedName(name);
this.setTextureName(OtherClassName.MODID + ":" + name);
Note that it's not more efficient as in faster to run, but it might be faster to write if you change the item name a lot.

Related

how to join a string and variable to th:src

I want spring to search an image under path: /upload-dir/ID.jpg
ID is a variable that depends on the object's id.
Ive made something like this:
th:src="|#{/upload-dir/} ${dog.id} .jpg|"
but this is not working at all. I beg for any advice how to make it work :)
You can use the following structure to do so.
th:src="#{'/upload-dir/' + ${dog.id} + '.jpg'}"

Inserting a variable inside a String

This is probably a pretty simple issue but since I'm working with 1.3 IDE I can't use the most common method to do this.
String at_cmd_response = atc.send("AT+CMGS=\"+35111111111\"\r");
I need to introduce a string called number which holds a number like "35191xxxxxxx" in at_cmd_response. To do so, I've seen the String.format method but I can't use it due to my IDE.
Is there another way to do this?
Thanks
Simple String concatenation (+) will work:
String at_cmd_response = atc.send("AT+CMGS=\""+number+"\"\r");
Its looks like you have a modem and want to send some commands... like send a SMS or make a phonecall or similar :-) ...
now to the question:
you need to concatenate the modem command with the parameter
in java those are strings and can be concatenated using the unary operator +
like:
"AT+CMGS=\"+yourPhoneNumber+"\"\r"
example:
String yourPhoneNumber = "+35111111111";
and now call the method
atc.send("AT+CMGS=\" + yourPhoneNumber + \"\r");
I use below code snippets for web element locators in Selenium.
Here variable is quoted with '" + text + "
String text="666";
String subject="Knowledge base '" + text + "' Approval Request";
Also for rest assured,
If I want to parameterize 3f1dd0320a0a0b99000a53f7604a2ef9 value of below URL.
https://pineapples.com/api/sn_sc/v1/fruit/items/3f1dd0320a0a0b99000a53f7604a2ef9/submit_producer
So I declared it in to a variable and using “+sys_ID+” I pass it.
String sys_ID = "3f1dd0320a0a0b99000a53f7604a2ef9";
RestAssured.baseURI = "https://pineapples.com";
RestAssured.basePath = "api/sn_sc/v1/fruits/items/"+sys_ID+"/submit_producer";

Retrofit query params

I'm trying to configure a request to http: //where.yahooapis.com/v1/places.q(name_here);count=50?....
Not the best solution, I guess, but I tried
#GET("/v1/{location}")
Places getLocations(#Path("location") String locationName);
and pass there
getLocations("places.q(" + locationName + ");count=50");
But it still doesn't work as the string (); is translated into %28%29%3B.
Can you suggest any solutions? It would be better to dinamycally modify only the name_here part, something like
#GET("/v1/places.q({location});count=50)
If it is not possible how do I have to pass symbols (); so that they are converted correctly?
I just tried
#GET("/v1/places.q({location});count=50")
Places getLocations(#Path("location") String name)
a bit later and it works fine. I thought it will insert something like "/" or modify it, but it does exectly what I need.

How can I modify a java.lang class on the fly?

I'm looking for a way to add fields to an Thread on the fly by rewriting the byte code and reloading the class, not sure if it is at all possible. Any pointers welcome. I found some info on modifying and loading a class, and I know JRebel can seamlessly hot swap your code but not sure if the same approach/tools apply here.
The motivation here is exploring a theoretically better alternative to thread local objects. Should the method work I should be able to replace thread local with an annotation and the result should outperform current JDK implementation.
PS: Please save me the "root of all evil speech"
Clarifying use case:
Imagine I have a class with a ThreadLocal:
class A {
ThreadLocal&ltCounter&gt counter;
...
counter.get().inc()
}
I'd like to replace that with an annotation:
class A {
#ThreadLocal
Counter counter;
...
counter.inc()
}
But instead of the above code getting generated I'd like to mutate Thread such that Thread will now have an Acounter field and the actual code will be:
class A {
// Nothing here, field is now in Thread
...
Thread.currentThread().Acounter.inc()
}
At present it is impossible to redefine a class at runtime such that the redefinition will result in new methods or fields. This is due to the complexity involved in scanning the heap for all existing instances and transforming them + their references + potential Unsafe field offset base updaters (like AtomicFieldUpdater).
This limitation may be lifted as part of the JEP-159 but as discussed on the concurrency-interest mailing group this is a big impact change so may never happen at all.
Using Javaassist/similar will allow the transformation of a class to a new class with new methods/fields. This class can be loaded by a ClassLoader and used at runtime, but it's definition will not replace existing instances. So it will not be possible to use this method combined with an agent to redefine the class as an instrumentation redefinition is limited such that: "The redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields ..." see here.
So for now, NO.
If you would like to change the behaviour of "class" at runtime, you could try javassist. API is here
I have seen custom class loading solution that dynamically reloaded JARs - you define one ClassLoader per JAR file and use it to load the classes from that JAR; to reload entire JAR you just "kill" its ClassLoader instance and create another one (after you replace the JAR file).
I don't think it's possible to tweak Java's internal Thread class this way because you don't have control over System ClassLoader. A possible solution is to have a CustomThreadWeaver class that would generate a new class extending Thread with the variables you need and use a custom DynamicWeavedThreadClassLoader to load them.
Good luck and show us your monster when you succeed ;-)
Possible
using instrumentation, and possibly libraries like javassist to modify code on fly. (however, adding and removing fields, methods or constructors are currently not possible)
//Modify code using javassist and call CtClass#toBytecode() or load bytecode from file
byte[] nevcode;
Class<?> clz = Class.forName("any.class.Example");
instrumentationInstace.redefineClasses(new ClassDefinition(clz, nevcode));
Do not forget to add Can-Redefine-Classes: true to your java agent's manifest.
Real example - optimizing java < 9 string.replace(CharSequence, CharSequence) using javassist:
String replace_src =
"{String str_obj = this;\n"
+ "char[] str = this.value;\n"
+ "String find_obj = $1.toString();\n"
+ "char[] find = find_obj.value;\n"
+ "String repl_obj = $2.toString();\n"
+ "char[] repl = repl_obj.value;\n"
+ "\n"
+ "if(str.length == 0 || find.length == 0 || find.length > str.length) {\n"
+ " return str_obj;\n"
+ "}\n"
+ "int start = 0;\n"
+ "int end = str_obj.indexOf(find_obj, start);\n"
+ "if(end == -1) {\n"
+ " return str_obj;\n"
+ "}\n"
+ "int inc = repl.length - find.length;\n"
+ "int inc2 = str.length / find.length / 512;\ninc2 = ((inc2 < 16) ? 16 : inc);\n"
+ "int sb_len = str.length + ((inc < 0) ? 0 : (inc * inc2));\n"
+ "StringBuilder sb = (sb_len < 0) ? new StringBuilder(str.length) : new StringBuilder(sb_len);\n"
+ "while(end != -1) {\n"
+ " sb.append(str, start, end - start);\n"
+ " sb.append(repl);\n"
+ " start = end + find.length;\n"
+ " end = str_obj.indexOf(find_obj, start);\n"
+ "}\n"
+ "if(start != str.length) {\n"
+ " sb.append(str, start, str.length - start);\n"
+ "}\n"
+ "return sb.toString();\n"
+"}";
ClassPool cp = new ClassPool(true);
CtClass clz = cp.get("java.lang.String");
CtClass charseq = cp.get("java.lang.CharSequence");
clz.getDeclaredMethod("replace", new CtClass[] {
charseq, charseq
}).setBody(replace_src);
instrumentationInstance.redefineClasses(new ClassDefinition(Class.forName(clz.getName(), false, null), clz.toBytecode()));
This seems to be a question of using the right tool for the job. A similar question has been asked here: Another Stack Overflow Question and the Javaassist byte code manipulation library was a possible solution.
But without further detail into the reasons why this is being attempted, it seems like the real answer is to use the right tool for the job. For example, with Groovy the ability to dynamically add methods to the language.
You could try creating a JVM Agent that makes use of the java.lang.instrument API and more specifically make use of the retransform method that " facilitates the instrumentation of already loaded classes" and then make use of Javassist (or ASM) as mentioned to deal with the bytecode.
More info on the java.lang.instrument API
To do what you want, the simpler alternative would be to use a subclass of Thread, run it, and then inside that thread execute the code from your example (together with a cast of currentThread() to your subclass).
What you are attempting to do is not possible.
Since you already know about ThreadLocal, you already know what the suggested solution is.
Alternatively, you can sub-class Thread and add your own fields; however, only those threads that you explicitly create of that class will have those fields, so you will still have to be able to "fall back" to using a thread local.
The real question is "why?", as in "why is a thread local insufficient for your requirements?"

Mysql session variable in JDBC string

am using this connection string to connect to mysql from java:
jdbc:mysql://localhost:3306/db?noDatetimeStringSync=true&useUnicode=yes&characterEncoding=UTF-8
is it possible to set the session variable in the string so that SET UNIQUE_CHECKS=0; would be executed upon connecting to server? the obvious
jdbc:mysql://localhost:3306/db?noDatetimeStringSync=true&useUnicode=yes&characterEncoding=UTF-8&unique_checks=0
doesn't seem to work, based on the fact that
'jdbc:mysql://localhost:3306/db?noDatetimeStringSync=true&useUnicode=yes&characterEncoding=UTF-8&unique_checks=blahblah`
doesn't generate any error.
Cheers!
How about using sessionVariables:
jdbc:mysql://localhost:3306/db?noDatetimeStringSync=true&useUnicode=yes&characterEncoding=UTF-8&sessionVariables=unique_checks=0
Your question is thus more "How do I concat Strings in Java?" ?
If so, then just use the + operator:
int uniqueChecks = 0; // Assign session variable here.
String url = "jdbc:mysql://localhost:3306/db?unique_checks=" + uniqueChecks;
Alternatively you can also use String#format() wherein you can use the %d pattern to represent a decimal:
int uniqueChecks = 0; // Assign session variable here.
String url = String.format("jdbc:mysql://localhost:3306/db?unique_checks=%d", uniqueChecks);
You can use Statement.execute() to run pretty much every statement the DB understands, including such a SET-statement.
The advantage of using an URL parameter or a dedicated method is that the JDBC-driver is actually aware that the option was set and can react accordingly. This may or may not be useful or necessary for this particular option, but it's vital for other options (for example toggling autocommit with such a statement is a very bad idea).
BalusC, thanks for a reply! actually I need to do that in Talend etl tool(which itself is a java code generator) and the only line i can edit is the "jdbc:mysql://localhost:3306/db?noDatetimeStringSync=true&useUnicode=yes&characterEncoding=UTF-8" string, which gets translated to this java code:
String url_tMysqlBulkExec_1 = "jdbc:mysql://"
+ "localhost" +
":"
+ "3306"
+ "/"
+ "db"
+ "?"
+ "noDatetimeStringSync=true&useUnicode=yes&characterEncoding=UTF-8&unique_checks=0";
that's the limitation, sorry for not pointing that out earlier.
According to mysql docs, there is no possibility to set the unique_checks setting, i guess i need to look for other solution than URL parameters (Joachim, thanks for reminding me that these things are called "URL parameters" - help a lot while googling :)

Categories