#Timestamps and durations issue
1 messages · Page 1 of 1 (latest)
Makes sense 👍
So its better to save the date when he left last time and then compare with current date?
Or is something better?
Yeah you dont need to save this data.
Just save the time when he joins and check again when he leaves
Sure you can use Instant for that.
right
Let me read about instant
So i would basically save the Instant#toEpochMillis() of when he joins?
Well for this case a raw long is maybe better
Just an example
private final Map<UUID, Long> joinTimes = new HashMap<>();
@EventHandler
public void onJoin(PlayerJoinEvent event) {
joinTimes.put(event.getPlayer().getUniqueId(), System.currentTimeMillis());
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
long joinTime = joinTimes.remove(event.getPlayer().getUniqueId());
long leaveTime = System.currentTimeMillis();
long millisPlayed = leaveTime - joinTime;
// Save diff
}
But i would not use a hmap raw like that
Nah all good. Instant is just not the right tool here.
Wait im doing that tho
Wait i will look the paste and sent it here
Isnt more or less the same?
I checked and the logic is the same haha
So must be an issue in spigot side, not bungee
Nope this is not the same logic. Look at the thought experiment on top again.
You would have to do this:
// on Join
user.setPlayed(user.getPlayed() - System.currentTimeMillis());
// on Quit
user.setPlayed(user.getPlayed() + System.currentTimeMillis());
But using only one timestamp is super fking hacky
right, so whats better?
Im really confused because there many ways, instant, date, etc
You need to remember the join time
oh right, so my code is written backwards 🤦♂️
Instant DateTime Long.
They do pretty much the same here.
I just realzed
But if you use this approach then when a player joins he will have a very negative number (several years minus)
and if the server crashes then his timestamp is broken
so?
It is just important to remember when a player joined
A long, a data, an Instant. All the same
Every one of those is just a point in time.
The important part is: You need more than just one timestamp. You need at least two.
oh right, that will fix the issue, okay
Now i understand
So one would be when he joins, and the other the time played?
Yes. But time played is not a timestamp. Its a duration. Thats important to understand.
okay my head is getting out of memory
let me look for the diff, so i can understand
A timestamp is this:
in 01.01.1970 the unix time started. This means every timestamp
(like System.currentTimeMillis()) is the milliseconds since 1970.
Those are millions of seconds.
A timeframe is only a duration of time. So it could be as small as 500s
okay i udnerstand the dfierences
But how i do apply them
I think my fault is there
Im not wana lied but im looking like an idiot which cant code such a simple logic
But i wont give up, i will put my effot to understand it
@dapper harbor So what fields would i have to save in the database to fix my issue?
Just the time played. You need temporary data while a player is joined.
Im using redis cache system for doing that, where i keep globally his data
Sure you can do that if you want. But the joined timestamp does not need to be in there
// Needs only to be on the current server. No Redis. No MongoDB.
private final Map<UUID, Long> joinTimes = new HashMap<>();
@EventHandler
public void onJoin(PlayerJoinEvent event) {
// Save the timestamp when a player joins
joinTimes.put(event.getPlayer().getUniqueId(), System.currentTimeMillis());
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
// Get the timestamp when a player joined and remove it
long joinTime = joinTimes.remove(event.getPlayer().getUniqueId());
// Get the current time
long leaveTime = System.currentTimeMillis();
// Calculate the diff
long millisPlayed = leaveTime - joinTime;
// Save diff
userData.setPlayed(userData.getPlayed() + millisPlayed);
}
No
okay, im confused sorry man
Im just losting ur time
I thinking you are taking this as im trolling haha
But really im not trolling. im seeing that the example is the same as my code
Its all good. Time is a pretty complicated concept inprogramming
You are throwing everything into one timestamp. Im using 1 timestamp and 1 duration
The problem is that i need to expose the time played to redis, if not i will have issues in other servers
You only need the total time played on redis.
You dont need the point in time when the player joined this current session in redis.
Ok one moment i will vis this
Im redis im just saving the total time played as a long value
If you are back just tag me
Right
Get some water first ^^
right better idea
i will chill up and read calm
So then i dont stress you and make you mad, and i dont to bed with this annoying issue
really thanks for your pacient tho
right im back
Can i u explain me now, that im calm
You only need the time diffs in redis, right? (so 200s played + 900s played + 20s played etc)
End every time a player leaves, you need to calculate a new diff and add it to the old diff.
When a player joins you dont have anything. So you dont have to touch the diff on redis.
When a player joins you only need to save the current timestamp (eg 1000_000s or whatever System.currentTime returns)
And you dont need to save that in Redis. Only on the server where the player is playing on.
Then later when the player quits, you look at when he joined on this server (Still no Redis).
Then you calculate a diff between now (eg 1001_200s) and when he joined (1000_000s).
This is then 1200s played. This is your diff. Now you can use redis and add this diff to the other diffs in redis.
okay
That is my fault i just realized
I must use the time cache which you sent before
Okay
I wil ltry to apply that to Bungeecord
Because i will count the time played inside the proxy itself
I think this should work
Yeah makes sense
okay i will change my code and send finaly code
Thanks smile, thanks for your pacient tho
Times and durations issue
I updated the thread name
Timestamps and durations issue
this is my final code, im compiling for testing t
Looks good