Liam
7a1ffc0538
All checks were successful
Deploy to Dokku / docker (ubuntu-latest) (push) Successful in 1m17s
118 lines
3.9 KiB
Java
118 lines
3.9 KiB
Java
package cc.fascinated.bat.service;
|
|
|
|
import cc.fascinated.bat.common.TimerUtils;
|
|
import cc.fascinated.bat.event.EventListener;
|
|
import cc.fascinated.bat.model.BatGuild;
|
|
import cc.fascinated.bat.model.BatUser;
|
|
import com.mongodb.client.model.Filters;
|
|
import lombok.Getter;
|
|
import lombok.NonNull;
|
|
import lombok.extern.log4j.Log4j2;
|
|
import net.dv8tion.jda.api.entities.User;
|
|
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
|
import net.dv8tion.jda.api.events.user.update.UserUpdateGlobalNameEvent;
|
|
import net.jodah.expiringmap.ExpirationPolicy;
|
|
import net.jodah.expiringmap.ExpiringMap;
|
|
import org.bson.Document;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.context.annotation.DependsOn;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
/**
|
|
* @author Fascinated (fascinated7)
|
|
*/
|
|
@Service
|
|
@Log4j2(topic = "User Service")
|
|
@Getter
|
|
@DependsOn({"discordService", "mongoService"})
|
|
public class UserService implements EventListener {
|
|
private static final long SAVE_INTERVAL = TimeUnit.MINUTES.toMillis(5);
|
|
|
|
/**
|
|
* The cached users
|
|
*/
|
|
private final Map<String, BatUser> users = ExpiringMap.builder()
|
|
.expiration(1, TimeUnit.HOURS)
|
|
.expirationPolicy(ExpirationPolicy.ACCESSED) // Expire after not being accessed for 1 hour
|
|
.expirationListener((key, cachedUser) -> {
|
|
BatUser user = (BatUser) cachedUser;
|
|
log.info("Removed user \"{}\" - \"{}\" from cache", user.getName(), user.getId());
|
|
user.save();
|
|
})
|
|
.build();
|
|
|
|
@Autowired
|
|
public UserService() {
|
|
TimerUtils.scheduleRepeating(() -> {
|
|
long before = System.currentTimeMillis();
|
|
for (BatUser user : users.values()) {
|
|
user.save();
|
|
}
|
|
log.info("Saved {} users in {}ms", users.size(), System.currentTimeMillis() - before);
|
|
}, SAVE_INTERVAL, SAVE_INTERVAL);
|
|
}
|
|
|
|
/**
|
|
* Gets a user by its ID
|
|
*
|
|
* @param id The ID of the user
|
|
* @return The user
|
|
*/
|
|
public BatUser getUser(@NonNull String id, User user) {
|
|
long before = System.currentTimeMillis();
|
|
// User is cached
|
|
if (users.containsKey(id)) {
|
|
return users.get(id);
|
|
}
|
|
// User is not cached
|
|
Document document = MongoService.INSTANCE.getUsersCollection().find(Filters.eq("_id", id)).first();
|
|
if (document != null) {
|
|
BatUser batUser = new BatUser(id, user, document);
|
|
users.put(id, batUser);
|
|
return batUser;
|
|
}
|
|
// New user
|
|
BatUser batUser = new BatUser(id, user, new Document());
|
|
users.put(id, batUser);
|
|
log.info("Created user \"{}\" - \"{}\" in {}ms", batUser.getName(), batUser.getId(), System.currentTimeMillis() - before);
|
|
return batUser;
|
|
}
|
|
|
|
/**
|
|
* Gets a user by its ID
|
|
*
|
|
* @param id The ID of the user
|
|
* @return The user
|
|
*/
|
|
public BatUser getUser(@NonNull String id) {
|
|
User user = DiscordService.JDA.retrieveUserById(id).complete();
|
|
if (user == null || user.isBot()) {
|
|
return null;
|
|
}
|
|
return getUser(id, null);
|
|
}
|
|
|
|
@Override
|
|
public void onShutdown() {
|
|
log.info("Saving all users before shutdown...");
|
|
for (BatUser user : users.values()) {
|
|
user.save();
|
|
}
|
|
log.info("Saved all users.");
|
|
}
|
|
|
|
@Override
|
|
public void onGuildMemberJoin(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildMemberJoinEvent event) {
|
|
user.setGlobalName(event.getUser().getGlobalName()); // Ensure the user's name is up-to-date
|
|
}
|
|
|
|
@Override
|
|
public void onUserUpdateGlobalName(@NonNull BatUser user, String oldName, String newName, @NonNull UserUpdateGlobalNameEvent event) {
|
|
user.setGlobalName(newName);
|
|
}
|
|
}
|