#Ways to store data for players

1 messages · Page 1 of 1 (latest)

thorn swallow
#

I can use PersistentDataContainers but I also want to have that data available in a DB /yaml file after server is offline, and be able to fetch data from offline players

trail yacht
#

use a db then

thorn swallow
#

but

trail yacht
#

dont use yaml for large datasets

thorn swallow
#

how should i store the data

dusky wharf
#

Create an abstract layer of an interface

thorn swallow
#

do i use PersistentDataContainers?

dusky wharf
#

then have different implementations?

#

in that case you can easily try an implementation of PDC as well as flat files or databases

trail yacht
#

Well

#

you said you want data when the server is offline

#

so no

thorn swallow
#

yes

trail yacht
#

pdc

thorn swallow
#

ok

dusky wharf
#

but the rest of your code would simply rely on your interface

thorn swallow
#

but

trail yacht
#

^^

thorn swallow
#

when the player logs in

#

should i retrieve data from files EVERY time i need it?

clear holly
#

no

thorn swallow
#

or store it on a map

clear holly
#

cache it

trail yacht
#

^^

thorn swallow
#

like Map<Player, Data>

dusky wharf
#

I believe pdc is cached?

thorn swallow
#

yes

#

thats what im asking

dusky wharf
#

you can use an IdentityHashMap there

thorn swallow
dusky wharf
#

its a special hash map

clear holly
#

personally i use this

