Add PWs #61
@ -1,349 +1,349 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2022 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.sql;
|
||||
|
||||
import de.steamwar.sql.internal.*;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SteamwarUser {
|
||||
|
||||
static {
|
||||
new SqlTypeMapper<>(UUID.class, "CHAR(36)", (rs, identifier) -> UUID.fromString(rs.getString(identifier)), (st, index, value) -> st.setString(index, value.toString()));
|
||||
new SqlTypeMapper<>(Locale.class, "VARCHAR(32)", (rs, identifier) -> {
|
||||
String l = rs.getString(identifier);
|
||||
return l != null ? Locale.forLanguageTag(l) : null;
|
||||
}, (st, index, value) -> st.setString(index, value.toLanguageTag()));
|
||||
new SqlTypeMapper<>(SteamwarUser.class, null, (rs, identifier) -> { throw new SecurityException("SteamwarUser cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.id));
|
||||
}
|
||||
|
||||
private static final Table<SteamwarUser> table = new Table<>(SteamwarUser.class, "UserData");
|
||||
private static final Statement insert = table.insertFields("UUID", "UserName");
|
||||
private static final SelectStatement<SteamwarUser> byID = table.selectFields("id");
|
||||
private static final SelectStatement<SteamwarUser> byUUID = table.selectFields("UUID");
|
||||
private static final SelectStatement<SteamwarUser> byName = table.selectFields("UserName");
|
||||
private static final SelectStatement<SteamwarUser> byDiscord = table.selectFields("DiscordId");
|
||||
private static final SelectStatement<SteamwarUser> byTeam = table.selectFields("Team");
|
||||
private static final SelectStatement<SteamwarUser> getServerTeam = new SelectStatement<>(table, "SELECT * FROM UserData WHERE UserGroup != 'Member' AND UserGroup != 'YouTuber'");
|
||||
|
||||
private static final Statement updateName = table.update(Table.PRIMARY, "UserName");
|
||||
private static final Statement updatePassword = table.update(Table.PRIMARY, "Password");
|
||||
private static final Statement updateLocale = table.update(Table.PRIMARY, "Locale", "ManualLocale");
|
||||
private static final Statement updateTeam = table.update(Table.PRIMARY, "Team");
|
||||
private static final Statement updateLeader = table.update(Table.PRIMARY, "Leader");
|
||||
private static final Statement updateDiscord = table.update(Table.PRIMARY, "DiscordId");
|
||||
|
||||
private static final Statement getPlaytime = new Statement("SELECT SUM(UNIX_TIMESTAMP(EndTime) - UNIX_TIMESTAMP(StartTime)) as Playtime FROM Session WHERE UserID = ?");
|
||||
private static final Statement getFirstjoin = new Statement("SELECT MIN(StartTime) AS FirstJoin FROM Session WHERE UserID = ?");
|
||||
|
||||
private static final Map<Integer, SteamwarUser> usersById = new HashMap<>();
|
||||
private static final Map<UUID, SteamwarUser> usersByUUID = new HashMap<>();
|
||||
private static final Map<String, SteamwarUser> usersByName = new HashMap<>();
|
||||
private static final Map<Long, SteamwarUser> usersByDiscord = new HashMap<>();
|
||||
public static void clear() {
|
||||
usersById.clear();
|
||||
usersByName.clear();
|
||||
usersByUUID.clear();
|
||||
usersByDiscord.clear();
|
||||
}
|
||||
|
||||
public static void invalidate(int userId) {
|
||||
SteamwarUser user = usersById.remove(userId);
|
||||
if (user == null)
|
||||
return;
|
||||
usersByName.remove(user.getUserName());
|
||||
usersByUUID.remove(user.getUUID());
|
||||
usersByDiscord.remove(user.getDiscordId());
|
||||
}
|
||||
|
||||
public static SteamwarUser get(String userName){
|
||||
SteamwarUser user = usersByName.get(userName.toLowerCase());
|
||||
if(user != null)
|
||||
return user;
|
||||
return byName.select(userName);
|
||||
}
|
||||
|
||||
public static SteamwarUser get(UUID uuid){
|
||||
SteamwarUser user = usersByUUID.get(uuid);
|
||||
if(user != null)
|
||||
return user;
|
||||
return byUUID.select(uuid);
|
||||
}
|
||||
|
||||
public static SteamwarUser get(int id) {
|
||||
SteamwarUser user = usersById.get(id);
|
||||
if(user != null)
|
||||
return user;
|
||||
return byID.select(id);
|
||||
}
|
||||
|
||||
public static SteamwarUser get(Long discordId) {
|
||||
if(usersByDiscord.containsKey(discordId))
|
||||
return usersByDiscord.get(discordId);
|
||||
return byDiscord.select(discordId);
|
||||
}
|
||||
|
||||
public static SteamwarUser getOrCreate(UUID uuid, String name, Consumer<UUID> newPlayer, BiConsumer<String, String> nameUpdate) {
|
||||
SteamwarUser user = get(uuid);
|
||||
|
||||
if (user != null) {
|
||||
if (!user.userName.equals(name)) {
|
||||
updateName.update(name, user.id);
|
||||
nameUpdate.accept(user.userName, name);
|
||||
user.userName = name;
|
||||
}
|
||||
|
||||
return user;
|
||||
} else {
|
||||
insert.update(uuid, name);
|
||||
newPlayer.accept(uuid);
|
||||
return get(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<SteamwarUser> getServerTeam() {
|
||||
return getServerTeam.listSelect();
|
||||
}
|
||||
|
||||
public static List<SteamwarUser> getTeam(int teamId) {
|
||||
return byTeam.listSelect(teamId);
|
||||
}
|
||||
|
||||
public static void batchCache(Set<Integer> ids) {
|
||||
ids.removeIf(usersById::containsKey);
|
||||
if(ids.isEmpty())
|
||||
return;
|
||||
|
||||
try (SelectStatement<SteamwarUser> batch = new SelectStatement<>(table, "SELECT * FROM UserData WHERE id IN (" + ids.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")")) {
|
||||
batch.listSelect();
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
private final int id;
|
||||
@Field(keys = {"uuid"})
|
||||
private final UUID uuid;
|
||||
@Getter
|
||||
@Field
|
||||
private String userName;
|
||||
@Field(nullable = true)
|
||||
private String password;
|
||||
@Getter
|
||||
@Field(def = "0")
|
||||
private int team;
|
||||
@Getter
|
||||
@Field(def = "0")
|
||||
private boolean leader;
|
||||
@Field(nullable = true)
|
||||
private Locale locale;
|
||||
@Field(def = "0")
|
||||
private boolean manualLocale;
|
||||
@Getter
|
||||
@Field(keys = {"discordId"}, nullable = true)
|
||||
private Long discordId;
|
||||
|
||||
private Map<Punishment.PunishmentType, Punishment> punishments = null;
|
||||
private Set<UserPerm> permissions = null;
|
||||
private UserPerm.Prefix prefix = null;
|
||||
|
||||
public SteamwarUser(int id, UUID uuid, String userName, String password, int team, boolean leader, Locale locale, boolean manualLocale, Long discordId) {
|
||||
this.id = id;
|
||||
this.uuid = uuid;
|
||||
this.userName = userName;
|
||||
this.password = password;
|
||||
this.team = team;
|
||||
this.leader = leader;
|
||||
this.locale = locale;
|
||||
this.manualLocale = manualLocale;
|
||||
this.discordId = discordId != null && discordId != 0 ? discordId : null;
|
||||
|
||||
usersById.put(id, this);
|
||||
usersByName.put(userName.toLowerCase(), this);
|
||||
usersByUUID.put(uuid, this);
|
||||
if (this.discordId != null) {
|
||||
usersByDiscord.put(discordId, this);
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getUUID() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
if(locale != null)
|
||||
return locale;
|
||||
return Locale.getDefault();
|
||||
}
|
||||
|
||||
public Punishment getPunishment(Punishment.PunishmentType type) {
|
||||
initPunishments();
|
||||
return punishments.getOrDefault(type, null);
|
||||
}
|
||||
|
||||
public boolean isPunished(Punishment.PunishmentType punishment) {
|
||||
initPunishments();
|
||||
if (!punishments.containsKey(punishment)) {
|
||||
return false;
|
||||
}
|
||||
if (!punishments.get(punishment).isCurrent()) {
|
||||
if (punishment == Punishment.PunishmentType.Ban) {
|
||||
BannedUserIPs.unbanIPs(id);
|
||||
}
|
||||
punishments.remove(punishment);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasPerm(UserPerm perm) {
|
||||
initPerms();
|
||||
return permissions.contains(perm);
|
||||
}
|
||||
|
||||
public Set<UserPerm> perms() {
|
||||
initPerms();
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public UserPerm.Prefix prefix() {
|
||||
initPerms();
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public double getOnlinetime() {
|
||||
return getPlaytime.select(rs -> {
|
||||
if (rs.next() && rs.getBigDecimal("Playtime") != null)
|
||||
return rs.getBigDecimal("Playtime").doubleValue();
|
||||
return 0.0;
|
||||
}, id);
|
||||
}
|
||||
|
||||
public Timestamp getFirstjoin() {
|
||||
return getFirstjoin.select(rs -> {
|
||||
if (rs.next())
|
||||
return rs.getTimestamp("FirstJoin");
|
||||
return null;
|
||||
}, id);
|
||||
}
|
||||
|
||||
public void punish(Punishment.PunishmentType punishment, Timestamp time, String banReason, int from, boolean perma) {
|
||||
initPunishments();
|
||||
punishments.remove(punishment);
|
||||
punishments.put(punishment, Punishment.createPunishment(id, from, punishment, banReason, time, perma));
|
||||
}
|
||||
|
||||
public void setTeam(int team) {
|
||||
this.team = team;
|
||||
updateTeam.update(team, id);
|
||||
setLeader(false);
|
||||
}
|
||||
|
||||
public void setLeader(boolean leader) {
|
||||
this.leader = leader;
|
||||
updateLeader.update(leader, id);
|
||||
}
|
||||
|
||||
public void setLocale(Locale locale, boolean manualLocale) {
|
||||
if (locale == null || (this.manualLocale && !manualLocale))
|
||||
return;
|
||||
|
||||
this.locale = locale;
|
||||
this.manualLocale = manualLocale;
|
||||
updateLocale.update(locale.toLanguageTag(), manualLocale, id);
|
||||
}
|
||||
|
||||
public void setDiscordId(Long discordId) {
|
||||
usersByDiscord.remove(this.discordId);
|
||||
this.discordId = discordId;
|
||||
updateDiscord.update(discordId, id);
|
||||
if (discordId != null) {
|
||||
usersByDiscord.put(discordId, this);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void setPassword(String password) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] salt = new byte[16];
|
||||
random.nextBytes(salt);
|
||||
String saltString = Base64.getEncoder().encodeToString(salt);
|
||||
|
||||
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
|
||||
byte[] hash = factory.generateSecret(spec).getEncoded();
|
||||
|
||||
String hashString = Base64.getEncoder().encodeToString(hash);
|
||||
|
||||
this.password = hashString + ":" + saltString;
|
||||
updatePassword.update(this.password, id);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public boolean verifyPassword(String password) {
|
||||
if (this.password == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] parts = this.password.split(":");
|
||||
if (parts.length != 2) {
|
||||
SQLConfig.impl.getLogger().log(Level.SEVERE ,"Invalid password hash for user {0} ({1})", new Object[]{userName, id});
|
||||
return false;
|
||||
}
|
||||
|
||||
String hashString = parts[0];
|
||||
byte[] realHash = Base64.getDecoder().decode(hashString);
|
||||
String saltString = parts[1];
|
||||
byte[] salt = Base64.getDecoder().decode(saltString);
|
||||
|
||||
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
|
||||
byte[] hash = factory.generateSecret(spec).getEncoded();
|
||||
|
||||
return Arrays.equals(realHash, hash);
|
||||
}
|
||||
|
||||
private void initPunishments() {
|
||||
if(punishments != null)
|
||||
return;
|
||||
|
||||
punishments = Punishment.getPunishmentsOfPlayer(id);
|
||||
}
|
||||
|
||||
private void initPerms() {
|
||||
if(permissions != null)
|
||||
return;
|
||||
|
||||
permissions = UserPerm.getPerms(id);
|
||||
prefix = permissions.stream().filter(UserPerm.prefixes::containsKey).findAny().map(UserPerm.prefixes::get).orElse(UserPerm.emptyPrefix);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2022 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.sql;
|
||||
|
||||
import de.steamwar.sql.internal.*;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.SecureRandom;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SteamwarUser {
|
||||
|
||||
static {
|
||||
new SqlTypeMapper<>(UUID.class, "CHAR(36)", (rs, identifier) -> UUID.fromString(rs.getString(identifier)), (st, index, value) -> st.setString(index, value.toString()));
|
||||
new SqlTypeMapper<>(Locale.class, "VARCHAR(32)", (rs, identifier) -> {
|
||||
String l = rs.getString(identifier);
|
||||
return l != null ? Locale.forLanguageTag(l) : null;
|
||||
}, (st, index, value) -> st.setString(index, value.toLanguageTag()));
|
||||
new SqlTypeMapper<>(SteamwarUser.class, null, (rs, identifier) -> { throw new SecurityException("SteamwarUser cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.id));
|
||||
}
|
||||
|
||||
private static final Table<SteamwarUser> table = new Table<>(SteamwarUser.class, "UserData");
|
||||
private static final Statement insert = table.insertFields("UUID", "UserName");
|
||||
private static final SelectStatement<SteamwarUser> byID = table.selectFields("id");
|
||||
private static final SelectStatement<SteamwarUser> byUUID = table.selectFields("UUID");
|
||||
private static final SelectStatement<SteamwarUser> byName = table.selectFields("UserName");
|
||||
private static final SelectStatement<SteamwarUser> byDiscord = table.selectFields("DiscordId");
|
||||
private static final SelectStatement<SteamwarUser> byTeam = table.selectFields("Team");
|
||||
private static final SelectStatement<SteamwarUser> getServerTeam = new SelectStatement<>(table, "SELECT * FROM UserData WHERE UserGroup != 'Member' AND UserGroup != 'YouTuber'");
|
||||
|
||||
private static final Statement updateName = table.update(Table.PRIMARY, "UserName");
|
||||
private static final Statement updatePassword = table.update(Table.PRIMARY, "Password");
|
||||
private static final Statement updateLocale = table.update(Table.PRIMARY, "Locale", "ManualLocale");
|
||||
private static final Statement updateTeam = table.update(Table.PRIMARY, "Team");
|
||||
private static final Statement updateLeader = table.update(Table.PRIMARY, "Leader");
|
||||
private static final Statement updateDiscord = table.update(Table.PRIMARY, "DiscordId");
|
||||
|
||||
private static final Statement getPlaytime = new Statement("SELECT SUM(UNIX_TIMESTAMP(EndTime) - UNIX_TIMESTAMP(StartTime)) as Playtime FROM Session WHERE UserID = ?");
|
||||
private static final Statement getFirstjoin = new Statement("SELECT MIN(StartTime) AS FirstJoin FROM Session WHERE UserID = ?");
|
||||
|
||||
private static final Map<Integer, SteamwarUser> usersById = new HashMap<>();
|
||||
private static final Map<UUID, SteamwarUser> usersByUUID = new HashMap<>();
|
||||
private static final Map<String, SteamwarUser> usersByName = new HashMap<>();
|
||||
private static final Map<Long, SteamwarUser> usersByDiscord = new HashMap<>();
|
||||
public static void clear() {
|
||||
usersById.clear();
|
||||
usersByName.clear();
|
||||
usersByUUID.clear();
|
||||
usersByDiscord.clear();
|
||||
}
|
||||
|
||||
public static void invalidate(int userId) {
|
||||
SteamwarUser user = usersById.remove(userId);
|
||||
if (user == null)
|
||||
return;
|
||||
usersByName.remove(user.getUserName());
|
||||
usersByUUID.remove(user.getUUID());
|
||||
usersByDiscord.remove(user.getDiscordId());
|
||||
}
|
||||
|
||||
public static SteamwarUser get(String userName){
|
||||
SteamwarUser user = usersByName.get(userName.toLowerCase());
|
||||
if(user != null)
|
||||
return user;
|
||||
return byName.select(userName);
|
||||
}
|
||||
|
||||
public static SteamwarUser get(UUID uuid){
|
||||
SteamwarUser user = usersByUUID.get(uuid);
|
||||
if(user != null)
|
||||
return user;
|
||||
return byUUID.select(uuid);
|
||||
}
|
||||
|
||||
public static SteamwarUser get(int id) {
|
||||
SteamwarUser user = usersById.get(id);
|
||||
if(user != null)
|
||||
return user;
|
||||
return byID.select(id);
|
||||
}
|
||||
|
||||
public static SteamwarUser get(Long discordId) {
|
||||
if(usersByDiscord.containsKey(discordId))
|
||||
return usersByDiscord.get(discordId);
|
||||
return byDiscord.select(discordId);
|
||||
}
|
||||
|
||||
public static SteamwarUser getOrCreate(UUID uuid, String name, Consumer<UUID> newPlayer, BiConsumer<String, String> nameUpdate) {
|
||||
SteamwarUser user = get(uuid);
|
||||
|
||||
if (user != null) {
|
||||
if (!user.userName.equals(name)) {
|
||||
updateName.update(name, user.id);
|
||||
nameUpdate.accept(user.userName, name);
|
||||
user.userName = name;
|
||||
}
|
||||
|
||||
return user;
|
||||
} else {
|
||||
insert.update(uuid, name);
|
||||
newPlayer.accept(uuid);
|
||||
return get(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<SteamwarUser> getServerTeam() {
|
||||
return getServerTeam.listSelect();
|
||||
}
|
||||
|
||||
public static List<SteamwarUser> getTeam(int teamId) {
|
||||
return byTeam.listSelect(teamId);
|
||||
}
|
||||
|
||||
public static void batchCache(Set<Integer> ids) {
|
||||
ids.removeIf(usersById::containsKey);
|
||||
if(ids.isEmpty())
|
||||
return;
|
||||
|
||||
try (SelectStatement<SteamwarUser> batch = new SelectStatement<>(table, "SELECT * FROM UserData WHERE id IN (" + ids.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")")) {
|
||||
batch.listSelect();
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
private final int id;
|
||||
@Field(keys = {"uuid"})
|
||||
private final UUID uuid;
|
||||
@Getter
|
||||
@Field
|
||||
private String userName;
|
||||
@Field(nullable = true)
|
||||
private String password;
|
||||
@Getter
|
||||
@Field(def = "0")
|
||||
private int team;
|
||||
@Getter
|
||||
@Field(def = "0")
|
||||
private boolean leader;
|
||||
@Field(nullable = true)
|
||||
private Locale locale;
|
||||
@Field(def = "0")
|
||||
private boolean manualLocale;
|
||||
@Getter
|
||||
@Field(keys = {"discordId"}, nullable = true)
|
||||
private Long discordId;
|
||||
|
||||
private Map<Punishment.PunishmentType, Punishment> punishments = null;
|
||||
private Set<UserPerm> permissions = null;
|
||||
private UserPerm.Prefix prefix = null;
|
||||
|
||||
public SteamwarUser(int id, UUID uuid, String userName, String password, int team, boolean leader, Locale locale, boolean manualLocale, Long discordId) {
|
||||
this.id = id;
|
||||
this.uuid = uuid;
|
||||
this.userName = userName;
|
||||
this.password = password;
|
||||
this.team = team;
|
||||
this.leader = leader;
|
||||
this.locale = locale;
|
||||
this.manualLocale = manualLocale;
|
||||
this.discordId = discordId != null && discordId != 0 ? discordId : null;
|
||||
|
||||
usersById.put(id, this);
|
||||
usersByName.put(userName.toLowerCase(), this);
|
||||
usersByUUID.put(uuid, this);
|
||||
if (this.discordId != null) {
|
||||
usersByDiscord.put(discordId, this);
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getUUID() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
if(locale != null)
|
||||
return locale;
|
||||
return Locale.getDefault();
|
||||
}
|
||||
|
||||
public Punishment getPunishment(Punishment.PunishmentType type) {
|
||||
initPunishments();
|
||||
return punishments.getOrDefault(type, null);
|
||||
}
|
||||
|
||||
public boolean isPunished(Punishment.PunishmentType punishment) {
|
||||
initPunishments();
|
||||
if (!punishments.containsKey(punishment)) {
|
||||
return false;
|
||||
}
|
||||
if (!punishments.get(punishment).isCurrent()) {
|
||||
if (punishment == Punishment.PunishmentType.Ban) {
|
||||
BannedUserIPs.unbanIPs(id);
|
||||
}
|
||||
punishments.remove(punishment);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasPerm(UserPerm perm) {
|
||||
initPerms();
|
||||
return permissions.contains(perm);
|
||||
}
|
||||
|
||||
public Set<UserPerm> perms() {
|
||||
initPerms();
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public UserPerm.Prefix prefix() {
|
||||
initPerms();
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public double getOnlinetime() {
|
||||
return getPlaytime.select(rs -> {
|
||||
if (rs.next() && rs.getBigDecimal("Playtime") != null)
|
||||
return rs.getBigDecimal("Playtime").doubleValue();
|
||||
return 0.0;
|
||||
}, id);
|
||||
}
|
||||
|
||||
public Timestamp getFirstjoin() {
|
||||
return getFirstjoin.select(rs -> {
|
||||
if (rs.next())
|
||||
return rs.getTimestamp("FirstJoin");
|
||||
return null;
|
||||
}, id);
|
||||
}
|
||||
|
||||
public void punish(Punishment.PunishmentType punishment, Timestamp time, String banReason, int from, boolean perma) {
|
||||
initPunishments();
|
||||
punishments.remove(punishment);
|
||||
punishments.put(punishment, Punishment.createPunishment(id, from, punishment, banReason, time, perma));
|
||||
}
|
||||
|
||||
public void setTeam(int team) {
|
||||
this.team = team;
|
||||
updateTeam.update(team, id);
|
||||
setLeader(false);
|
||||
}
|
||||
|
||||
public void setLeader(boolean leader) {
|
||||
this.leader = leader;
|
||||
updateLeader.update(leader, id);
|
||||
}
|
||||
|
||||
public void setLocale(Locale locale, boolean manualLocale) {
|
||||
if (locale == null || (this.manualLocale && !manualLocale))
|
||||
return;
|
||||
|
||||
this.locale = locale;
|
||||
this.manualLocale = manualLocale;
|
||||
updateLocale.update(locale.toLanguageTag(), manualLocale, id);
|
||||
}
|
||||
|
||||
public void setDiscordId(Long discordId) {
|
||||
usersByDiscord.remove(this.discordId);
|
||||
this.discordId = discordId;
|
||||
updateDiscord.update(discordId, id);
|
||||
if (discordId != null) {
|
||||
usersByDiscord.put(discordId, this);
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public void setPassword(String password) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte[] salt = new byte[16];
|
||||
random.nextBytes(salt);
|
||||
String saltString = Base64.getEncoder().encodeToString(salt);
|
||||
|
||||
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 512);
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
|
||||
byte[] hash = factory.generateSecret(spec).getEncoded();
|
||||
|
||||
String hashString = Base64.getEncoder().encodeToString(hash);
|
||||
|
||||
this.password = hashString + ":" + saltString;
|
||||
updatePassword.update(this.password, id);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public boolean verifyPassword(String password) {
|
||||
if (this.password == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String[] parts = this.password.split(":");
|
||||
if (parts.length != 2) {
|
||||
SQLConfig.impl.getLogger().log(Level.SEVERE ,"Invalid password hash for user {0} ({1})", new Object[]{userName, id});
|
||||
return false;
|
||||
}
|
||||
|
||||
String hashString = parts[0];
|
||||
byte[] realHash = Base64.getDecoder().decode(hashString);
|
||||
String saltString = parts[1];
|
||||
byte[] salt = Base64.getDecoder().decode(saltString);
|
||||
|
||||
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 512);
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
|
||||
byte[] hash = factory.generateSecret(spec).getEncoded();
|
||||
|
||||
return Arrays.equals(realHash, hash);
|
||||
}
|
||||
|
||||
private void initPunishments() {
|
||||
if(punishments != null)
|
||||
return;
|
||||
|
||||
punishments = Punishment.getPunishmentsOfPlayer(id);
|
||||
}
|
||||
|
||||
private void initPerms() {
|
||||
if(permissions != null)
|
||||
return;
|
||||
|
||||
permissions = UserPerm.getPerms(id);
|
||||
prefix = permissions.stream().filter(UserPerm.prefixes::containsKey).findAny().map(UserPerm.prefixes::get).orElse(UserPerm.emptyPrefix);
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren