@@ -0,0 +1,122 @@
|
||||
package com.disklexar.mmorpg.player;
|
||||
|
||||
import com.disklexar.mmorpg.MmorpgPlugin;
|
||||
import com.disklexar.mmorpg.core.config.MmorpgConfig;
|
||||
import com.disklexar.mmorpg.core.service.Service;
|
||||
import com.disklexar.mmorpg.persistence.repository.PlayerProfileRepository;
|
||||
import com.disklexar.mmorpg.player.model.PlayerProfile;
|
||||
import com.disklexar.mmorpg.rpg.race.RaceCatalog;
|
||||
import com.hypixel.hytale.logger.HytaleLogger;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Tracks online player sessions and synchronizes profiles with SQLite.
|
||||
*/
|
||||
public final class PlayerSessionService implements Service {
|
||||
|
||||
private final MmorpgPlugin plugin;
|
||||
private final MmorpgConfig config;
|
||||
private final PlayerProfileRepository repository;
|
||||
private final HytaleLogger logger;
|
||||
private final Map<UUID, PlayerProfile> sessions = new ConcurrentHashMap<>();
|
||||
private final Map<UUID, Long> connectedAt = new ConcurrentHashMap<>();
|
||||
|
||||
public PlayerSessionService(
|
||||
@Nonnull MmorpgPlugin plugin,
|
||||
@Nonnull MmorpgConfig config,
|
||||
@Nonnull PlayerProfileRepository repository) {
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.repository = repository;
|
||||
this.logger = plugin.getLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
try {
|
||||
repository.clearConnectedFlags();
|
||||
} catch (SQLException e) {
|
||||
logger.at(Level.WARNING).log("Failed to reset connection flags: %s", e.getMessage());
|
||||
}
|
||||
logger.at(Level.INFO).log("Player session service started");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
for (PlayerProfile profile : sessions.values()) {
|
||||
accumulatePlaytime(profile.getUuid(), profile);
|
||||
profile.setConnected(false);
|
||||
saveQuietly(profile);
|
||||
}
|
||||
sessions.clear();
|
||||
connectedAt.clear();
|
||||
logger.at(Level.INFO).log("Player session service stopped");
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads (or creates) a profile and marks the player connected.
|
||||
*/
|
||||
@Nonnull
|
||||
public PlayerProfile loadOrCreate(@Nonnull UUID uuid, @Nonnull String displayName) throws SQLException {
|
||||
long now = System.currentTimeMillis();
|
||||
Optional<PlayerProfile> existing = repository.findByUuid(uuid);
|
||||
PlayerProfile profile;
|
||||
if (existing.isPresent()) {
|
||||
profile = existing.get();
|
||||
profile.setDisplayName(displayName);
|
||||
} else {
|
||||
profile = new PlayerProfile(uuid, displayName, now);
|
||||
profile.setLevel(config.getDefaultLevel());
|
||||
profile.setRaceId(RaceCatalog.DEFAULT_RACE_ID);
|
||||
logger.at(Level.INFO).log("Created new MMORPG profile for %s", displayName);
|
||||
}
|
||||
|
||||
profile.setConnected(true);
|
||||
profile.setLastDateConnected(now);
|
||||
profile.touch();
|
||||
sessions.put(uuid, profile);
|
||||
connectedAt.put(uuid, now);
|
||||
saveQuietly(profile);
|
||||
return profile;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PlayerProfile getSession(@Nonnull UUID uuid) {
|
||||
return sessions.get(uuid);
|
||||
}
|
||||
|
||||
public void unload(@Nonnull UUID uuid) {
|
||||
PlayerProfile profile = sessions.remove(uuid);
|
||||
if (profile == null) {
|
||||
return;
|
||||
}
|
||||
accumulatePlaytime(uuid, profile);
|
||||
profile.setConnected(false);
|
||||
profile.touch();
|
||||
saveQuietly(profile);
|
||||
}
|
||||
|
||||
private void accumulatePlaytime(@Nonnull UUID uuid, @Nonnull PlayerProfile profile) {
|
||||
Long start = connectedAt.remove(uuid);
|
||||
if (start != null) {
|
||||
profile.addTimePlay(System.currentTimeMillis() - start);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveQuietly(@Nonnull PlayerProfile profile) {
|
||||
try {
|
||||
repository.save(profile);
|
||||
} catch (SQLException e) {
|
||||
logger.at(Level.WARNING).log(
|
||||
"Failed to save profile for %s: %s", profile.getUuid(), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user