2022-09-08 10:42:57 +02:00
/ *
* 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 ;
2023-02-21 18:22:06 +01:00
import java.sql.Timestamp ;
2022-09-08 10:42:57 +02:00
import java.util.* ;
2023-02-21 18:22:06 +01:00
import java.util.function.BiConsumer ;
import java.util.function.Consumer ;
2022-09-08 10:42:57 +02:00
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 ( ) ) ) ;
SqlTypeMapper . nameEnumMapper ( UserGroup . class ) ;
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 " ) ;
2022-09-20 16:41:07 +02:00
private static final SelectStatement < SteamwarUser > byTeam = table . selectFields ( " Team " ) ;
2022-09-08 10:42:57 +02:00
private static final SelectStatement < SteamwarUser > getServerTeam = new SelectStatement < > ( table , " SELECT * FROM UserData WHERE UserGroup != 'Member' AND UserGroup != 'YouTuber' " ) ;
2023-02-21 18:22:06 +01:00
private static final SelectStatement < SteamwarUser > batchGet = new SelectStatement < > ( table , " SELECT * FROM UserData WHERE id IN ? " ) ;
2022-09-08 10:42:57 +02:00
private static final Statement updateName = table . update ( Table . PRIMARY , " UserName " ) ;
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 " ) ;
2023-02-21 18:22:06 +01:00
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 = ? " ) ;
2022-09-08 10:42:57 +02:00
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 ( ) ) ;
}
2023-02-21 18:22:06 +01:00
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 = SteamwarUser . get ( uuid ) ;
if ( user ! = null ) {
if ( ! user . userName . equals ( name ) ) {
updateName . update ( name , user . id ) ;
nameUpdate . accept ( user . userName , name ) ;
user . userName = name ;
}
} else {
insert . update ( uuid , name ) ;
newPlayer . accept ( uuid ) ;
return get ( uuid ) ;
}
return user ;
}
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 ;
batchGet . listSelect ( ( Object ) ids . toArray ( ) ) ;
}
2022-09-08 10:42:57 +02:00
@Getter
@Field ( keys = { Table . PRIMARY } , autoincrement = true )
private final int id ;
@Field ( keys = { " uuid " } )
private final UUID uuid ;
@Getter
@Field
private String userName ;
@Getter
@Field ( def = " 'Member' " )
private final UserGroup userGroup ;
@Getter
@Field ( def = " 0 " )
private int team ;
2023-02-21 18:22:06 +01:00
@Getter
2022-09-08 10:42:57 +02:00
@Field ( def = " 0 " )
private boolean leader ;
@Field ( nullable = true )
private Locale locale ;
@Field ( def = " 0 " )
private boolean manualLocale ;
2023-02-21 18:22:06 +01:00
@Getter
2022-09-08 10:42:57 +02:00
@Field ( keys = { " discordId " } , nullable = true )
private Long discordId ;
2023-02-21 18:22:06 +01:00
private final Map < Punishment . PunishmentType , Punishment > punishments ;
2022-09-08 10:42:57 +02:00
public SteamwarUser ( int id , UUID uuid , String userName , UserGroup userGroup , int team , boolean leader , Locale locale , boolean manualLocale , Long discordId ) {
this . id = id ;
this . uuid = uuid ;
this . userName = userName ;
this . userGroup = userGroup ;
this . team = team ;
this . leader = leader ;
this . locale = locale ;
this . manualLocale = manualLocale ;
2022-11-02 22:38:21 +01:00
this . discordId = discordId ! = null & & discordId ! = 0 ? discordId : null ;
2022-09-08 10:42:57 +02:00
usersById . put ( id , this ) ;
usersByName . put ( userName . toLowerCase ( ) , this ) ;
usersByUUID . put ( uuid , this ) ;
if ( this . discordId ! = null ) {
usersByDiscord . put ( discordId , this ) ;
}
2023-02-21 18:22:06 +01:00
punishments = Punishment . getPunishmentsOfPlayer ( id ) ; //TODO load always on Subservers?
2022-09-08 10:42:57 +02:00
}
public UUID getUUID ( ) {
return uuid ;
}
public Locale getLocale ( ) {
if ( locale ! = null )
return locale ;
2022-11-02 22:38:21 +01:00
return Locale . getDefault ( ) ;
}
2023-02-21 18:22:06 +01:00
public Punishment getPunishment ( Punishment . PunishmentType type ) {
return punishments . getOrDefault ( type , null ) ;
}
2022-11-02 22:38:21 +01:00
2023-02-21 18:22:06 +01:00
public boolean isPunished ( Punishment . PunishmentType punishment ) {
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 ;
2022-09-08 10:42:57 +02:00
}
2023-02-21 18:22:06 +01:00
public double getOnlinetime ( ) {
return getPlaytime . select ( rs - > {
if ( rs . next ( ) & & rs . getBigDecimal ( " Playtime " ) ! = null )
return rs . getBigDecimal ( " Playtime " ) . doubleValue ( ) ;
return 0 . 0 ;
} , id ) ;
2022-09-08 10:42:57 +02:00
}
2023-02-21 18:22:06 +01:00
public Timestamp getFirstjoin ( ) {
return getFirstjoin . select ( rs - > {
if ( rs . next ( ) )
return rs . getTimestamp ( " FirstJoin " ) ;
return null ;
} , id ) ;
2022-09-08 10:42:57 +02:00
}
2023-02-21 18:22:06 +01:00
public void punish ( Punishment . PunishmentType punishment , Timestamp time , String banReason , int from , boolean perma ) {
punishments . remove ( punishment ) ;
punishments . put ( punishment , Punishment . createPunishment ( id , from , punishment , banReason , time , perma ) ) ;
2022-09-08 10:42:57 +02:00
}
2023-02-21 18:22:06 +01:00
public void setTeam ( int team ) {
this . team = team ;
updateTeam . update ( team , id ) ;
setLeader ( false ) ;
2022-09-08 10:42:57 +02:00
}
2023-02-21 18:22:06 +01:00
public void setLeader ( boolean leader ) {
this . leader = leader ;
updateLeader . update ( leader , id ) ;
2022-09-20 16:41:07 +02:00
}
2023-02-21 18:22:06 +01:00
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 ) ;
2022-09-08 10:42:57 +02:00
}
2022-09-20 16:41:07 +02:00
2023-02-21 18:22:06 +01:00
public void setDiscordId ( Long discordId ) {
usersByDiscord . remove ( this . discordId ) ;
this . discordId = discordId ;
updateDiscord . update ( discordId , id ) ;
if ( discordId ! = null ) {
usersByDiscord . put ( discordId , this ) ;
}
2022-09-20 16:41:07 +02:00
}
2022-09-08 10:42:57 +02:00
}