@Getter
    private static transient ExpiringMap<String, IslandCache> cacheMap = ExpiringMap.builder()
            .expiration(10, TimeUnit.MINUTES)
            .expirationPolicy(ExpirationPolicy.ACCESSED)
            .asyncExpirationListener((k, v) ->
            {
                try {
                    ((IslandCache) v).save();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).build();

this is from a library of mine. but you can maybe find similar options

dusky wharf
#

every instance is resolved as its own key

#

why transient?

clear holly
#

so its not Serialized with json

dusky wharf
#

ah fair

thorn swallow
dusky wharf
#

its in the jdk

thorn swallow
#

kk

#

ty

dusky wharf
#

if and only if instance a is instance b then a == b

#

thats how the identity hash map identifies its keys

#

(well not really) but in theory

#

and you'd use it because it doesnt have to go through any hashing computations

thorn swallow
#

so 2 identic maps (in content) are not equal?

dusky wharf
#

like a normal hash map would have to do

#

no

#

thing is a regular HashMap uses the implemented hashCode()

#

to determine if two keys are the same or not

thorn swallow
#

but why isnt that a good implementation

dusky wharf
#

its not bad

#

just that an IdentityHashMap here is more performant

thorn swallow
#

so why shouldnt i just use HashMap

thorn swallow
dusky wharf
#

no because it uses the memory address of objects as its keys

#

which requires literal to no computation

thorn swallow
#

and can i use IdentityHashMaps the same way as a regular HashMap?

dusky wharf
#

nope

#

its not that you cant go with a regular HashMap

#

its just that an IdentityHashMap is more suitable for storing Player as key given that you remove the entry on disconnect

#

but you would have to do that with a normal HashMap also

thorn swallow
#

but i can store the player's UUID/Username

#

as the key

clear holly
#

defo shoulnt store username

dusky wharf
#

which is less performant

#

yeah usernames are changeable

#

UUIDs require proper hash computation

thorn swallow
#

arent uuid's Strings

dusky wharf
#

no

#

well

#

you can turn one into a string

thorn swallow
#

well that

dusky wharf
#

but in Java they're objects

thorn swallow
#

i can store the string version

#

of uuid

dusky wharf
#

dont

hard oyster
#

what are you using for keys on your identityhashmap suggestion conclure

thorn swallow
#

why?

hard oyster
#

the player object?

dusky wharf
#

Yes

#

the Player instance can serve as an identity holder

hard oyster
#

for the express purpose of having one player be able to have multiple instances of itself?

dusky wharf
#

given that he only needs the key during the session

thorn swallow
#

in my map player keys are unique, a player can only appear once

dusky wharf
#

there will only be one valid player instance valid during that players time online on the server instance

thorn swallow
#

but i can store it while the server is online

dusky wharf
#

unless you'd for some bizarre reason run a weird fork of spigot which changes that

thorn swallow
#

i run paper

dusky wharf
#

then it should be fine

hard oyster
#

yeah this sounds like you're just trying to implement possible mem leaks in really fun and interesting ways by mistake

thorn swallow
#

;-;

hard oyster
#

I wouldn't rely on identity specifically because one player could accidentally create a never ending amounts of itself on the server if one thing violates your assumptions of how the player sessions will run

#

fake players for one have caused me lots of fun issues in the past

thorn swallow
#

then why shouldnt i just store uuids on a regular hashmap

hard oyster
#

it's marginally less performant so maybe you'll see a tps drop at 10,000 logins per tick instead of 100,000 logins per tick directly due to this code

thorn swallow
#

player logins?

hard oyster
#

is this not for caching on login?

dusky wharf
#

but that's definitely not the case

thorn swallow
hard oyster
#

well yeah

thorn swallow
#

my implementation idea would be

#

have data stored on DB

#

then when players login

hard oyster
#

lucky

thorn swallow
#

data is retrieved from DB to map

dusky wharf
#

no

thorn swallow
#

and on disable or when data needs to be written i write to DB

dusky wharf
#

that the player reproduces a lot of instances from them mere selves

hard oyster
#

if the fake players come with a fake login they might never log out, at which point you'd never have a reason to remove them from your map

#

and they might log in as many times as someone decided they'd be doing that for

thorn swallow
#

the server has to restart

#

so they disappear from map on restart

thorn swallow
#

or it checking for an instance of the player in the map before adding it

thorn swallow
dusky wharf
hard oyster
#

you misunderstand me, this is not an attack vector, this is a feature of some software out there

dusky wharf
#

I have never seen it happen when working with newer versions so Idk but if what you assert is true then Ig it would be bad

hard oyster
#

last russian report of such issues I had was in... I want to say 2019

#

but I patched the issue so it could still be going on right now, it's just not visible to me anymore

dusky wharf
#

fair then

hard oyster
#

I will say these issues tend to only pop up in russian and east asian servers for whatever reason, they have some trippy plugins and forks

#

if this is for a more personal use then don't worry too much about it

thorn swallow
#

its for a private server with no russian players and less than 20 players in total

hard oyster
#

yeah you're fine

thorn swallow
#

so what should i use then

hard oyster
#

either will work, conclure's version is slightly more performant and a regular hashmap is slightly safer

thorn swallow
#

but i shoudnt really worry abt performance if it has less than 20 players right?

dusky wharf
#

you could just use pdc for this

#

¯_(ツ)_/¯

thorn swallow
#

but what about the DB

#

and fetching data from offline players

hard oyster
#

by the time you realize you have to start worrying about performance you've already monumentally fucked up in a way that might be near impossible to fix

thorn swallow
#

i want to make an api that fetches data from any player that has entered the server

dusky wharf
#

Believe that's fully possible with pdc?

thorn swallow
dusky wharf
#

or nvm

thorn swallow
#

oh

dusky wharf
#

OfflinePlayer doesnt extend PersistentDataHolder

hard oyster
#

would offlineplayer have the pdc

#

right

#

was going to say

thorn swallow
#

and what about if server is offline

#

is there any way to retrieve pdc from server files?

hard oyster
#

just use a database at that point

thorn swallow
#

probs too complex

#

thats why i want to use a db

#

but i dont want to use the DB EVERY time i need to access data from players

#

thats too expensive

hard oyster
#

on player login, cache the data

#

on player logout, make sure the data is synced and clear it out

thorn swallow
#

yes

#

but where do i cache

#

pdc

#

or map

hard oyster
#

if you need to query the db for offline players during runtime you will need to query the db

#

doesn't matter, I prefer maps

thorn swallow
#

what i want to do

#

is run an external server as an api

hard oyster
#

specifically I prefer keeping objects for my players with data relevant for that player for the plugin I'm working on

thorn swallow
#

that fetches data from the DB

#

for offline players, even when the main server is offline

#

kk ill use maps

hard oyster
#

be careful about concurrent modifications of your db

hard oyster
#

if you are not just reading but modifying data externally

thorn swallow
#

nono

#

just reading

#

to display the custom data of players

#

i may make like a discord bot where you can see a player's custom data

hard oyster
#

you'll probably want to make sure that you are keeping some degree of parity between your server and your db

thorn swallow
#

yes thats the thing

#

i might check whether the player is online

#

then if he is retrieve data from map

#

if not from db?

hard oyster
#

yes

thorn swallow
#

ok now time to learn how to use a DB yay

hard oyster
#

personally I have a class that queries player data

#

it internally checks if the player has cached data and if not it can (but doesn't have to) query the database