Variable not resetting when command is ran again - java

I have a piece of code that outputs the player's total experience.
The issue is that the XP value it outputs doesn't change if the actual XP does.
For example, at level 50,000 the XP was 2,147,483,647. When level dropped to 4, the XP value stayed the same.
if (cmd.getName().equalsIgnoreCase("checkxp")) {
// If person is null, it's not a player!
if (person == null) {
sender.sendMessage("This command can only be used by a player, sorry!");
return false;
} else {
int curxp;
Player player = (Player) sender;
curxp = player.getTotalExperience();
sender.sendMessage("You currently have: " + curxp + " XP!");
return true;
}
}
How do I get this value to reset after it was ran so it re-checks the XP and updates the variable with the new amount?

If you don't update your Player object which looks like it's coming from sender it will hold the old values, so I check that sender is coming in with new data.

Looking at ExpSkills, it seems that playing with experience instead of levels is the way to go.
So use setTotalExperience() and getTotalExperience() for now.
Once you get everything working, then try and add support for levels.
Maybe there's a converter somewhere to convert levels to experience and experience to levels?
If not, here are the conversion charts.

Related

Minestom (Minecraft) water bucket placing

I am creating a Minecraft server using minestom which is a server building library, it had so no code and you have to make everything yourself. So im trying to make it so players can place water but it doesnt work sometimes. If im falling and place it then it gets placed client side but not server side sometimes, when its placed server side it says "placed block" in the chat.
globalEventHandler.addListener(PlayerUseItemOnBlockEvent.class, event -> {
final Player player = event.getPlayer();
if (event.getItemStack().getMaterial() != Material.WATER_BUCKET) {
return;
}
if (player.getInstance().getBlock(new Vec(event.getPosition().x(),
event.getPosition().y(),
event.getPosition().z())) == Block.IRON_BLOCK
&& event.getBlockFace().normalY() == 1) {
Point placedPos = event.getPosition();
placedPos.withX(placedPos.x() + event.getBlockFace().normalX());
placedPos.withY(placedPos.y() + event.getBlockFace().normalY());
placedPos.withZ(placedPos.z() + event.getBlockFace().normalZ());
player.getInstance().setBlock(placedPos, Block.WATER);
player.sendMessage("placed water");
}
player.getInventory().update();
});
Video - Ignore the platform disappearing, bug that I know how to fix but havent just yet but that also only happens when the water is placed server side too
https://youtu.be/njH58gbXPlE
I believe on the look vector is the next tick’s look vector for placing water, but the server hasn’t gotten this new look vector so it uses the old one

Android sampling rates variation of hardware Sensors on Nexus 6P

I'm developing an Android app, for a research, and im reading several Sensor data like accelerometer, gyroscope, barometer etc.
So I have 4 Nexus 6P devices all with the newest Factory Image and freshly set up with no other app installed than the standard once which are pre-installed.
So the Problem that occurs now is that one of the phones is constantly lagging behind, so for example i record for half an hour the accelerometer at 105 Hz (so the max possible rate for the accelerometer is 400Hz), just to make sure i get at least about the amount of samples i would expect for 100Hz and the results are the following:
Smapling for Half an hour at 100Hz -> 180000 Samples
Smapling for Half an hour at 105Hz -> 189000 Samples
(This is now just an example for the accelerometer but is the same for every other sensor on each device. So device 1,3,4 get about the same good results for other senors while device 2 gets the same bad results on all other sensors).
Device 1: 180000 Samples
Device 2: 177273 Samples <- the phone that is lagging behind
Device 3: 181800 Samples
Device 4: 179412 Samples
So the problem is at device number 2 where I'm missing almost 3000 Samples (I know this is crying at a high level) and my guess for this problem is that it is probably Hardware related. That it might be a performance issue i can probably rule out since it does not matter how many Sensors im reading and also reading them at 400Hz works as expected (if wanted i can also offer the Samples for this too). I also tried to set the sampling rate to 400Hz so to the fastest and then take recordings according to the timestamp which led to the same result.
So just in case I'll provide how I register the Sensor Listener:
protected void onCreate(Bundle savedInstanceState){
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
unaccDataSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED);
}
....
private void Start(){
sensorManager.registerListener(unaccDataListener, unaccDataSensor, 10000);
}
So what i want is to get at least about the amount of samples that i should expect so above is no problem and just a bit below is also acceptable.
So if anyone has an idea about what else I can try or what can cause the problem i would be really thankful.
This is my first Post so if anything is missing or if i explained something in a bad way im sorry and i try my best to fix it.
I work with Android sensors a lot, and i can tell you the hardware is of variable quality. I usually use a filter if I need the results to be consistent across phones:
// Filter to remove readings that come too often
if (TS < LAST_TS_ACC + 100) {
//Log.d(TAG, "onSensorChanged: skipping");
return;
}
however this means you can only set the phones to match the lowest common denominator. If it helps I find that getting any more than 25hz is overkill for most applications, even medical ones.
It can also help to make sure any file writes you are doing are done off thread, and in batches, as writing to file is an expensive operation.
accelBuffer = new StringBuilder();
accelBuffer.append(LAST_TS_ACC + "," + event.values[0] + "," + event.values[1] + "," + event.values[2] + "\n");
if((accelBuffer.length() > 500000) && (writingAccelToFile == false) ){
writingAccelToFile = true;
AccelFile = new File(path2 +"/Acc/" + LAST_TS_ACC +"_Service.txt");
Log.d(TAG, "onSensorChanged: accelfile created at : " + AccelFile.getPath());
File parent = AccelFile.getParentFile();
if(!parent.exists() && !parent.mkdirs()){
throw new IllegalStateException("Couldn't create directory: " + parent);
}
//Try threading to take of UI thread
new Thread(new Runnable() {
#Override
public void run() {
//Log.d(TAG, "onSensorChanged: in accelbuffer");
// Log.d(TAG, "run: in runnable");
//writeToStream(accelBuffer);
writeStringBuilderToFile(AccelFile, accelBuffer);
accelBuffer.setLength(0);
writingAccelToFile = false;
}
}).start();
}
Doing all of the above has got me reasonably good results, but it will never be perfect due to differences in the hardware.
Good luck!

