ValioBungee
ValioBungee copied to clipboard
Transfer - UUID
What is your question?
Good evening, I am interested in Redis and in particular its way of assigning uuids and storing them. How can I retrieve this data and modify the uuids assigned to the players or better, how can I transfer the uuids of the players from one bungee to another?
Last question, does redis-bungee sync player uuids across proxies?
If you have a discord, I would be happy to discuss it with you in a simpler way than by issues !
discord: Ham1255#4547
Redis is just the database standalone software
which RedisBungee uses to store data since Redis is really fast for such things, you can read the readme of the project to know what redis Lib RedisBungee uses.
RedisBungee does automatically add the uuid of player and remove them when they quit the network
and you can access these data on all proxies about a player:
- joined proxy like
proxy-1
- joined server like
survival-1
etc - Last online
when == 0 means online
- Ip address of the player
- UUID cache for
username -> UUID or uuid -> username
conversion
also other data not related about players:
- current online proxies
- dead proxies
unless the code removes them
Excuse my mistake, I wanted to write Bungeecord and not Redis, I should have read it again... Because I searched a bit but I can't find the place where the uuids generated for players by bungeecord are stored by default.
This most likely already exists but I was wondering what was the data transferred by jedis! I looked a bit in your wiki but I only saw a few examples!
sorry about the wiki its just really old from original redisbunge repository, so everything clear now?
Not really, my question was rather, how do you synchronize the UUIDs and how bungeecord generates them, if you have the time to explain it to me, that's great, otherwise you won't take the lead.
Because looking at the dependencies used, you only use the API which is really surprising! I was expecting Bungee Native or other style dependencies to do this kind of sync!
i am not very good at explaining but if i get your question correctly, there is no need for using internal bungee stuff, basically uuid stuff is handled during login redis bungee does not change anything related to uuids, also when we sync the uuid which seen in https://github.com/ProxioDev/RedisBungee/blob/develop/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeBungeeListener.java see on join
note: i didn't create whole thing, i just made it modular in-case other proxy appears which in this case velocity
proxy init
proxy startup it starts 2 repeating tasks, heartbeat and integrity check
https://github.com/ProxioDev/RedisBungee/blob/develop/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/tasks/HeartbeatTask.java
heart beat keep adding/updating itself with timestamp in unix using redis server time stamps
since you cannot trust that proxy is running with correct time settings, inside hashset
long redisTime = plugin.getRedisTime(unifiedJedis);
unifiedJedis.hset("heartbeats", plugin.getConfiguration().getProxyId(), String.valueOf(redisTime));
on join
when everything in the login event is passed like bans getting checked on login event
then post login event get called and we call BungeePlayerUtils.createBungeePlayer(event.getPlayer(), unifiedJedis, true);
and handle platform stuff like getting servername, which then method it self calls
PlayerUtils.createPlayer(player.getUniqueId(), unifiedJedis, serverName, pendingConnection.getAddress().getAddress(), fireEvent);
here is code for that:
public static void createPlayer(UUID uuid, UnifiedJedis unifiedJedis, String currentServer, InetAddress hostname, boolean fireEvent) {
final boolean isKickedFromOtherLocation = isKickedOtherLocation(uuid.toString(), unifiedJedis);
Map<String, String> playerData = new HashMap<>(4);
playerData.put("online", "0");
playerData.put("ip", hostname.getHostName());
playerData.put("proxy", AbstractRedisBungeeAPI.getAbstractRedisBungeeAPI().getProxyId());
if (currentServer != null) {
playerData.put("server", currentServer);
}
unifiedJedis.sadd("proxy:" + AbstractRedisBungeeAPI.getAbstractRedisBungeeAPI().getProxyId() + ":usersOnline", uuid.toString());
unifiedJedis.hset("player:" + uuid, playerData);
if (fireEvent && !isKickedFromOtherLocation) {
playerJoinPayload(uuid, unifiedJedis, hostname);
}
}
you can see we are using redis hashsets to store stuff like hostnameip of the player
etc.
but you can also see sadd which basically adds the player uuid into the set of online players, since each proxy got it own ID.
getting synced uuids
so to get the players uuids we need to get current heart beating proxies which can be seen below
here is the method of getting all players uuids from data is stored in redis
default Set<UUID> getPlayers() {
return new RedisTask<Set<UUID>>(this) {
@Override
public Set<UUID> unifiedJedisTask(UnifiedJedis unifiedJedis) {
ImmutableSet.Builder<UUID> setBuilder = ImmutableSet.builder();
try {
List<String> keys = new ArrayList<>();
for (String i : getProxiesIds()) {
keys.add("proxy:" + i + ":usersOnline");
}
if (!keys.isEmpty()) {
Set<String> users = unifiedJedis.sunion(keys.toArray(new String[0]));
if (users != null && !users.isEmpty()) {
for (String user : users) {
try {
setBuilder = setBuilder.add(UUID.fromString(user));
} catch (IllegalArgumentException ignored) {
}
}
}
}
} catch (JedisConnectionException e) {
// Redis server has disappeared!
logFatal("Unable to get connection from pool - did your Redis server go away?");
throw new RuntimeException("Unable to get all players online", e);
}
return setBuilder.build();
}
}.execute();
}
i am not very good at explaining but if i get your question correctly, there is no need for using internal bungee stuff, basically uuid stuff is handled during login redis bungee does not change anything related to uuids, also when we sync the uuid which seen in https://github.com/ProxioDev/RedisBungee/blob/develop/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeBungeeListener.java see
on join
note: i didn't create whole thing, i just made it modular in-case other proxy appears which in this case
velocity
proxy init
proxy startup it starts 2 repeating tasks, heartbeat and integrity check
https://github.com/ProxioDev/RedisBungee/blob/develop/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/tasks/HeartbeatTask.java
heart beat keep adding/updating itself with timestamp in unix using
redis server time stamps
since you cannot trust that proxy is running with correct time settings, inside hashsetlong redisTime = plugin.getRedisTime(unifiedJedis); unifiedJedis.hset("heartbeats", plugin.getConfiguration().getProxyId(), String.valueOf(redisTime));
on join
when everything in the login event is passed
like bans getting checked on login event
then post login event get called and we callBungeePlayerUtils.createBungeePlayer(event.getPlayer(), unifiedJedis, true);
and handle platform stuff like getting servername, which then method it self callsPlayerUtils.createPlayer(player.getUniqueId(), unifiedJedis, serverName, pendingConnection.getAddress().getAddress(), fireEvent);
here is code for that:public static void createPlayer(UUID uuid, UnifiedJedis unifiedJedis, String currentServer, InetAddress hostname, boolean fireEvent) { final boolean isKickedFromOtherLocation = isKickedOtherLocation(uuid.toString(), unifiedJedis); Map<String, String> playerData = new HashMap<>(4); playerData.put("online", "0"); playerData.put("ip", hostname.getHostName()); playerData.put("proxy", AbstractRedisBungeeAPI.getAbstractRedisBungeeAPI().getProxyId()); if (currentServer != null) { playerData.put("server", currentServer); } unifiedJedis.sadd("proxy:" + AbstractRedisBungeeAPI.getAbstractRedisBungeeAPI().getProxyId() + ":usersOnline", uuid.toString()); unifiedJedis.hset("player:" + uuid, playerData); if (fireEvent && !isKickedFromOtherLocation) { playerJoinPayload(uuid, unifiedJedis, hostname); } }
you can see we are using redis hashsets to store stuff like hostname
ip of the player
etc.but you can also see sadd which basically adds the player uuid into the set of online players, since each proxy got it own ID.
getting synced uuids
so to get the players uuids we need to get current heart beating proxies which can be seen below
here is the method of getting all players uuids from data is stored in redis
default Set<UUID> getPlayers() { return new RedisTask<Set<UUID>>(this) { @Override public Set<UUID> unifiedJedisTask(UnifiedJedis unifiedJedis) { ImmutableSet.Builder<UUID> setBuilder = ImmutableSet.builder(); try { List<String> keys = new ArrayList<>(); for (String i : getProxiesIds()) { keys.add("proxy:" + i + ":usersOnline"); } if (!keys.isEmpty()) { Set<String> users = unifiedJedis.sunion(keys.toArray(new String[0])); if (users != null && !users.isEmpty()) { for (String user : users) { try { setBuilder = setBuilder.add(UUID.fromString(user)); } catch (IllegalArgumentException ignored) { } } } } } catch (JedisConnectionException e) { // Redis server has disappeared! logFatal("Unable to get connection from pool - did your Redis server go away?"); throw new RuntimeException("Unable to get all players online", e); } return setBuilder.build(); } }.execute(); }
You explained it to me very well, thank you!