1package com.runehive.net.session;
3import com.jcabi.jdbc.JdbcSession;
4import com.runehive.Config;
5import com.runehive.RuneHive;
6import com.runehive.content.bot.BotUtility;
7import com.runehive.game.service.ForumService;
8import com.runehive.game.world.World;
9import com.runehive.game.world.entity.mob.player.BannedPlayers;
10import com.runehive.game.world.entity.mob.player.Player;
11import com.runehive.game.world.entity.mob.player.persist.PlayerSerializer;
12import com.runehive.game.world.entity.mob.player.profile.Profile;
13import com.runehive.game.world.entity.mob.player.profile.ProfileRepository;
14import com.runehive.net.codec.game.GamePacketDecoder;
15import com.runehive.net.codec.game.GamePacketEncoder;
16import com.runehive.net.codec.login.LoginDetailsPacket;
17import com.runehive.net.codec.login.LoginResponse;
18import com.runehive.net.codec.login.LoginResponsePacket;
19import com.runehive.util.Stopwatch;
20import com.runehive.util.Utility;
21import de.mkammerer.argon2.Argon2Factory.Argon2Types;
22import io.netty.channel.Channel;
23import io.netty.channel.ChannelFutureListener;
24import io.netty.channel.ChannelPipeline;
25import org.jire.runehiveps.Argon2;
26import org.mindrot.jbcrypt.BCrypt;
27import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
30import java.time.Instant;
32import java.util.concurrent.ConcurrentHashMap;
33import java.util.concurrent.ConcurrentMap;
34import java.util.concurrent.TimeUnit;
35import java.util.concurrent.atomic.AtomicInteger;
46 private static final ConcurrentMap<String, FailedLoginAttempt>
failedLogins =
new ConcurrentHashMap<>();
64 final String username =
packet.getUsername();
67 if (attempt !=
null) {
69 final AtomicInteger atomicTime = attempt.
getAttempt();
70 final int time = atomicTime.get();
79 atomicTime.incrementAndGet();
84 final String password =
packet.getPassword();
96 final Channel
channel = this.channel;
104 if (argon2Type !=
Argon2.DEFAULT_TYPE) {
106 final String passwordHash =
Argon2.getDefault().hash(
107 Argon2.DEFAULT_ITERATIONS,
109 Argon2.DEFAULT_PARALLELISM,
117 .addListener((ChannelFutureListener) sourceFuture -> {
119 final ChannelPipeline pipeline =
channel.pipeline();
120 pipeline.replace(
"login-decoder",
122 pipeline.replace(
"login-encoder",
130 }
catch (
final Exception e) {
131 logger.error(
"Failed to queue login for \"" + username +
"\"", e);
138 .addListener(ChannelFutureListener.CLOSE);
144 final boolean isEmail = username.indexOf(
'@') != -1;
153 if (username.equalsIgnoreCase(botName)) {
193 }
else if (password.isEmpty()) {
222 .sql(isEmail ?
"SELECT member_id, members_pass_hash, name, temp_ban FROM core_members WHERE UPPER(email) = ?" :
"SELECT member_id, members_pass_hash, temp_ban FROM core_members WHERE UPPER(name) = ?")
223 .set(username.toUpperCase())
224 .select((rset, stmt) -> {
226 final int memberId = rset.getInt(1);
227 final String passwordHash = rset.getString(2);
228 final String forumUsername = isEmail ? rset.getString(3) : username;
229 final long unixTime = rset.getLong(isEmail ? 4 : 3);
235 if (passwordHash.isEmpty()) {
237 }
else if (BCrypt.checkpw(player.
getPassword(), passwordHash)) {
249 }
catch (Exception ex) {
250 ex.printStackTrace();
259 }
else if (unixTime == -1) {
263 final Date date = Date.from(Instant.ofEpochSecond(unixTime));
265 final Date currentDate = Date.from(Instant.now());
267 return date.after(currentDate);
277 private final AtomicInteger
attempt =
new AtomicInteger(0);
The class that contains setting-related constants for the server.
static final boolean FORUM_INTEGRATION
If forum integration is true, users can only login if they enter the same username and password that'...
static final int USERNAME_MIN_CHARACTERS
static final int USERNAME_MAX_CHARACTERS
static final int FAILED_LOGIN_ATTEMPTS
static final int FAILED_LOGIN_TIMEOUT
static final int EMAIL_MAX_CHARACTERS
static final AttributeKey< Session > SESSION_KEY
The session key.
static final int MAX_PLAYERS
The maximum amount of players that can be held within the game world.
static final int EMAIL_MIN_CHARACTERS
static final AtomicBoolean serverStarted
static RuneHive getInstance()
LoginExecutorService getLoginExecutorService()
Holds all the constants used by bot.
static final String[] BOT_NAMES
List of all available bot names.
static HikariDataSource getConnectionPool()
Represents the game world.
static final AtomicBoolean update
static int getPlayerCount()
Gets the amount of valid players online.
static Optional< Player > search(String name)
Gets a player by name.
static Optional< Player > getPlayerByHash(long usernameHash)
static void queueLogin(Player player)
Handles queueing the player logins.
static Optional< Player > searchAll(String name)
static final List< String > bans
This class represents a character controlled by a player.
void setUsername(String username)
void setPassword(String password)
void setMemberId(int memberId)
void setSession(GameSession session)
final Set< String > hostList
static LoginResponse load(Player player, String expectedPassword)
Handles the profile repository, used for gathering important information for all created profiles.
static void put(Profile profile)
Puts a profile into the hash map.
void execute(final LoginSession loginSession, final LoginDetailsPacket loginDetailsPacket)
The class that reads packets from the client into GamePacket's.
An immutable message that is written through a channel and forwarded to the LoginResponseEncoder wher...
Represents a Session when a Player has been authenticated and active in the game world.
A data class that represents a failed login attempt.
final AtomicInteger attempt
AtomicInteger getAttempt()
final Stopwatch stopwatch
static final ConcurrentMap< String, FailedLoginAttempt > failedLogins
void handleClientPacket(Object o)
The method that is called when the client sends packets to the server.
LoginResponse evaluate(Player player)
void handleUserLoginDetails(final LoginDetailsPacket packet)
LoginResponse authenticatedForumUser(Player player, boolean isEmail)
LoginSession(Channel channel)
static void sendFailedResponse(final Channel channel, final LoginResponse response)
static final Logger logger
boolean isBanned(long unixTime)
final Channel channel
The channel attached to this session.
Session(Channel channel)
Creates a new Session.
boolean elapsed(long time, TimeUnit unit)
Handles miscellaneous methods.
static long nameToLong(String text)
Converts the first 12 characters in a string of text to a hash.
Represents the enumerated login response codes.