Raspberry PI, Java and Pi4J Controlling GPIO cant get current PinState

Iám ciurrently Working on a Little Programm wich should check the current state of an explizit GPIO Pin and than toggle ist. For this iám using java and PI4J. When my Programm starts, the LED is turned of. But as soon as i get it as a variable it automaticly sets the state to HIGH. Dos anyone have an idea how to avoid this ? my code so far:
final GpioController gpio = GpioFactory.getInstance();
GpioPinDigitalOutput led =gpio.provisionDigitalMultipurposePin(RaspiPin.GPIO_07,PinMode.DIGITAL_OUTPUT);
PinState ledStatus = led.getState();
if (ledStatus.isHigh())
{
led.setShutdownOptions(true, PinState.LOW);
System.out.println("Set shutdownOption LOW");
}
else
{
led.setShutdownOptions(true, PinState.HIGH);
System.out.println("Set shutdownOption HIGH");
}
if(ledStatus.isHigh())
{
System.out.println("LEDS aus...");
}
else
{
System.out.println("LEDS an...");
}
led.toggle();
This Works quite fine. But as i said, before i start the programm... the LED is off! as soon as i get to this line :
GpioPinDigitalOutput led =gpio.provisionDigitalMultipurposePin(RaspiPin.GPIO_07,PinMode.DIGITAL_OUTPUT);
The LED is ON! i need to figure out a way to get the state before the app is running , change it and then exit my programm with the LED toggled.
Thanks for your Help :)
try using the provisionDigitalMultipurposePin method to set first mode INPUT in order to read the state, and then switch to OUTPUT mode to change the pin state.
GpioController gpio = GpioFactory.getInstance();
GpioPinDigitalMultipurpose led = gpio.provisionDigitalMultipurposePin(RaspiPin.GPIO_07, PinMode.DIGITAL_INPUT);
// read state
led.setMode(PinMode.DIGITAL_OUTPUT);
// write state

define a Custom Property as a Data Object

