refactor server

This commit is contained in:
2024-01-01 21:51:21 +09:00
parent c55d170292
commit 2f3079faac
90 changed files with 293 additions and 203 deletions

View File

@@ -9,6 +9,8 @@ import java.util.concurrent.atomic.AtomicLong;
import org.kareha.hareka.ManuallyClosable;
import org.kareha.hareka.annotation.GuardedBy;
import org.kareha.hareka.annotation.NotFinalForTesting;
import org.kareha.hareka.annotation.NotPrivateForTesting;
import org.kareha.hareka.client.mirror.Mirrors;
import org.kareha.hareka.client.protocol.ServerPacket;
import org.kareha.hareka.client.protocol.ServerRequestPacket;
@@ -19,7 +21,7 @@ import org.kareha.hareka.protocol.ClientPacketType;
import org.kareha.hareka.protocol.HandlerTable;
import org.kareha.hareka.protocol.ProtocolSocket;
// not final for FakeSession
@NotFinalForTesting
public class Session implements ManuallyClosable {
private volatile ConnectionSettings.Entry connection;
@@ -37,12 +39,12 @@ public class Session implements ManuallyClosable {
private volatile Mirrors mirrors;
private final DiceRollTable diceRollTable = new DiceRollTable();
// not private for test
@NotPrivateForTesting
protected Session(final Context context) {
this.context = context;
}
// not private for test
@NotPrivateForTesting
protected ProtocolSocket<ClientPacketType, Session> newPacketSocket(final Socket socket,
final HandlerTable<ClientPacketType, Session> parserTable) {
return new ProtocolSocket<ClientPacketType, Session>(socket, parserTable, this) {
@@ -53,7 +55,7 @@ public class Session implements ManuallyClosable {
};
}
// not private for test
@NotPrivateForTesting
protected void initialize(final Socket socket, final HandlerTable<ClientPacketType, Session> parserTable) {
packetSocket = newPacketSocket(socket, parserTable);
mirrors = new Mirrors(this);

View File

@@ -12,9 +12,6 @@ import org.kareha.hareka.persistent.FastPersistentHashTable;
import org.kareha.hareka.persistent.PersistentHashTable;
import org.kareha.hareka.server.entity.Entities;
import org.kareha.hareka.server.entity.EntityStatic;
import org.kareha.hareka.server.external.SessionStatic;
import org.kareha.hareka.server.external.Sessions;
import org.kareha.hareka.server.external.GameServer;
import org.kareha.hareka.server.field.FieldStatic;
import org.kareha.hareka.server.field.Fields;
import org.kareha.hareka.server.game.CharacterSpawner;
@@ -22,6 +19,9 @@ import org.kareha.hareka.server.game.Clock;
import org.kareha.hareka.server.game.ItemSpawner;
import org.kareha.hareka.server.item.Items;
import org.kareha.hareka.server.net.Server;
import org.kareha.hareka.server.session.SessionServer;
import org.kareha.hareka.server.session.SessionStatic;
import org.kareha.hareka.server.session.Sessions;
import org.kareha.hareka.server.skill.ActiveSkills;
import org.kareha.hareka.server.stat.SpeciesTable;
import org.kareha.hareka.server.user.AccessController;
@@ -97,10 +97,10 @@ public final class Context {
characterSpawner = new CharacterSpawner(new File(dataDirectory, "CharacterSpawner.xml"));
itemSpawner = new ItemSpawner(new File(dataDirectory, "ItemSpawner.xml"));
if (parameters.noTls()) {
server = new GameServer(this, parameters.port(), null);
server = new SessionServer(this, parameters.port(), null);
} else {
final var keyStoreFile = new File(dataDirectory.getParent(), ServerConstants.KEY_STORE_FILENAME);
server = new GameServer(this, parameters.port(), keyStoreFile);
server = new SessionServer(this, parameters.port(), keyStoreFile);
}
}

View File

@@ -9,7 +9,7 @@ import javax.swing.SwingUtilities;
import org.kareha.hareka.logging.FileLogger;
import org.kareha.hareka.logging.SimpleLogger;
import org.kareha.hareka.server.net.ServerException;
import org.kareha.hareka.server.net.ServerSocketException;
import org.kareha.hareka.tool.KeyStoreUtil;
import org.kareha.hareka.tool.LogUtil;
import org.kareha.hareka.util.FileUtil;
@@ -62,7 +62,7 @@ final class Main {
case CONSOLE:
try {
Starter.INSTANCE.start(parameters);
} catch (final IOException | JAXBException | ServerException e) {
} catch (final IOException | JAXBException | ServerSocketException e) {
logger.log(Level.SEVERE, "", e);
return;
}

View File

@@ -19,7 +19,7 @@ import javax.swing.WindowConstants;
import org.kareha.hareka.annotation.ConfinedTo;
import org.kareha.hareka.annotation.Private;
import org.kareha.hareka.server.net.ServerException;
import org.kareha.hareka.server.net.ServerSocketException;
import org.kareha.hareka.ui.swing.LogPanel;
import jakarta.xml.bind.JAXBException;
@@ -115,7 +115,7 @@ public final class MainFrame extends JFrame {
new Thread(() -> {
try {
Starter.INSTANCE.start(params);
} catch (final IOException | JAXBException | ServerException e) {
} catch (final IOException | JAXBException | ServerSocketException e) {
SwingUtilities.invokeLater(() -> {
logger.log(Level.SEVERE, "", e);
JOptionPane.showMessageDialog(MainFrame.this, e.getMessage());

View File

@@ -6,7 +6,8 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.kareha.hareka.logging.SimpleLogger;
import org.kareha.hareka.server.net.ServerException;
import org.kareha.hareka.server.net.IllegalServerStateException;
import org.kareha.hareka.server.net.ServerSocketException;
import jakarta.xml.bind.JAXBException;
@@ -52,6 +53,13 @@ public enum Saver {
// Stop listening
try {
context.server().stop();
} catch (final IllegalServerStateException e) {
if (shutdown) {
SimpleLogger.INSTANCE.log("Failed to stop server; Server has already been stopped");
} else {
logger.warning("Failed to stop server; Server has already been stopped");
}
return;
} catch (final IOException e) {
if (shutdown) {
SimpleLogger.INSTANCE.log(e);
@@ -109,7 +117,10 @@ public enum Saver {
// Start listening
try {
context.server().start();
} catch (final IOException | ServerException e) {
} catch (final IllegalServerStateException e) {
logger.warning("Failed to start server; Server is already running.");
return;
} catch (final IOException | ServerSocketException e) {
logger.log(Level.SEVERE, "", e);
return;
}

View File

@@ -7,9 +7,10 @@ public final class ServerConstants {
}
public static final String KEY_STORE_FILENAME = "KeyStore";
// Using keytool, you must specify minimum 6 character password
public static final String KEY_STORE_PASSWORD = "foobar";
public static final String KEY_PASSWORD = "foobar";
// Using keytool, you must specify minimum 6 character password.
// "changeit" is the common default password in Java world.
public static final String KEY_STORE_PASSWORD = "changeit";
public static final String KEY_PASSWORD = "changeit";
public static final int CONNECTION_SIZE = 100;
public static final int MAX_CHARACTERS_PER_USER = 4;
public static final String DICE_ROLL_HASH_ALGORITHM = "SHA-256";

View File

@@ -6,7 +6,8 @@ import java.util.logging.Logger;
import org.kareha.hareka.Constants;
import org.kareha.hareka.annotation.GuardedBy;
import org.kareha.hareka.server.net.ServerException;
import org.kareha.hareka.server.net.IllegalServerStateException;
import org.kareha.hareka.server.net.ServerSocketException;
import org.kareha.hareka.util.FileUtil;
import jakarta.xml.bind.DatatypeConverter;
@@ -23,7 +24,7 @@ public enum Starter {
private boolean shutdownHookAdded = false;
public synchronized void start(final ServerParameters parameters)
throws IOException, JAXBException, ServerException {
throws IOException, JAXBException, ServerSocketException {
FileUtil.ensureDirectoryExists(parameters.liveDirectory());
final var crashedFile = new File(parameters.liveDirectory(), ServerConstants.CRASHED_FILENAME);
@@ -102,7 +103,11 @@ public enum Starter {
context.entities().startMotion();
// Start listening
context.server().start();
try {
context.server().start();
} catch (final IllegalServerStateException e) {
logger.warning("Failed to start server; Server is already running.");
}
}
}

View File

@@ -1,52 +0,0 @@
package org.kareha.hareka.server.external;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
import org.kareha.hareka.annotation.GuardedBy;
import org.kareha.hareka.annotation.ThreadSafe;
@ThreadSafe
public final class Sessions {
private static final Logger logger = Logger.getLogger(Sessions.class.getName());
@GuardedBy("this")
private final Set<Session> sessions = new HashSet<>();
public synchronized boolean addSession(final Session session) {
final var b = sessions.add(session);
if (b) {
logger.info(session.getStamp() + "Connected");
} else {
logger.warning(session.getStamp() + "Already connected");
}
return b;
}
public synchronized boolean removeSession(final Session session) {
final var b = sessions.remove(session);
if (b) {
logger.info(session.getStamp() + "Disconnected");
} else {
logger.warning(session.getStamp() + "Already disconnected");
}
return b;
}
public synchronized Collection<Session> getSessions() {
if (sessions.isEmpty()) {
return Collections.emptyList();
}
return new ArrayList<>(sessions);
}
public synchronized int sizeOfSessions() {
return sessions.size();
}
}

View File

@@ -18,7 +18,6 @@ import org.kareha.hareka.server.entity.ChatDriver;
import org.kareha.hareka.server.entity.ChatEntity;
import org.kareha.hareka.server.entity.FieldDriver;
import org.kareha.hareka.server.entity.FieldEntity;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.field.FieldPosition;
import org.kareha.hareka.server.field.ServerFieldObject;
import org.kareha.hareka.server.packet.AddActiveSkillPacket;
@@ -43,6 +42,7 @@ import org.kareha.hareka.server.packet.SelfNamePacket;
import org.kareha.hareka.server.packet.TilesPacket;
import org.kareha.hareka.server.packet.CooldownPacket;
import org.kareha.hareka.server.packet.WeightBarPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.server.stat.StatPoints;
import org.kareha.hareka.server.user.User;

View File

@@ -9,8 +9,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.field.ServerField;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class AddDownstairsHandler implements Handler<Session> {

View File

@@ -8,9 +8,9 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.field.FieldPosition;
import org.kareha.hareka.server.field.Gate;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class AddGatePairHandler implements Handler<Session> {

View File

@@ -9,8 +9,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.field.ServerField;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
import org.kareha.hareka.user.RoleSet;

View File

@@ -7,7 +7,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
public final class AutopilotHandler implements Handler<Session> {

View File

@@ -8,7 +8,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
public final class CancelPowHandler implements Handler<Session> {

View File

@@ -7,8 +7,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.game.TokenReceiver;
import org.kareha.hareka.server.session.Session;
public final class CancelTokenHandler implements Handler<Session> {

View File

@@ -10,8 +10,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.SelfNamePacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.tool.Utf8Util;
public final class ChangeNameHandler implements Handler<Session> {

View File

@@ -6,8 +6,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.CommandOutPacket;
import org.kareha.hareka.server.session.Session;
public final class CommandHandler implements Handler<Session> {

View File

@@ -8,7 +8,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
public final class ConsumeRoleTokenHandler implements Handler<Session> {

View File

@@ -9,8 +9,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RoleListPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.server.user.CustomRole;
import org.kareha.hareka.server.user.RolesLogRecord;
import org.kareha.hareka.user.Permission;

View File

@@ -9,8 +9,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.entity.CharacterEntity;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.CharactersPacket;
import org.kareha.hareka.server.session.Session;
public final class DeleteCharacterHandler implements Handler<Session> {

View File

@@ -7,7 +7,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
public final class DeleteItemHandler implements Handler<Session> {

View File

@@ -6,8 +6,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RoleTokenListPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class DeleteRoleTokenHandler implements Handler<Session> {

View File

@@ -9,8 +9,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.ServerConstants;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.DiceResultPacket;
import org.kareha.hareka.server.session.Session;
public final class DiceChoiceHandler implements Handler<Session> {

View File

@@ -9,8 +9,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.ServerConstants;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RequestDiceChoicePacket;
import org.kareha.hareka.server.session.Session;
public final class DiceTokenHandler implements Handler<Session> {

View File

@@ -13,8 +13,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.ServerConstants;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RequestPowPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class DrawLineHandler implements Handler<Session> {

View File

@@ -14,8 +14,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.ServerConstants;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RequestPowPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class DrawRingHandler implements Handler<Session> {

View File

@@ -7,7 +7,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
public final class DropItemHandler implements Handler<Session> {

View File

@@ -13,8 +13,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.ServerConstants;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RequestPowPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class FillRangeHandler implements Handler<Session> {

View File

@@ -12,8 +12,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.ServerConstants;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RequestPowPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class GenerateTerrainHandler implements Handler<Session> {

View File

@@ -6,8 +6,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.PlacementRecordPacket;
import org.kareha.hareka.server.session.Session;
public final class GetPlacementRecordHandler implements Handler<Session> {

View File

@@ -11,8 +11,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.entity.CharacterEntity;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.InspectionPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
import org.kareha.hareka.user.UserId;

View File

@@ -12,8 +12,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.entity.CharacterEntity;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.InspectionPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
import org.kareha.hareka.user.UserId;

View File

@@ -8,8 +8,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.TextPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.server.user.InvitationTokensLogRecord;
import org.kareha.hareka.user.Permission;

View File

@@ -7,8 +7,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.TextPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
import jakarta.xml.bind.DatatypeConverter;

View File

@@ -8,7 +8,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
public final class LocalChatHandler implements Handler<Session> {

View File

@@ -9,7 +9,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
public final class LocaleHandler implements Handler<Session> {

View File

@@ -10,9 +10,9 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.entity.CharacterEntity;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.field.FieldId;
import org.kareha.hareka.server.game.Player;
import org.kareha.hareka.server.session.Session;
public final class LoginCharacterHandler implements Handler<Session> {

View File

@@ -14,13 +14,13 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.game.TokenReceiver;
import org.kareha.hareka.server.packet.CharactersPacket;
import org.kareha.hareka.server.packet.MessagePacket;
import org.kareha.hareka.server.packet.RequestPowPacket;
import org.kareha.hareka.server.packet.RequestPublicKeyPacket;
import org.kareha.hareka.server.packet.RequestTokenPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.server.user.InvitationToken;
import org.kareha.hareka.server.user.InvitationTokensLogRecord;
import org.kareha.hareka.user.UserId;

View File

@@ -7,8 +7,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.CharactersPacket;
import org.kareha.hareka.server.session.Session;
public final class LogoutCharacterHandler implements Handler<Session> {

View File

@@ -7,8 +7,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.VersionPacket;
import org.kareha.hareka.server.session.Session;
public final class LogoutUserHandler implements Handler<Session> {

View File

@@ -10,8 +10,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.CooldownPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.server.stat.ExperienceType;
import org.kareha.hareka.server.stat.ExperienceVariation;

View File

@@ -11,8 +11,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.ServerConstants;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.CharactersPacket;
import org.kareha.hareka.server.session.Session;
public final class NewCharacterHandler implements Handler<Session> {

View File

@@ -11,11 +11,11 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.field.FieldPosition;
import org.kareha.hareka.server.field.Gate;
import org.kareha.hareka.server.field.PeriodicBoundary;
import org.kareha.hareka.server.field.ServerField;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class NewFieldHandler implements Handler<Session> {

View File

@@ -8,7 +8,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
public final class NoPublicKeyHandler implements Handler<Session> {

View File

@@ -8,7 +8,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
public final class PowHandler implements Handler<Session> {

View File

@@ -9,7 +9,7 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.entity.ChatEntity;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
public final class PrivateChatHandler implements Handler<Session> {

View File

@@ -12,7 +12,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
public final class PublicKeyHandler implements Handler<Session> {

View File

@@ -8,7 +8,7 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.Rebooter;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class RebootHandler implements Handler<Session> {

View File

@@ -7,7 +7,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class ReduceToBackgroundTilesHandler implements Handler<Session> {

View File

@@ -6,7 +6,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class RemoveOrphansHandler implements Handler<Session> {

View File

@@ -12,8 +12,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.field.ServerField;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class RemoveSpecialTileHandler implements Handler<Session> {

View File

@@ -6,8 +6,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.EchoPacket;
import org.kareha.hareka.server.session.Session;
public final class RequestEchoHandler implements Handler<Session> {

View File

@@ -6,8 +6,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.MyRolesPacket;
import org.kareha.hareka.server.session.Session;
public final class RequestMyRolesHandler implements Handler<Session> {

View File

@@ -10,9 +10,9 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.NoPublicKeyPacket;
import org.kareha.hareka.server.packet.PublicKeyPacket;
import org.kareha.hareka.server.session.Session;
import jakarta.xml.bind.JAXBException;

View File

@@ -7,8 +7,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RegionListPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class RequestRegionListHandler implements Handler<Session> {

View File

@@ -6,8 +6,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RoleListPacket;
import org.kareha.hareka.server.session.Session;
public final class RequestRoleListHandler implements Handler<Session> {

View File

@@ -6,8 +6,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RoleTokenListPacket;
import org.kareha.hareka.server.session.Session;
public final class RequestRoleTokenListHandler implements Handler<Session> {

View File

@@ -6,8 +6,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.SettingsPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class RequestSettingsHandler implements Handler<Session> {

View File

@@ -8,7 +8,7 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.Saver;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class SaveHandler implements Handler<Session> {

View File

@@ -10,7 +10,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class SetDefaultTilePatternHandler implements Handler<Session> {

View File

@@ -6,8 +6,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.field.FieldPosition;
import org.kareha.hareka.server.session.Session;
public final class SetMarkHandler implements Handler<Session> {

View File

@@ -10,8 +10,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.field.ServerSimpleRegion;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class SetRegionListHandler implements Handler<Session> {

View File

@@ -7,7 +7,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class SetRescueMethodsEnabledHandler implements Handler<Session> {

View File

@@ -7,7 +7,7 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
import org.kareha.hareka.user.UserRegistrationMode;

View File

@@ -8,7 +8,7 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.Rebooter;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class ShutdownHandler implements Handler<Session> {

View File

@@ -8,8 +8,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.field.FieldPosition;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.server.user.User;
public final class TeleportToCenterHandler implements Handler<Session> {

View File

@@ -7,8 +7,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.field.PlacementRecord;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class TeleportToPlacementRecordHandler implements Handler<Session> {

View File

@@ -12,8 +12,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.ServerConstants;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RequestPowPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.Permission;
public final class TileHandler implements Handler<Session> {

View File

@@ -7,8 +7,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.game.TokenReceiver;
import org.kareha.hareka.server.session.Session;
public final class TokenHandler implements Handler<Session> {

View File

@@ -9,8 +9,8 @@ import org.kareha.hareka.protocol.Handler;
import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.RoleListPacket;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.server.user.RolesLogRecord;
import org.kareha.hareka.user.Permission;

View File

@@ -10,8 +10,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.entity.FieldEntity;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.CooldownPacket;
import org.kareha.hareka.server.session.Session;
public final class UseActiveSkillHandler implements Handler<Session> {

View File

@@ -8,8 +8,8 @@ import org.kareha.hareka.protocol.HandlerException;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.protocol.ProtocolInput;
import org.kareha.hareka.server.entity.FieldEntity;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.packet.CooldownPacket;
import org.kareha.hareka.server.session.Session;
public final class UseItemHandler implements Handler<Session> {

View File

@@ -10,7 +10,7 @@ import java.util.logging.Logger;
import org.kareha.hareka.annotation.GuardedBy;
import org.kareha.hareka.annotation.Private;
public sealed abstract class AbstractServer implements Server permits SecureServer {
public sealed abstract class AbstractServer implements Server permits PlainServer, SecureServer {
@Private
static final Logger logger = Logger.getLogger(AbstractServer.class.getName());
@@ -28,28 +28,26 @@ public sealed abstract class AbstractServer implements Server permits SecureServ
return port;
}
protected abstract ServerSocket createServerSocket() throws IOException, ServerException;
protected abstract ServerSocket createServerSocket() throws IOException, ServerSocketException;
@SuppressWarnings("resource")
@Override
public synchronized boolean start() throws IOException, ServerException {
public synchronized void start() throws IOException, IllegalServerStateException, ServerSocketException {
if (thread != null) {
return false;
throw new IllegalServerStateException("Already started");
}
thread = new ServerThread(createServerSocket());
thread.start();
return true;
}
@Override
public synchronized boolean stop() throws IOException, InterruptedException {
public synchronized void stop() throws IOException, InterruptedException, IllegalServerStateException {
if (thread == null) {
return false;
throw new IllegalServerStateException("Already stopped");
}
thread.interrupt();
thread.join();
thread = null;
return true;
}
protected abstract void accepted(Socket clientSocket);

View File

@@ -0,0 +1,10 @@
package org.kareha.hareka.server.net;
@SuppressWarnings("serial")
public final class IllegalServerStateException extends Exception {
public IllegalServerStateException(final String message) {
super(message);
}
}

View File

@@ -0,0 +1,17 @@
package org.kareha.hareka.server.net;
import java.io.IOException;
import java.net.ServerSocket;
public non-sealed abstract class PlainServer extends AbstractServer {
public PlainServer(final int port) {
super(port);
}
@Override
protected ServerSocket createServerSocket() throws IOException {
return new ServerSocket(port());
}
}

View File

@@ -17,7 +17,6 @@ import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
@@ -36,7 +35,7 @@ public non-sealed abstract class SecureServer extends AbstractServer {
}
@Override
protected ServerSocket createServerSocket() throws IOException, ServerException {
protected ServerSocket createServerSocket() throws IOException, ServerSocketException {
final SSLContext sslContext;
try {
sslContext = SSLContext.getInstance("TLS");
@@ -56,15 +55,15 @@ public non-sealed abstract class SecureServer extends AbstractServer {
} catch (final NoSuchAlgorithmException e) {
throw new AssertionError(e);
} catch (final CertificateException e) {
throw new RuntimeException(e);
throw new ServerSocketException(e);
} catch (final IOException e) {
if (e.getCause() instanceof UnrecoverableKeyException) {
throw new ServerException("Store password may be incorrect", e);
if (e.getCause() instanceof UnrecoverableKeyException ex) {
throw new ServerSocketException("Store password may be incorrect", ex);
}
throw e;
}
} catch (final FileNotFoundException e) {
throw new ServerException("KeyStore not found", e);
throw new ServerSocketException("KeyStore file not found", e);
}
final KeyManagerFactory keyManagerFactory;
@@ -76,9 +75,9 @@ public non-sealed abstract class SecureServer extends AbstractServer {
try {
keyManagerFactory.init(keyStore, keyPassword);
} catch (final UnrecoverableKeyException e) {
throw new ServerException("Key password may be incorrect", e);
throw new ServerSocketException("Key password may be incorrect", e);
} catch (final KeyStoreException e) {
throw new RuntimeException(e);
throw new ServerSocketException(e);
} catch (final NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
@@ -88,13 +87,13 @@ public non-sealed abstract class SecureServer extends AbstractServer {
@Override
public void checkClientTrusted(final X509Certificate[] chain, final String authType)
throws CertificateException {
// TODO
// nothing to do
}
@Override
public void checkServerTrusted(final X509Certificate[] chain, final String authType)
throws CertificateException {
// TODO
// nothing to do
}
@Override
@@ -105,9 +104,9 @@ public non-sealed abstract class SecureServer extends AbstractServer {
try {
sslContext.init(km, tm, new SecureRandom());
} catch (final KeyManagementException e) {
throw new RuntimeException(e);
throw new ServerSocketException(e);
}
final SSLServerSocketFactory socketFactory = sslContext.getServerSocketFactory();
final var socketFactory = sslContext.getServerSocketFactory();
return socketFactory.createServerSocket(port());
}

View File

@@ -2,14 +2,15 @@ package org.kareha.hareka.server.net;
import java.io.IOException;
import org.kareha.hareka.server.external.GameServer;
import org.kareha.hareka.server.session.SessionServer;
public sealed interface Server permits AbstractServer, GameServer {
public sealed interface Server permits AbstractServer, SessionServer {
// used in logging
int port();
boolean start() throws IOException, ServerException;
void start() throws IOException, IllegalServerStateException, ServerSocketException;
boolean stop() throws IOException, InterruptedException;
void stop() throws IOException, InterruptedException, IllegalServerStateException;
}

View File

@@ -1,14 +0,0 @@
package org.kareha.hareka.server.net;
@SuppressWarnings("serial")
public final class ServerException extends Exception {
public ServerException(final String message) {
super(message);
}
public ServerException(final String message, final Throwable cause) {
super(message, cause);
}
}

View File

@@ -0,0 +1,22 @@
package org.kareha.hareka.server.net;
@SuppressWarnings("serial")
public final class ServerSocketException extends Exception {
public ServerSocketException() {
// do nothing
}
public ServerSocketException(final String message) {
super(message);
}
public ServerSocketException(final String message, final Throwable cause) {
super(message, cause);
}
public ServerSocketException(final Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,10 @@
package org.kareha.hareka.server.session;
@SuppressWarnings("serial")
public final class IllegalSessionStateException extends Exception {
public IllegalSessionStateException(final String message) {
super(message);
}
}

View File

@@ -1,13 +1,15 @@
package org.kareha.hareka.server.external;
package org.kareha.hareka.server.session;
import java.net.InetAddress;
import java.net.Socket;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.kareha.hareka.annotation.GuardedBy;
import org.kareha.hareka.annotation.NotPrivateForTesting;
import org.kareha.hareka.annotation.Private;
import org.kareha.hareka.game.PassiveSkillType;
import org.kareha.hareka.key.KeyReceiver;
@@ -49,25 +51,31 @@ public final class Session {
private Player player;
private final DiceRollTable diceRollTable = new DiceRollTable(ServerConstants.DICE_ROLL_HASH_ALGORITHM);
// not private for test
@NotPrivateForTesting
Session(final Context context) {
this.context = context;
id = context.sessionStatic().next();
}
// not private for test
@NotPrivateForTesting
ProtocolSocket<ServerPacketType, Session> newPacketSocket(final Socket socket,
final HandlerTable<ServerPacketType, Session> parserTable) {
return new ProtocolSocket<ServerPacketType, Session>(socket, parserTable, this) {
@Override
public void finish() {
logoutUser();
context.sessions().removeSession(Session.this);
try {
context.sessions().removeSession(Session.this);
} catch (final IllegalSessionStateException e) {
logger.log(Level.SEVERE, "", e);
return;
}
logger.info(Session.this.getStamp() + "Disconnected");
}
};
}
// not private for test
@NotPrivateForTesting
void initialize(final Socket socket, final HandlerTable<ServerPacketType, Session> parserTable) {
packetSocket = newPacketSocket(socket, parserTable);
}

View File

@@ -1,4 +1,4 @@
package org.kareha.hareka.server.external;
package org.kareha.hareka.server.session;
import org.kareha.hareka.annotation.Immutable;

View File

@@ -1,27 +1,29 @@
package org.kareha.hareka.server.external;
package org.kareha.hareka.server.session;
import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.kareha.hareka.protocol.HandlerTable;
import org.kareha.hareka.protocol.ServerPacketType;
import org.kareha.hareka.server.Context;
import org.kareha.hareka.server.ServerConstants;
import org.kareha.hareka.server.net.IllegalServerStateException;
import org.kareha.hareka.server.net.SecureServer;
import org.kareha.hareka.server.net.Server;
import org.kareha.hareka.server.net.ServerException;
import org.kareha.hareka.server.net.ServerSocketException;
import org.kareha.hareka.server.packet.VersionPacket;
public final class GameServer implements Server {
public final class SessionServer implements Server {
private static final Logger logger = Logger.getLogger(GameServer.class.getName());
private static final Logger logger = Logger.getLogger(SessionServer.class.getName());
private final Server server;
public GameServer(final Context context, final int port, final File keyStoreFile) {
public SessionServer(final Context context, final int port, final File keyStoreFile) {
if (keyStoreFile == null) {
throw new IllegalArgumentException("keyStoreFile must not be null");
}
@@ -31,7 +33,14 @@ public final class GameServer implements Server {
class Accepter {
void accepted(final Socket clientSocket) {
final var session = Session.newInstance(context, clientSocket, parserTable);
context.sessions().addSession(session);
try {
context.sessions().addSession(session);
} catch (final IllegalSessionStateException e) {
logger.log(Level.SEVERE, "", e);
return;
}
logger.info(session.getStamp() + "Connected");
session.start();
session.write(new VersionPacket());
@@ -54,25 +63,17 @@ public final class GameServer implements Server {
}
@Override
public boolean start() throws IOException, ServerException {
if (!server.start()) {
logger.warning("Failed to start server; Server is already running.");
return false;
}
public void start() throws IOException, IllegalServerStateException, ServerSocketException {
server.start();
logger.info(MessageFormat.format("Listening to port {0}", port()));
logger.info("Waiting for connections..");
return true;
}
@Override
public boolean stop() throws IOException, InterruptedException {
public void stop() throws IOException, InterruptedException, IllegalServerStateException {
logger.info("Stop Listening..");
if (!server.stop()) {
logger.warning("Failed to stop server; Server has already been stopped");
return false;
}
server.stop();
logger.info("Listening stopped");
return true;
}
}

View File

@@ -1,4 +1,4 @@
package org.kareha.hareka.server.external;
package org.kareha.hareka.server.session;
import java.io.File;
import java.util.concurrent.atomic.AtomicLong;

View File

@@ -0,0 +1,43 @@
package org.kareha.hareka.server.session;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.kareha.hareka.annotation.GuardedBy;
import org.kareha.hareka.annotation.ThreadSafe;
@ThreadSafe
public final class Sessions {
@GuardedBy("this")
private final Set<Session> sessions = new HashSet<>();
public synchronized void addSession(final Session session) throws IllegalSessionStateException {
final var success = sessions.add(session);
if (!success) {
throw new IllegalSessionStateException("Already connected");
}
}
public synchronized void removeSession(final Session session) throws IllegalSessionStateException {
final var success = sessions.remove(session);
if (!success) {
throw new IllegalSessionStateException("Already disconnected");
}
}
public synchronized Collection<Session> getSessions() {
if (sessions.isEmpty()) {
return Collections.emptyList();
}
return new ArrayList<>(sessions);
}
public synchronized int sizeOfSessions() {
return sessions.size();
}
}

View File

@@ -19,7 +19,7 @@ import org.kareha.hareka.annotation.GuardedBy;
import org.kareha.hareka.annotation.Private;
import org.kareha.hareka.annotation.ThreadSafe;
import org.kareha.hareka.server.entity.EntityId;
import org.kareha.hareka.server.external.SessionId;
import org.kareha.hareka.server.session.SessionId;
import org.kareha.hareka.user.UserId;
import jakarta.xml.bind.annotation.XmlAccessType;

View File

@@ -19,7 +19,7 @@ import org.kareha.hareka.annotation.Private;
import org.kareha.hareka.annotation.ThreadSafe;
import org.kareha.hareka.key.KeyXml;
import org.kareha.hareka.server.entity.EntityId;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.tool.JaxbUtil;
import org.kareha.hareka.user.UserId;

View File

@@ -13,7 +13,7 @@ import java.util.logging.Logger;
import org.kareha.hareka.annotation.GuardedBy;
import org.kareha.hareka.persistent.PersistentHashTable;
import org.kareha.hareka.protocol.ProtocolException;
import org.kareha.hareka.server.external.Session;
import org.kareha.hareka.server.session.Session;
import org.kareha.hareka.user.UserId;
import org.kareha.hareka.user.UserStatic;
import org.kareha.hareka.util.FileUtil;

View File

@@ -0,0 +1,14 @@
package org.kareha.hareka.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target({ ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD })
@Documented
public @interface NotFinalForTesting {
// marker annotation
}

View File

@@ -0,0 +1,14 @@
package org.kareha.hareka.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target({ ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD })
@Documented
public @interface NotPrivateForTesting {
// marker annotation
}