Found the issue on my payment Input control. There was a small computed Text field that was failing but not throwing an error. Just stopped the whole process. In any case removed the computedText and it now works. The compositeData formula that returns pItem to the custom control still fires way to often but I can't figure out how to stop that. It is all memory resident so it is probably not a major performance hit, but still.....
This question is a follow up to my previous question and I will try to refine the issue
defining an object property in a compositeData on a custom control
Here is a picture of what I am trying to do:
The repeat control is bound to an arrayList generated by the Java method Payments.getAllItems(LinkKey) and that works correctly. The button in the repeat is fairly simple it just setts the viewScope.vsShowPayment = true and vsRIndex to the repeat Index value so I know which element in the ArrayList we are working with. It then does a refresh of the panelPaymentContainer which hides the repeat and renders the custom control ccTestPayment.
ccTestPayment has a custom property called pItem of the type java.lang.Object with this code:
<xc:ccTestPaymentInput rendered="#{javascript:(viewScope.vsShowPayment)}">
<xc:this.pItem><![CDATA[#{javascript:try{
var debug:Boolean = true;
if (debug) print("Open existing row = " + viewScope.vsRIndex)
rIndex = parseInt(viewScope.vsRIndex.toString());
if (debug) print("rIndex = " + rIndex);
pItem = Payments.getItem(rIndex);
return pItem;
}catch(e){
print("Failure in Custom Prop of add item " + e.toString());
return null;
}}]]></xc:this.pItem>
</xc:ccTestPaymentInput>
the method in the class Payments Payments.getItem(rIndex) then returns the PaymentItem Object from the ArrayList of PaymentItems and displays them in custom control. the fields in the custom control are bound to compositeData.pItem.getPaymentDate etc and to this point everything is cool.
I can edit any of the fields on the custom control and that all works fine. However, when I press the "Save" button none of the code in it gets executed.
try{
print("Start Payment save");
var debug:Boolean = true;
var pos:Integer = parseInt(viewScope.vsRIndex.toString());
if (debug) print("Working with pos = " + pos + " Call saveThisItem");
if (Payments.saveThisItem(compositeData.pItem , pos)){
if (debug) print("save Payments Worked ");
}else{
if (debug) print("save Payments FAILED ");
}
}catch(e){
print("payment save Error " + e.tostring);
}finally{
viewScope.vsExpPayDate = null;
viewScope.vsShowPayment = false;
viewScope.remove("vsRIndex");
viewScope.remove("vsGotItem")
}
None of the print statements get fired. I suspect it has something to do how pItem gets defined. the code behind the custom property gets fired over and over again and I'm wondering if that is getting in the way.
The reason that the save was not working was that there was a computed Text field on the control that generated an error. The problem was that there was no error message reported on the client nor the console. After a lot of head scratching I noticed the text filed was no longer displaying the value it was supposed to. Deleted the field and the save and everything else started to work.
On the issue of the number of times the processes are called I think I have resolved many of them. I'm moving the control ccTestPaymentInput.xsp inside the repeat. It will now have direct access to the 'current' PaymentItem Object so I can access teh repeat var=pItem which is teh PaymentItem object I want to work with. Clean and far simpler than what I was doing. The only refreshes necessary are the ones related to the rpeat control and there is not much that I can do about that.

J2me application out of memory exception on multiple time file play

In my j2me application i have to play a small sound file each times user click on an item. But the issues is when i play sound file multiple times like after 10-14 times it gives me
out of memory exception. Although i release the player each time i play the file but still it
gives out of memory exception : Here is the code snippet,
public void playSound(String soundFile) {
try{
if (player!=null) {
try {
player.deallocate(); //deallocate the unnecessary memory.
} catch (Exception ex) {
player=null;
System.gc();
}
}
player = Manager.createPlayer(getClass().getResourceAsStream(musicFolder + soundFile), "audio/mpeg");
// player = Manager.createPlayer(is, "audio/mpeg");
player.realize();
// get volume control for player and set volume to max
VolumeControl vc = (VolumeControl) player.getControl("VolumeControl");
if (vc != null) {
vc.setLevel(100);
}
player.prefetch();
player.start();
isException=false;
} catch (Exception e) {
isException=true;
}
}
Can someone tell me what is going wrong?
3 things to keep in mind
If you are going to play the same sound several times, you might want to keep one Player prefetched and simply start it multiple times.
When you want to properly cleanup a player, you should call Player.close()
You may want to use a media event listener to close and/or restart a player independently of user input.
I think you should also call
player.close()
right after after
player.deallocate();
According to documentation "When deallocate returns, the Player is in the UNREALIZED or REALIZED state." but close goes further... "When the method returns, the Player is in the CLOSED state and can no longer be used."
I'm not sure why the de-allocation isn't working. I guess it either takes longer to de-allocated than to create a new one, or the de-allocation fails for some reason. Is there a player.stop() to match the player.start()?
Another thing to try (if nothing else, for good form :) is not to create new player unless you need to/should. I.e. move the
if(player!=null){
So it also covers
player = Manager.createPlayer(getClass().getResourceAsStream(musicFolder + soundFile), "audio/mpeg");
HTH!

Categories