diff --git a/.codesight/CODESIGHT.md b/.codesight/CODESIGHT.md index 949a540..acfeafa 100644 --- a/.codesight/CODESIGHT.md +++ b/.codesight/CODESIGHT.md @@ -2,11 +2,58 @@ > **Stack:** raw-http | none | unknown | scala -> 0 routes | 0 models | 0 components | 159 lib files | 1 env vars | 1 middleware +> 0 routes + 40 rpc | 0 models | 0 components | 140 lib files | 1 env vars | 1 middleware > **Token savings:** this file is ~0 tokens. Without it, AI exploration would cost ~0 tokens. **Saves ~0 tokens per conversation.** --- +# Routes + +## gRPC + +- `/CoordinatorService/BatchResubscribeGames` (BatchResubscribeRequest) → BatchResubscribeResponse +- `/CoordinatorService/UnsubscribeGames` (UnsubscribeGamesRequest) → UnsubscribeGamesResponse +- `/CoordinatorService/EvictGames` (EvictGamesRequest) → EvictGamesResponse +- `/CoordinatorService/DrainInstance` (DrainInstanceRequest) → DrainInstanceResponse +- `/CoordinatorService/BatchResubscribeGames` (BatchResubscribeRequest) → BatchResubscribeResponse +- `/CoordinatorService/UnsubscribeGames` (UnsubscribeGamesRequest) → UnsubscribeGamesResponse +- `/CoordinatorService/EvictGames` (EvictGamesRequest) → EvictGamesResponse +- `/CoordinatorService/DrainInstance` (DrainInstanceRequest) → DrainInstanceResponse +- `/IoService/ImportFen` (ProtoImportFenRequest) → ProtoGameContext +- `/IoService/ImportPgn` (ProtoImportPgnRequest) → ProtoGameContext +- `/IoService/ExportCombined` (ProtoGameContext) → ProtoCombinedExport +- `/IoService/ExportFen` (ProtoGameContext) → ProtoStringResult +- `/IoService/ExportPgn` (ProtoGameContext) → ProtoStringResult +- `/RuleService/CandidateMoves` (ProtoSquareRequest) → ProtoMoveList +- `/RuleService/LegalMoves` (ProtoSquareRequest) → ProtoMoveList +- `/RuleService/AllLegalMoves` (ProtoGameContext) → ProtoMoveList +- `/RuleService/IsCheck` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsCheckmate` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsStalemate` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsInsufficientMaterial` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsFiftyMoveRule` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsThreefoldRepetition` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/ApplyMove` (ProtoMoveRequest) → ProtoGameContext +- `/RuleService/PostMoveStatus` (ProtoGameContext) → ProtoPostMoveStatus +- `/IoService/ImportFen` (ProtoImportFenRequest) → ProtoGameContext +- `/IoService/ImportPgn` (ProtoImportPgnRequest) → ProtoGameContext +- `/IoService/ExportCombined` (ProtoGameContext) → ProtoCombinedExport +- `/IoService/ExportFen` (ProtoGameContext) → ProtoStringResult +- `/IoService/ExportPgn` (ProtoGameContext) → ProtoStringResult +- `/RuleService/CandidateMoves` (ProtoSquareRequest) → ProtoMoveList +- `/RuleService/LegalMoves` (ProtoSquareRequest) → ProtoMoveList +- `/RuleService/AllLegalMoves` (ProtoGameContext) → ProtoMoveList +- `/RuleService/IsCheck` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsCheckmate` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsStalemate` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsInsufficientMaterial` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsFiftyMoveRule` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsThreefoldRepetition` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/ApplyMove` (ProtoMoveRequest) → ProtoGameContext +- `/RuleService/PostMoveStatus` (ProtoGameContext) → ProtoPostMoveStatus + +--- + # Libraries - `jacoco-reporter/scoverage_coverage_gaps.py` @@ -28,7 +75,6 @@ - `modules/account/src/main/scala/de/nowchess/account/client/CoreGameClient.scala` — class CoreGameClient, function createGame - `modules/account/src/main/scala/de/nowchess/account/config/JacksonConfig.scala` — class JacksonConfig, function customize - `modules/account/src/main/scala/de/nowchess/account/config/NativeReflectionConfig.scala` — class NativeReflectionConfig -- `modules/account/src/main/scala/de/nowchess/account/domain/Account.scala` — class Account - `modules/account/src/main/scala/de/nowchess/account/domain/Challenge.scala` - class Challenge - function gameIdOpt @@ -39,15 +85,22 @@ - `modules/account/src/main/scala/de/nowchess/account/domain/ChallengeStatusConverter.scala` — class ChallengeStatusConverter - `modules/account/src/main/scala/de/nowchess/account/domain/DeclineReasonConverter.scala` — class DeclineReasonConverter - `modules/account/src/main/scala/de/nowchess/account/domain/TimeControl.scala` — class TimeControl +- `modules/account/src/main/scala/de/nowchess/account/domain/UserAccount.scala` + - class UserAccount + - function getBotAccounts + - class BotAccount + - class OfficialBotAccount - `modules/account/src/main/scala/de/nowchess/account/error/AccountError.scala` — function message - `modules/account/src/main/scala/de/nowchess/account/error/ChallengeError.scala` — function message +- `modules/account/src/main/scala/de/nowchess/account/filter/AlreadyLoggedInFilter.scala` — class AlreadyLoggedInFilter - `modules/account/src/main/scala/de/nowchess/account/repository/AccountRepository.scala` - - class AccountRepository + - class UserAccountRepository - function findByUsername - function findById - function persist - function findByEmail - function findAll + - _...12 more_ - `modules/account/src/main/scala/de/nowchess/account/repository/ChallengeRepository.scala` - class ChallengeRepository - function findActiveByChallengerId @@ -62,6 +115,8 @@ - function login - function me - function publicProfile + - function banUser + - _...10 more_ - `modules/account/src/main/scala/de/nowchess/account/resource/ChallengeResource.scala` - class ChallengeResource - function create @@ -75,6 +130,8 @@ - function login - function findByUsername - function findById + - function createBotAccount + - _...11 more_ - `modules/account/src/main/scala/de/nowchess/account/service/ChallengeService.scala` - class ChallengeService - function create @@ -83,48 +140,6 @@ - function cancel - function listForUser - _...1 more_ -- `modules/api/bin/scoverage/de/nowchess/api/board/Board.scala` - - class Board - - function apply - - function pieceAt - - function updated - - function removed - - function withMove - - _...2 more_ -- `modules/api/bin/scoverage/de/nowchess/api/board/CastlingRights.scala` - - function hasAnyRights - - function hasRights - - function revokeColor - - function revokeKingSide - - function revokeQueenSide - - class CastlingRights -- `modules/api/bin/scoverage/de/nowchess/api/board/Color.scala` — function opposite, function label -- `modules/api/bin/scoverage/de/nowchess/api/board/Piece.scala` — class Piece -- `modules/api/bin/scoverage/de/nowchess/api/board/PieceType.scala` — function label -- `modules/api/bin/scoverage/de/nowchess/api/board/Square.scala` - - class Square - - function fromAlgebraic - - function offset -- `modules/api/bin/scoverage/de/nowchess/api/bot/Bot.scala` - - class Bot - - function name - - function nextMove -- `modules/api/bin/scoverage/de/nowchess/api/dto/ErrorEventDto.scala` — class ErrorEventDto, function apply -- `modules/api/bin/scoverage/de/nowchess/api/dto/GameFullEventDto.scala` — class GameFullEventDto, function apply -- `modules/api/bin/scoverage/de/nowchess/api/dto/GameStateEventDto.scala` — class GameStateEventDto, function apply -- `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala` - - function kingSquare - - function withBoard - - function withTurn - - function withCastlingRights - - function withEnPassantSquare - - function withHalfMoveClock - - _...4 more_ -- `modules/api/bin/scoverage/de/nowchess/api/player/PlayerInfo.scala` — class PlayerId, function apply -- `modules/api/bin/scoverage/de/nowchess/api/response/ApiResponse.scala` - - class ApiResponse - - function error - - function totalPages - `modules/api/src/main/scala/de/nowchess/api/board/Board.scala` - class Board - function apply @@ -185,76 +200,7 @@ - function allLegalMoves - function isCheck - function isCheckmate - - _...5 more_ -- `modules/bot/bin/scoverage/de/nowchess/bot/BotController.scala` - - class BotController - - function getBot - - function listBots -- `modules/bot/bin/scoverage/de/nowchess/bot/BotMoveRepetition.scala` - - class BotMoveRepetition - - function blockedMoves - - function repeatedMove - - function filterAllowed -- `modules/bot/bin/scoverage/de/nowchess/bot/Config.scala` — class Config -- `modules/bot/bin/scoverage/de/nowchess/bot/ai/Evaluation.scala` - - class Evaluation - - class CHECKMATE_SCORE - - class DRAW_SCORE - - function evaluate - - function initAccumulator - - function copyAccumulator - - _...2 more_ -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/classic/EvaluationClassic.scala` - - class EvaluationClassic - - function evaluate - - function countRay -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/EvaluationNNUE.scala` — class EvaluationNNUE, function evaluate -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NNUE.scala` - - class NNUE - - function initAccumulator - - function pushAccumulator - - function copyAccumulator - - function recomputeAccumulator - - function validateAccumulator - - _...4 more_ -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NbaiLoader.scala` - - class NbaiLoader - - function load - - function loadDefault -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NbaiMigrator.scala` — class NbaiMigrator, function migrateFromBin -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NbaiModel.scala` - - function toJson - - class NbaiMetadata - - function fromJson - - function str - - function num -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NbaiWriter.scala` — class NbaiWriter, function write -- `modules/bot/bin/scoverage/de/nowchess/bot/logic/AlphaBetaSearch.scala` - - function bestMove - - function bestMove - - function bestMoveWithTime - - function bestMoveWithTime - - function loop - - function loop -- `modules/bot/bin/scoverage/de/nowchess/bot/logic/MoveOrdering.scala` - - class MoveOrdering - - class OrderingContext - - function addKillerMove - - function getKillerMoves - - function addHistory - - function getHistory - - _...3 more_ -- `modules/bot/bin/scoverage/de/nowchess/bot/logic/TranspositionTable.scala` - - function advance - - function probe - - function store - - function clear -- `modules/bot/bin/scoverage/de/nowchess/bot/util/PolyglotBook.scala` — function probe, function select -- `modules/bot/bin/scoverage/de/nowchess/bot/util/PolyglotHash.scala` — class PolyglotHash, function hash -- `modules/bot/bin/scoverage/de/nowchess/bot/util/ZobristHash.scala` - - class ZobristHash - - function hash - - function nextHash + - _...6 more_ - `modules/bot/python/nnue.py` - function get_weights_dir: () - function get_data_dir: () @@ -359,63 +305,65 @@ - class ZobristHash - function hash - function nextHash -- `modules/core/bin/scoverage/de/nowchess/chess/command/Command.scala` - - class Command - - function execute - - function undo - - function description - - class MoveResult -- `modules/core/bin/scoverage/de/nowchess/chess/command/CommandInvoker.scala` - - class CommandInvoker - - function execute - - function undo - - function redo - - function history - - function getCurrentIndex - - _...3 more_ -- `modules/core/bin/scoverage/de/nowchess/chess/config/JacksonConfig.scala` — class JacksonConfig, function customize -- `modules/core/bin/scoverage/de/nowchess/chess/controller/Parser.scala` — class Parser, function parseMove -- `modules/core/bin/scoverage/de/nowchess/chess/engine/GameEngine.scala` - - class GameEngine - - function board - - function turn - - function context - - function pendingDrawOfferBy - - function canUndo - - _...17 more_ -- `modules/core/bin/scoverage/de/nowchess/chess/exception/ApiException.scala` - - class ApiException - - class GameNotFoundException - - class BadRequestException -- `modules/core/bin/scoverage/de/nowchess/chess/exception/ApiExceptionMapper.scala` — class ApiExceptionMapper, function toResponse -- `modules/core/bin/scoverage/de/nowchess/chess/observer/Observer.scala` - - function context - - class Observer - - function onGameEvent - - class Observable - - function subscribe - - function unsubscribe +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/CoordinatorApp.scala` — class CoordinatorApp +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/config/BeansProducer.scala` + - class BeansProducer + - function redissonClient + - function kubernetesClient +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/config/CoordinatorConfig.scala` + - class CoordinatorConfig + - function maxGamesPerCore + - function maxDeviationPercent + - function rebalanceInterval + - function rebalanceMinInterval + - function heartbeatTtl + - _...11 more_ +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/grpc/CoordinatorGrpcServer.scala` — class CoordinatorGrpcServer +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/grpc/CoreGrpcClient.scala` + - class CoreGrpcClient + - function shutdown + - function batchResubscribeGames + - function unsubscribeGames + - function evictGames +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/resource/CoordinatorResource.scala` + - class CoordinatorResource + - function listInstances + - function getMetrics + - function triggerRebalance + - function triggerFailover + - function triggerScaleUp - _...1 more_ -- `modules/core/bin/scoverage/de/nowchess/chess/registry/GameRegistry.scala` - - class GameRegistry - - function store - - function get - - function update - - function generateId -- `modules/core/bin/scoverage/de/nowchess/chess/registry/GameRegistryImpl.scala` - - class GameRegistryImpl - - function store - - function get - - function update - - function generateId -- `modules/core/bin/scoverage/de/nowchess/chess/resource/GameResource.scala` - - class GameResource - - function onGameEvent - - function createGame - - function getGame - - function streamGame - - function onGameEvent - - _...10 more_ +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/AutoScaler.scala` + - class AutoScaler + - function checkAndScale + - function scaleUp + - function scaleDown +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/CacheEvictionManager.scala` + - class CacheEvictionManager + - function setRedisPrefix + - function evictStaleGames +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/FailoverService.scala` + - class FailoverService + - function setRedisPrefix + - function onInstanceStreamDropped +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/HealthMonitor.scala` + - class HealthMonitor + - function setRedisPrefix + - function checkInstanceHealth + - function watchK8sPods +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/InstanceRegistry.scala` + - class InstanceRegistry + - function setRedisPrefix + - function getInstance + - function getAllInstances + - function updateInstanceFromRedis + - function markInstanceDead + - _...1 more_ +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/LoadBalancer.scala` + - class LoadBalancer + - function setRedisPrefix + - function shouldRebalance + - function rebalance - `modules/core/src/main/scala/de/nowchess/chess/adapter/RuleSetRestAdapter.scala` - class RuleSetRestAdapter - function candidateMoves @@ -430,6 +378,7 @@ - function importPgn - function exportFen - function exportPgn + - function exportCombined - `modules/core/src/main/scala/de/nowchess/chess/client/RuleServiceClient.scala` - class RuleServiceClient - function candidateMoves @@ -437,23 +386,15 @@ - function allLegalMoves - function isCheck - function isCheckmate - - _...5 more_ -- `modules/core/src/main/scala/de/nowchess/chess/command/Command.scala` - - class Command - - function execute - - function undo - - function description - - class MoveResult -- `modules/core/src/main/scala/de/nowchess/chess/command/CommandInvoker.scala` - - class CommandInvoker - - function execute - - function undo - - function redo - - function history - - function getCurrentIndex - - _...3 more_ + - _...6 more_ +- `modules/core/src/main/scala/de/nowchess/chess/client/StoreServiceClient.scala` — class StoreServiceClient, function getGame - `modules/core/src/main/scala/de/nowchess/chess/config/JacksonConfig.scala` — class JacksonConfig, function customize - `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala` — class NativeReflectionConfig +- `modules/core/src/main/scala/de/nowchess/chess/config/RedisConfig.scala` — class RedisConfig +- `modules/core/src/main/scala/de/nowchess/chess/config/RedissonProducer.scala` + - class RedissonProducer + - function produceRedissonClient + - function shutdown - `modules/core/src/main/scala/de/nowchess/chess/controller/Parser.scala` — class Parser, function parseMove - `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala` - class GameEngine @@ -462,12 +403,36 @@ - function context - function pendingDrawOfferBy - function currentClockState - - _...18 more_ + - _...22 more_ - `modules/core/src/main/scala/de/nowchess/chess/exception/ApiException.scala` - class ApiException - class GameNotFoundException - class BadRequestException - `modules/core/src/main/scala/de/nowchess/chess/exception/ApiExceptionMapper.scala` — class ApiExceptionMapper, function toResponse +- `modules/core/src/main/scala/de/nowchess/chess/grpc/CoordinatorServiceHandler.scala` — class CoordinatorServiceHandler +- `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala` + - class CoreProtoMapper + - function toProtoColor + - function fromProtoColor + - function toProtoPieceType + - function fromProtoPieceType + - function toProtoMoveKind + - _...9 more_ +- `modules/core/src/main/scala/de/nowchess/chess/grpc/IoGrpcClientWrapper.scala` + - class IoGrpcClientWrapper + - function exportCombined + - function importFen + - function importPgn + - function exportFen + - function exportPgn +- `modules/core/src/main/scala/de/nowchess/chess/grpc/RuleSetGrpcAdapter.scala` + - class RuleSetGrpcAdapter + - function candidateMoves + - function legalMoves + - function allLegalMoves + - function isCheck + - function isCheckmate + - _...5 more_ - `modules/core/src/main/scala/de/nowchess/chess/observer/Observer.scala` - function context - class Observer @@ -476,18 +441,36 @@ - function subscribe - function unsubscribe - _...1 more_ +- `modules/core/src/main/scala/de/nowchess/chess/redis/C2sMessage.scala` — class C2sMessage +- `modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisPublisher.scala` — class GameRedisPublisher, function onGameEvent +- `modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisSubscriberManager.scala` + - class GameRedisSubscriberManager + - function subscribeGame + - function onMessage + - function unsubscribeGame + - function batchResubscribeGames + - function unsubscribeGames + - _...3 more_ - `modules/core/src/main/scala/de/nowchess/chess/registry/GameRegistry.scala` - class GameRegistry - function store - function get - function update - function generateId -- `modules/core/src/main/scala/de/nowchess/chess/registry/GameRegistryImpl.scala` - - class GameRegistryImpl +- `modules/core/src/main/scala/de/nowchess/chess/registry/RedisGameRegistry.scala` + - class RedisGameRegistry + - function generateId - function store - function get - function update - - function generateId +- `modules/core/src/main/scala/de/nowchess/chess/resource/GameDtoMapper.scala` + - class GameDtoMapper + - function statusOf + - function moveToUci + - function toPlayerDto + - function toClockDto + - function toGameStateDto + - _...1 more_ - `modules/core/src/main/scala/de/nowchess/chess/resource/GameResource.scala` - class GameResource - function onGameEvent @@ -495,54 +478,15 @@ - function getGame - function resignGame - function makeMove - - _...8 more_ -- `modules/core/src/main/scala/de/nowchess/chess/resource/GameWebSocketResource.scala` - - class GameWebSocketResource - - function onOpen - - function onGameEvent - - function onClose -- `modules/io/bin/scoverage/de/nowchess/io/GameContextExport.scala` — class GameContextExport, function exportGameContext -- `modules/io/bin/scoverage/de/nowchess/io/GameContextImport.scala` — class GameContextImport, function importGameContext -- `modules/io/bin/scoverage/de/nowchess/io/GameFileService.scala` - - class GameFileService - - function saveGameToFile - - function loadGameFromFile - - class FileSystemGameService - - function saveGameToFile - - function loadGameFromFile -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenExporter.scala` - - class FenExporter - - function boardToFen - - function gameContextToFen - - function exportGameContext -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenParser.scala` - - class FenParser - - function parseFen - - function importGameContext - - function parseBoard -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenParserCombinators.scala` - - class FenParserCombinators - - function parseFen - - function parseBoard - - function importGameContext -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenParserFastParse.scala` - - class FenParserFastParse - - function parseFen - - function parseBoard - - function importGameContext -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenParserSupport.scala` — function buildSquares -- `modules/io/bin/scoverage/de/nowchess/io/json/JsonExporter.scala` — class JsonExporter, function exportGameContext -- `modules/io/bin/scoverage/de/nowchess/io/json/JsonParser.scala` — class JsonParser, function importGameContext -- `modules/io/bin/scoverage/de/nowchess/io/pgn/PgnExporter.scala` - - class PgnExporter - - function exportGameContext - - function exportGame -- `modules/io/bin/scoverage/de/nowchess/io/pgn/PgnParser.scala` - - class PgnParser - - function validatePgn - - function importGameContext - - function parsePgn - - function parseAlgebraicMove + - _...9 more_ +- `modules/core/src/main/scala/de/nowchess/chess/service/InstanceHeartbeatService.scala` + - class InstanceHeartbeatService + - function onStart + - function onShutdown + - function setRedisPrefix + - function setSubscriptionCount + - function setLocalCacheSize + - _...2 more_ - `modules/io/src/main/scala/de/nowchess/io/GameFileService.scala` - class GameFileService - function saveGameToFile @@ -571,6 +515,15 @@ - function parseBoard - function importGameContext - `modules/io/src/main/scala/de/nowchess/io/fen/FenParserSupport.scala` — function buildSquares +- `modules/io/src/main/scala/de/nowchess/io/grpc/IoGrpcService.scala` — class IoGrpcService +- `modules/io/src/main/scala/de/nowchess/io/grpc/IoProtoMapper.scala` + - class IoProtoMapper + - function toProtoColor + - function fromProtoColor + - function toProtoPieceType + - function fromProtoPieceType + - function toProtoMoveKind + - _...9 more_ - `modules/io/src/main/scala/de/nowchess/io/json/JsonExporter.scala` — class JsonExporter, function exportGameContext - `modules/io/src/main/scala/de/nowchess/io/json/JsonParser.scala` — class JsonParser, function importGameContext - `modules/io/src/main/scala/de/nowchess/io/pgn/PgnExporter.scala` @@ -591,6 +544,7 @@ - function importPgn - function exportFen - function exportPgn + - function exportCombined - `modules/json/src/main/scala/de/nowchess/json/ChessJacksonModule.scala` — class ChessJacksonModule - `modules/json/src/main/scala/de/nowchess/json/GameResultDeserializer.scala` — class GameResultDeserializer - `modules/json/src/main/scala/de/nowchess/json/GameResultSerializer.scala` — class GameResultSerializer @@ -600,22 +554,17 @@ - `modules/json/src/main/scala/de/nowchess/json/SquareKeyDeserializer.scala` — class SquareKeyDeserializer - `modules/json/src/main/scala/de/nowchess/json/SquareKeySerializer.scala` — class SquareKeySerializer - `modules/json/src/main/scala/de/nowchess/json/SquareSerializer.scala` — class SquareSerializer -- `modules/rule/bin/scoverage/de/nowchess/rules/RuleSet.scala` - - class RuleSet - - function candidateMoves - - function legalMoves - - function allLegalMoves - - function isCheck - - function isCheckmate - - _...5 more_ -- `modules/rule/bin/scoverage/de/nowchess/rules/sets/DefaultRules.scala` - - class DefaultRules - - function positionOf - - function loop - - function toMoves - - function loop - `modules/rule/src/main/scala/de/nowchess/rules/config/JacksonConfig.scala` — class JacksonConfig, function customize - `modules/rule/src/main/scala/de/nowchess/rules/config/NativeReflectionConfig.scala` — class NativeReflectionConfig +- `modules/rule/src/main/scala/de/nowchess/rules/grpc/ProtoMapper.scala` + - class ProtoMapper + - function toProtoColor + - function fromProtoColor + - function toProtoPieceType + - function fromProtoPieceType + - function toProtoMoveKind + - _...9 more_ +- `modules/rule/src/main/scala/de/nowchess/rules/grpc/RuleGrpcService.scala` — class RuleGrpcService - `modules/rule/src/main/scala/de/nowchess/rules/resource/RuleSetResource.scala` - class RuleSetResource - function candidateMoves @@ -623,8 +572,36 @@ - function allLegalMoves - function isCheck - function isCheckmate - - _...5 more_ + - _...6 more_ - `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` — class DefaultRules, function positionOf +- `modules/store/src/main/scala/de/nowchess/store/config/RedisConfig.scala` — class RedisConfig +- `modules/store/src/main/scala/de/nowchess/store/config/RedissonProducer.scala` + - class RedissonProducer + - function redissonClient + - function close +- `modules/store/src/main/scala/de/nowchess/store/domain/GameRecord.scala` — class GameRecord +- `modules/store/src/main/scala/de/nowchess/store/redis/GameWritebackStreamListener.scala` + - class GameWritebackStreamListener + - function startListening + - function onMessage +- `modules/store/src/main/scala/de/nowchess/store/repository/GameRecordRepository.scala` + - class GameRecordRepository + - function findByGameId + - function persist + - function merge +- `modules/store/src/main/scala/de/nowchess/store/resource/StoreGameResource.scala` — class StoreGameResource, function getGame +- `modules/store/src/main/scala/de/nowchess/store/service/GameWritebackService.scala` — class GameWritebackService, function writeBack +- `modules/ws/src/main/scala/de/nowchess/ws/config/RedisConfig.scala` — class RedisConfig +- `modules/ws/src/main/scala/de/nowchess/ws/config/RedissonProducer.scala` + - class RedissonProducer + - function produceRedissonClient + - function shutdown +- `modules/ws/src/main/scala/de/nowchess/ws/resource/GameWebSocketResource.scala` + - class GameWebSocketResource + - function onOpen + - function onMessage + - function onTextMessage + - function onClose --- @@ -647,39 +624,39 @@ ## Most Imported Files (change these carefully) -- `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala` — imported by **138** files -- `modules/api/bin/scoverage/de/nowchess/api/board/Square.scala` — imported by **99** files -- `modules/api/bin/scoverage/de/nowchess/api/move/Move.scala` — imported by **97** files -- `modules/api/bin/scoverage/de/nowchess/api/board/Color.scala` — imported by **81** files -- `modules/rule/bin/scoverage/de/nowchess/rules/sets/DefaultRules.scala` — imported by **44** files -- `modules/api/bin/scoverage/de/nowchess/api/board/Board.scala` — imported by **39** files -- `modules/api/bin/scoverage/de/nowchess/api/board/Piece.scala` — imported by **39** files -- `modules/api/bin/scoverage/de/nowchess/api/board/PieceType.scala` — imported by **37** files -- `modules/api/bin/scoverage/de/nowchess/api/game/DrawReason.scala` — imported by **23** files -- `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala` — imported by **23** files -- `modules/api/bin/scoverage/de/nowchess/api/board/CastlingRights.scala` — imported by **22** files -- `modules/api/bin/scoverage/de/nowchess/api/game/GameResult.scala` — imported by **21** files -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenParser.scala` — imported by **20** files -- `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala` — imported by **15** files -- `modules/api/bin/scoverage/de/nowchess/api/player/PlayerInfo.scala` — imported by **14** files -- `modules/core/bin/scoverage/de/nowchess/chess/observer/Observer.scala` — imported by **13** files -- `modules/api/bin/scoverage/de/nowchess/api/bot/Bot.scala` — imported by **12** files -- `modules/bot/bin/scoverage/de/nowchess/bot/ai/Evaluation.scala` — imported by **12** files -- `modules/bot/bin/scoverage/de/nowchess/bot/util/PolyglotBook.scala` — imported by **10** files -- `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala` — imported by **10** files +- `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala` — imported by **76** files +- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala` — imported by **57** files +- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala` — imported by **55** files +- `modules/api/src/main/scala/de/nowchess/api/board/Color.scala` — imported by **46** files +- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` — imported by **28** files +- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala` — imported by **20** files +- `modules/api/src/main/scala/de/nowchess/api/board/PieceType.scala` — imported by **20** files +- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala` — imported by **20** files +- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala` — imported by **18** files +- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala` — imported by **18** files +- `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala` — imported by **14** files +- `modules/api/src/main/scala/de/nowchess/api/board/CastlingRights.scala` — imported by **13** files +- `modules/io/src/main/scala/de/nowchess/io/fen/FenParser.scala` — imported by **11** files +- `modules/api/src/main/scala/de/nowchess/api/player/PlayerInfo.scala` — imported by **9** files +- `modules/api/src/main/scala/de/nowchess/api/error/GameError.scala` — imported by **9** files +- `modules/core/src/main/scala/de/nowchess/chess/observer/Observer.scala` — imported by **9** files +- `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala` — imported by **8** files +- `modules/core/src/main/scala/de/nowchess/chess/grpc/IoGrpcClientWrapper.scala` — imported by **7** files +- `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala` — imported by **6** files +- `modules/bot/src/main/scala/de/nowchess/bot/ai/Evaluation.scala` — imported by **6** files ## Import Map (who imports what) -- `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala` ← `modules/api/bin/scoverage/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala` +133 more -- `modules/api/bin/scoverage/de/nowchess/api/board/Square.scala` ← `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala`, `modules/api/bin/scoverage/de/nowchess/api/move/Move.scala`, `modules/api/bin/test/de/nowchess/api/game/GameContextTest.scala`, `modules/api/bin/test/de/nowchess/api/move/MoveTest.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala` +94 more -- `modules/api/bin/scoverage/de/nowchess/api/move/Move.scala` ← `modules/api/bin/scoverage/de/nowchess/api/bot/Bot.scala`, `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala`, `modules/api/bin/test/de/nowchess/api/board/BoardTest.scala`, `modules/api/bin/test/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala` +92 more -- `modules/api/bin/scoverage/de/nowchess/api/board/Color.scala` ← `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala`, `modules/api/bin/scoverage/de/nowchess/api/game/GameResult.scala`, `modules/api/bin/test/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/main/scala/de/nowchess/api/game/ClockState.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala` +76 more -- `modules/rule/bin/scoverage/de/nowchess/rules/sets/DefaultRules.scala` ← `modules/bot/bin/scoverage/de/nowchess/bot/bots/ClassicalBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/HybridBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/NNUEBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/bin/test/de/nowchess/bot/AlphaBetaSearchTest.scala` +39 more -- `modules/api/bin/scoverage/de/nowchess/api/board/Board.scala` ← `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala`, `modules/api/bin/test/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NNUE.scala` +34 more -- `modules/api/bin/scoverage/de/nowchess/api/board/Piece.scala` ← `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/logic/MoveOrdering.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/util/PolyglotHash.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/util/ZobristHash.scala`, `modules/bot/bin/test/de/nowchess/bot/AlphaBetaSearchTest.scala` +34 more -- `modules/api/bin/scoverage/de/nowchess/api/board/PieceType.scala` ← `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/classic/EvaluationClassic.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/logic/AlphaBetaSearch.scala` +32 more -- `modules/api/bin/scoverage/de/nowchess/api/game/DrawReason.scala` ← `modules/api/bin/test/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/bin/scoverage/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/bin/scoverage/de/nowchess/chess/observer/Observer.scala`, `modules/core/bin/scoverage/de/nowchess/chess/resource/GameResource.scala` +18 more -- `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala` ← `modules/bot/bin/scoverage/de/nowchess/bot/bots/ClassicalBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/HybridBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/NNUEBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/bin/test/de/nowchess/bot/AlphaBetaSearchTest.scala` +18 more +- `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala` ← `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/bot/src/main/scala/de/nowchess/bot/BotMoveRepetition.scala` +71 more +- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala` ← `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/move/Move.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/test/scala/de/nowchess/api/move/MoveTest.scala` +52 more +- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala` ← `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/board/BoardTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala` +50 more +- `modules/api/src/main/scala/de/nowchess/api/board/Color.scala` ← `modules/api/src/main/scala/de/nowchess/api/game/ClockState.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala`, `modules/api/src/test/scala/de/nowchess/api/game/ClockStateTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala` +41 more +- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` ← `modules/bot/src/main/scala/de/nowchess/bot/bots/ClassicalBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/HybridBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/NNUEBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +23 more +- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala` ← `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +15 more +- `modules/api/src/main/scala/de/nowchess/api/board/PieceType.scala` ← `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/classic/EvaluationClassic.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala` +15 more +- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala` ← `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`, `modules/bot/src/main/scala/de/nowchess/bot/util/PolyglotHash.scala`, `modules/bot/src/main/scala/de/nowchess/bot/util/ZobristHash.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +15 more +- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala` ← `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala`, `modules/core/src/main/scala/de/nowchess/chess/observer/Observer.scala` +13 more +- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala` ← `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala`, `modules/core/src/main/scala/de/nowchess/chess/resource/GameDtoMapper.scala` +13 more --- diff --git a/.codesight/graph.md b/.codesight/graph.md index 4201932..0c644f6 100644 --- a/.codesight/graph.md +++ b/.codesight/graph.md @@ -2,36 +2,36 @@ ## Most Imported Files (change these carefully) -- `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala` — imported by **138** files -- `modules/api/bin/scoverage/de/nowchess/api/board/Square.scala` — imported by **99** files -- `modules/api/bin/scoverage/de/nowchess/api/move/Move.scala` — imported by **97** files -- `modules/api/bin/scoverage/de/nowchess/api/board/Color.scala` — imported by **81** files -- `modules/rule/bin/scoverage/de/nowchess/rules/sets/DefaultRules.scala` — imported by **44** files -- `modules/api/bin/scoverage/de/nowchess/api/board/Board.scala` — imported by **39** files -- `modules/api/bin/scoverage/de/nowchess/api/board/Piece.scala` — imported by **39** files -- `modules/api/bin/scoverage/de/nowchess/api/board/PieceType.scala` — imported by **37** files -- `modules/api/bin/scoverage/de/nowchess/api/game/DrawReason.scala` — imported by **23** files -- `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala` — imported by **23** files -- `modules/api/bin/scoverage/de/nowchess/api/board/CastlingRights.scala` — imported by **22** files -- `modules/api/bin/scoverage/de/nowchess/api/game/GameResult.scala` — imported by **21** files -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenParser.scala` — imported by **20** files -- `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala` — imported by **15** files -- `modules/api/bin/scoverage/de/nowchess/api/player/PlayerInfo.scala` — imported by **14** files -- `modules/core/bin/scoverage/de/nowchess/chess/observer/Observer.scala` — imported by **13** files -- `modules/api/bin/scoverage/de/nowchess/api/bot/Bot.scala` — imported by **12** files -- `modules/bot/bin/scoverage/de/nowchess/bot/ai/Evaluation.scala` — imported by **12** files -- `modules/bot/bin/scoverage/de/nowchess/bot/util/PolyglotBook.scala` — imported by **10** files -- `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala` — imported by **10** files +- `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala` — imported by **76** files +- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala` — imported by **57** files +- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala` — imported by **55** files +- `modules/api/src/main/scala/de/nowchess/api/board/Color.scala` — imported by **46** files +- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` — imported by **28** files +- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala` — imported by **20** files +- `modules/api/src/main/scala/de/nowchess/api/board/PieceType.scala` — imported by **20** files +- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala` — imported by **20** files +- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala` — imported by **18** files +- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala` — imported by **18** files +- `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala` — imported by **14** files +- `modules/api/src/main/scala/de/nowchess/api/board/CastlingRights.scala` — imported by **13** files +- `modules/io/src/main/scala/de/nowchess/io/fen/FenParser.scala` — imported by **11** files +- `modules/api/src/main/scala/de/nowchess/api/player/PlayerInfo.scala` — imported by **9** files +- `modules/api/src/main/scala/de/nowchess/api/error/GameError.scala` — imported by **9** files +- `modules/core/src/main/scala/de/nowchess/chess/observer/Observer.scala` — imported by **9** files +- `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala` — imported by **8** files +- `modules/core/src/main/scala/de/nowchess/chess/grpc/IoGrpcClientWrapper.scala` — imported by **7** files +- `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala` — imported by **6** files +- `modules/bot/src/main/scala/de/nowchess/bot/ai/Evaluation.scala` — imported by **6** files ## Import Map (who imports what) -- `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala` ← `modules/api/bin/scoverage/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala` +133 more -- `modules/api/bin/scoverage/de/nowchess/api/board/Square.scala` ← `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala`, `modules/api/bin/scoverage/de/nowchess/api/move/Move.scala`, `modules/api/bin/test/de/nowchess/api/game/GameContextTest.scala`, `modules/api/bin/test/de/nowchess/api/move/MoveTest.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala` +94 more -- `modules/api/bin/scoverage/de/nowchess/api/move/Move.scala` ← `modules/api/bin/scoverage/de/nowchess/api/bot/Bot.scala`, `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala`, `modules/api/bin/test/de/nowchess/api/board/BoardTest.scala`, `modules/api/bin/test/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala` +92 more -- `modules/api/bin/scoverage/de/nowchess/api/board/Color.scala` ← `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala`, `modules/api/bin/scoverage/de/nowchess/api/game/GameResult.scala`, `modules/api/bin/test/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/main/scala/de/nowchess/api/game/ClockState.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala` +76 more -- `modules/rule/bin/scoverage/de/nowchess/rules/sets/DefaultRules.scala` ← `modules/bot/bin/scoverage/de/nowchess/bot/bots/ClassicalBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/HybridBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/NNUEBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/bin/test/de/nowchess/bot/AlphaBetaSearchTest.scala` +39 more -- `modules/api/bin/scoverage/de/nowchess/api/board/Board.scala` ← `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala`, `modules/api/bin/test/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NNUE.scala` +34 more -- `modules/api/bin/scoverage/de/nowchess/api/board/Piece.scala` ← `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/logic/MoveOrdering.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/util/PolyglotHash.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/util/ZobristHash.scala`, `modules/bot/bin/test/de/nowchess/bot/AlphaBetaSearchTest.scala` +34 more -- `modules/api/bin/scoverage/de/nowchess/api/board/PieceType.scala` ← `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/classic/EvaluationClassic.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/logic/AlphaBetaSearch.scala` +32 more -- `modules/api/bin/scoverage/de/nowchess/api/game/DrawReason.scala` ← `modules/api/bin/test/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/bin/scoverage/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/bin/scoverage/de/nowchess/chess/observer/Observer.scala`, `modules/core/bin/scoverage/de/nowchess/chess/resource/GameResource.scala` +18 more -- `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala` ← `modules/bot/bin/scoverage/de/nowchess/bot/bots/ClassicalBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/HybridBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/bots/NNUEBot.scala`, `modules/bot/bin/scoverage/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/bin/test/de/nowchess/bot/AlphaBetaSearchTest.scala` +18 more +- `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala` ← `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextExport.scala`, `modules/api/src/main/scala/de/nowchess/api/io/GameContextImport.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/bot/src/main/scala/de/nowchess/bot/BotMoveRepetition.scala` +71 more +- `modules/api/src/main/scala/de/nowchess/api/board/Square.scala` ← `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/move/Move.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/api/src/test/scala/de/nowchess/api/move/MoveTest.scala` +52 more +- `modules/api/src/main/scala/de/nowchess/api/move/Move.scala` ← `modules/api/src/main/scala/de/nowchess/api/bot/Bot.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/rules/RuleSet.scala`, `modules/api/src/test/scala/de/nowchess/api/board/BoardTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala` +50 more +- `modules/api/src/main/scala/de/nowchess/api/board/Color.scala` ← `modules/api/src/main/scala/de/nowchess/api/game/ClockState.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala`, `modules/api/src/test/scala/de/nowchess/api/game/ClockStateTest.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala` +41 more +- `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` ← `modules/bot/src/main/scala/de/nowchess/bot/bots/ClassicalBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/HybridBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/NNUEBot.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +23 more +- `modules/api/src/main/scala/de/nowchess/api/board/Board.scala` ← `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +15 more +- `modules/api/src/main/scala/de/nowchess/api/board/PieceType.scala` ← `modules/api/src/main/scala/de/nowchess/api/game/GameContext.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/classic/EvaluationClassic.scala`, `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/AlphaBetaSearch.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala` +15 more +- `modules/api/src/main/scala/de/nowchess/api/board/Piece.scala` ← `modules/bot/src/main/scala/de/nowchess/bot/bots/nnue/NNUE.scala`, `modules/bot/src/main/scala/de/nowchess/bot/logic/MoveOrdering.scala`, `modules/bot/src/main/scala/de/nowchess/bot/util/PolyglotHash.scala`, `modules/bot/src/main/scala/de/nowchess/bot/util/ZobristHash.scala`, `modules/bot/src/test/scala/de/nowchess/bot/AlphaBetaSearchTest.scala` +15 more +- `modules/api/src/main/scala/de/nowchess/api/game/DrawReason.scala` ← `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala`, `modules/core/src/main/scala/de/nowchess/chess/observer/Observer.scala` +13 more +- `modules/api/src/main/scala/de/nowchess/api/game/GameResult.scala` ← `modules/api/src/test/scala/de/nowchess/api/game/GameContextTest.scala`, `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala`, `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala`, `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala`, `modules/core/src/main/scala/de/nowchess/chess/resource/GameDtoMapper.scala` +13 more diff --git a/.codesight/libs.md b/.codesight/libs.md index b560577..4ad2ab4 100644 --- a/.codesight/libs.md +++ b/.codesight/libs.md @@ -19,7 +19,6 @@ - `modules/account/src/main/scala/de/nowchess/account/client/CoreGameClient.scala` — class CoreGameClient, function createGame - `modules/account/src/main/scala/de/nowchess/account/config/JacksonConfig.scala` — class JacksonConfig, function customize - `modules/account/src/main/scala/de/nowchess/account/config/NativeReflectionConfig.scala` — class NativeReflectionConfig -- `modules/account/src/main/scala/de/nowchess/account/domain/Account.scala` — class Account - `modules/account/src/main/scala/de/nowchess/account/domain/Challenge.scala` - class Challenge - function gameIdOpt @@ -30,15 +29,22 @@ - `modules/account/src/main/scala/de/nowchess/account/domain/ChallengeStatusConverter.scala` — class ChallengeStatusConverter - `modules/account/src/main/scala/de/nowchess/account/domain/DeclineReasonConverter.scala` — class DeclineReasonConverter - `modules/account/src/main/scala/de/nowchess/account/domain/TimeControl.scala` — class TimeControl +- `modules/account/src/main/scala/de/nowchess/account/domain/UserAccount.scala` + - class UserAccount + - function getBotAccounts + - class BotAccount + - class OfficialBotAccount - `modules/account/src/main/scala/de/nowchess/account/error/AccountError.scala` — function message - `modules/account/src/main/scala/de/nowchess/account/error/ChallengeError.scala` — function message +- `modules/account/src/main/scala/de/nowchess/account/filter/AlreadyLoggedInFilter.scala` — class AlreadyLoggedInFilter - `modules/account/src/main/scala/de/nowchess/account/repository/AccountRepository.scala` - - class AccountRepository + - class UserAccountRepository - function findByUsername - function findById - function persist - function findByEmail - function findAll + - _...12 more_ - `modules/account/src/main/scala/de/nowchess/account/repository/ChallengeRepository.scala` - class ChallengeRepository - function findActiveByChallengerId @@ -53,6 +59,8 @@ - function login - function me - function publicProfile + - function banUser + - _...10 more_ - `modules/account/src/main/scala/de/nowchess/account/resource/ChallengeResource.scala` - class ChallengeResource - function create @@ -66,6 +74,8 @@ - function login - function findByUsername - function findById + - function createBotAccount + - _...11 more_ - `modules/account/src/main/scala/de/nowchess/account/service/ChallengeService.scala` - class ChallengeService - function create @@ -74,48 +84,6 @@ - function cancel - function listForUser - _...1 more_ -- `modules/api/bin/scoverage/de/nowchess/api/board/Board.scala` - - class Board - - function apply - - function pieceAt - - function updated - - function removed - - function withMove - - _...2 more_ -- `modules/api/bin/scoverage/de/nowchess/api/board/CastlingRights.scala` - - function hasAnyRights - - function hasRights - - function revokeColor - - function revokeKingSide - - function revokeQueenSide - - class CastlingRights -- `modules/api/bin/scoverage/de/nowchess/api/board/Color.scala` — function opposite, function label -- `modules/api/bin/scoverage/de/nowchess/api/board/Piece.scala` — class Piece -- `modules/api/bin/scoverage/de/nowchess/api/board/PieceType.scala` — function label -- `modules/api/bin/scoverage/de/nowchess/api/board/Square.scala` - - class Square - - function fromAlgebraic - - function offset -- `modules/api/bin/scoverage/de/nowchess/api/bot/Bot.scala` - - class Bot - - function name - - function nextMove -- `modules/api/bin/scoverage/de/nowchess/api/dto/ErrorEventDto.scala` — class ErrorEventDto, function apply -- `modules/api/bin/scoverage/de/nowchess/api/dto/GameFullEventDto.scala` — class GameFullEventDto, function apply -- `modules/api/bin/scoverage/de/nowchess/api/dto/GameStateEventDto.scala` — class GameStateEventDto, function apply -- `modules/api/bin/scoverage/de/nowchess/api/game/GameContext.scala` - - function kingSquare - - function withBoard - - function withTurn - - function withCastlingRights - - function withEnPassantSquare - - function withHalfMoveClock - - _...4 more_ -- `modules/api/bin/scoverage/de/nowchess/api/player/PlayerInfo.scala` — class PlayerId, function apply -- `modules/api/bin/scoverage/de/nowchess/api/response/ApiResponse.scala` - - class ApiResponse - - function error - - function totalPages - `modules/api/src/main/scala/de/nowchess/api/board/Board.scala` - class Board - function apply @@ -176,76 +144,7 @@ - function allLegalMoves - function isCheck - function isCheckmate - - _...5 more_ -- `modules/bot/bin/scoverage/de/nowchess/bot/BotController.scala` - - class BotController - - function getBot - - function listBots -- `modules/bot/bin/scoverage/de/nowchess/bot/BotMoveRepetition.scala` - - class BotMoveRepetition - - function blockedMoves - - function repeatedMove - - function filterAllowed -- `modules/bot/bin/scoverage/de/nowchess/bot/Config.scala` — class Config -- `modules/bot/bin/scoverage/de/nowchess/bot/ai/Evaluation.scala` - - class Evaluation - - class CHECKMATE_SCORE - - class DRAW_SCORE - - function evaluate - - function initAccumulator - - function copyAccumulator - - _...2 more_ -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/classic/EvaluationClassic.scala` - - class EvaluationClassic - - function evaluate - - function countRay -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/EvaluationNNUE.scala` — class EvaluationNNUE, function evaluate -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NNUE.scala` - - class NNUE - - function initAccumulator - - function pushAccumulator - - function copyAccumulator - - function recomputeAccumulator - - function validateAccumulator - - _...4 more_ -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NbaiLoader.scala` - - class NbaiLoader - - function load - - function loadDefault -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NbaiMigrator.scala` — class NbaiMigrator, function migrateFromBin -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NbaiModel.scala` - - function toJson - - class NbaiMetadata - - function fromJson - - function str - - function num -- `modules/bot/bin/scoverage/de/nowchess/bot/bots/nnue/NbaiWriter.scala` — class NbaiWriter, function write -- `modules/bot/bin/scoverage/de/nowchess/bot/logic/AlphaBetaSearch.scala` - - function bestMove - - function bestMove - - function bestMoveWithTime - - function bestMoveWithTime - - function loop - - function loop -- `modules/bot/bin/scoverage/de/nowchess/bot/logic/MoveOrdering.scala` - - class MoveOrdering - - class OrderingContext - - function addKillerMove - - function getKillerMoves - - function addHistory - - function getHistory - - _...3 more_ -- `modules/bot/bin/scoverage/de/nowchess/bot/logic/TranspositionTable.scala` - - function advance - - function probe - - function store - - function clear -- `modules/bot/bin/scoverage/de/nowchess/bot/util/PolyglotBook.scala` — function probe, function select -- `modules/bot/bin/scoverage/de/nowchess/bot/util/PolyglotHash.scala` — class PolyglotHash, function hash -- `modules/bot/bin/scoverage/de/nowchess/bot/util/ZobristHash.scala` - - class ZobristHash - - function hash - - function nextHash + - _...6 more_ - `modules/bot/python/nnue.py` - function get_weights_dir: () - function get_data_dir: () @@ -350,63 +249,65 @@ - class ZobristHash - function hash - function nextHash -- `modules/core/bin/scoverage/de/nowchess/chess/command/Command.scala` - - class Command - - function execute - - function undo - - function description - - class MoveResult -- `modules/core/bin/scoverage/de/nowchess/chess/command/CommandInvoker.scala` - - class CommandInvoker - - function execute - - function undo - - function redo - - function history - - function getCurrentIndex - - _...3 more_ -- `modules/core/bin/scoverage/de/nowchess/chess/config/JacksonConfig.scala` — class JacksonConfig, function customize -- `modules/core/bin/scoverage/de/nowchess/chess/controller/Parser.scala` — class Parser, function parseMove -- `modules/core/bin/scoverage/de/nowchess/chess/engine/GameEngine.scala` - - class GameEngine - - function board - - function turn - - function context - - function pendingDrawOfferBy - - function canUndo - - _...17 more_ -- `modules/core/bin/scoverage/de/nowchess/chess/exception/ApiException.scala` - - class ApiException - - class GameNotFoundException - - class BadRequestException -- `modules/core/bin/scoverage/de/nowchess/chess/exception/ApiExceptionMapper.scala` — class ApiExceptionMapper, function toResponse -- `modules/core/bin/scoverage/de/nowchess/chess/observer/Observer.scala` - - function context - - class Observer - - function onGameEvent - - class Observable - - function subscribe - - function unsubscribe +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/CoordinatorApp.scala` — class CoordinatorApp +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/config/BeansProducer.scala` + - class BeansProducer + - function redissonClient + - function kubernetesClient +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/config/CoordinatorConfig.scala` + - class CoordinatorConfig + - function maxGamesPerCore + - function maxDeviationPercent + - function rebalanceInterval + - function rebalanceMinInterval + - function heartbeatTtl + - _...11 more_ +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/grpc/CoordinatorGrpcServer.scala` — class CoordinatorGrpcServer +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/grpc/CoreGrpcClient.scala` + - class CoreGrpcClient + - function shutdown + - function batchResubscribeGames + - function unsubscribeGames + - function evictGames +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/resource/CoordinatorResource.scala` + - class CoordinatorResource + - function listInstances + - function getMetrics + - function triggerRebalance + - function triggerFailover + - function triggerScaleUp - _...1 more_ -- `modules/core/bin/scoverage/de/nowchess/chess/registry/GameRegistry.scala` - - class GameRegistry - - function store - - function get - - function update - - function generateId -- `modules/core/bin/scoverage/de/nowchess/chess/registry/GameRegistryImpl.scala` - - class GameRegistryImpl - - function store - - function get - - function update - - function generateId -- `modules/core/bin/scoverage/de/nowchess/chess/resource/GameResource.scala` - - class GameResource - - function onGameEvent - - function createGame - - function getGame - - function streamGame - - function onGameEvent - - _...10 more_ +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/AutoScaler.scala` + - class AutoScaler + - function checkAndScale + - function scaleUp + - function scaleDown +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/CacheEvictionManager.scala` + - class CacheEvictionManager + - function setRedisPrefix + - function evictStaleGames +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/FailoverService.scala` + - class FailoverService + - function setRedisPrefix + - function onInstanceStreamDropped +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/HealthMonitor.scala` + - class HealthMonitor + - function setRedisPrefix + - function checkInstanceHealth + - function watchK8sPods +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/InstanceRegistry.scala` + - class InstanceRegistry + - function setRedisPrefix + - function getInstance + - function getAllInstances + - function updateInstanceFromRedis + - function markInstanceDead + - _...1 more_ +- `modules/coordinator/src/main/scala/de/nowchess/coordinator/service/LoadBalancer.scala` + - class LoadBalancer + - function setRedisPrefix + - function shouldRebalance + - function rebalance - `modules/core/src/main/scala/de/nowchess/chess/adapter/RuleSetRestAdapter.scala` - class RuleSetRestAdapter - function candidateMoves @@ -421,6 +322,7 @@ - function importPgn - function exportFen - function exportPgn + - function exportCombined - `modules/core/src/main/scala/de/nowchess/chess/client/RuleServiceClient.scala` - class RuleServiceClient - function candidateMoves @@ -428,23 +330,15 @@ - function allLegalMoves - function isCheck - function isCheckmate - - _...5 more_ -- `modules/core/src/main/scala/de/nowchess/chess/command/Command.scala` - - class Command - - function execute - - function undo - - function description - - class MoveResult -- `modules/core/src/main/scala/de/nowchess/chess/command/CommandInvoker.scala` - - class CommandInvoker - - function execute - - function undo - - function redo - - function history - - function getCurrentIndex - - _...3 more_ + - _...6 more_ +- `modules/core/src/main/scala/de/nowchess/chess/client/StoreServiceClient.scala` — class StoreServiceClient, function getGame - `modules/core/src/main/scala/de/nowchess/chess/config/JacksonConfig.scala` — class JacksonConfig, function customize - `modules/core/src/main/scala/de/nowchess/chess/config/NativeReflectionConfig.scala` — class NativeReflectionConfig +- `modules/core/src/main/scala/de/nowchess/chess/config/RedisConfig.scala` — class RedisConfig +- `modules/core/src/main/scala/de/nowchess/chess/config/RedissonProducer.scala` + - class RedissonProducer + - function produceRedissonClient + - function shutdown - `modules/core/src/main/scala/de/nowchess/chess/controller/Parser.scala` — class Parser, function parseMove - `modules/core/src/main/scala/de/nowchess/chess/engine/GameEngine.scala` - class GameEngine @@ -453,12 +347,36 @@ - function context - function pendingDrawOfferBy - function currentClockState - - _...18 more_ + - _...22 more_ - `modules/core/src/main/scala/de/nowchess/chess/exception/ApiException.scala` - class ApiException - class GameNotFoundException - class BadRequestException - `modules/core/src/main/scala/de/nowchess/chess/exception/ApiExceptionMapper.scala` — class ApiExceptionMapper, function toResponse +- `modules/core/src/main/scala/de/nowchess/chess/grpc/CoordinatorServiceHandler.scala` — class CoordinatorServiceHandler +- `modules/core/src/main/scala/de/nowchess/chess/grpc/CoreProtoMapper.scala` + - class CoreProtoMapper + - function toProtoColor + - function fromProtoColor + - function toProtoPieceType + - function fromProtoPieceType + - function toProtoMoveKind + - _...9 more_ +- `modules/core/src/main/scala/de/nowchess/chess/grpc/IoGrpcClientWrapper.scala` + - class IoGrpcClientWrapper + - function exportCombined + - function importFen + - function importPgn + - function exportFen + - function exportPgn +- `modules/core/src/main/scala/de/nowchess/chess/grpc/RuleSetGrpcAdapter.scala` + - class RuleSetGrpcAdapter + - function candidateMoves + - function legalMoves + - function allLegalMoves + - function isCheck + - function isCheckmate + - _...5 more_ - `modules/core/src/main/scala/de/nowchess/chess/observer/Observer.scala` - function context - class Observer @@ -467,18 +385,36 @@ - function subscribe - function unsubscribe - _...1 more_ +- `modules/core/src/main/scala/de/nowchess/chess/redis/C2sMessage.scala` — class C2sMessage +- `modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisPublisher.scala` — class GameRedisPublisher, function onGameEvent +- `modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisSubscriberManager.scala` + - class GameRedisSubscriberManager + - function subscribeGame + - function onMessage + - function unsubscribeGame + - function batchResubscribeGames + - function unsubscribeGames + - _...3 more_ - `modules/core/src/main/scala/de/nowchess/chess/registry/GameRegistry.scala` - class GameRegistry - function store - function get - function update - function generateId -- `modules/core/src/main/scala/de/nowchess/chess/registry/GameRegistryImpl.scala` - - class GameRegistryImpl +- `modules/core/src/main/scala/de/nowchess/chess/registry/RedisGameRegistry.scala` + - class RedisGameRegistry + - function generateId - function store - function get - function update - - function generateId +- `modules/core/src/main/scala/de/nowchess/chess/resource/GameDtoMapper.scala` + - class GameDtoMapper + - function statusOf + - function moveToUci + - function toPlayerDto + - function toClockDto + - function toGameStateDto + - _...1 more_ - `modules/core/src/main/scala/de/nowchess/chess/resource/GameResource.scala` - class GameResource - function onGameEvent @@ -486,54 +422,15 @@ - function getGame - function resignGame - function makeMove - - _...8 more_ -- `modules/core/src/main/scala/de/nowchess/chess/resource/GameWebSocketResource.scala` - - class GameWebSocketResource - - function onOpen - - function onGameEvent - - function onClose -- `modules/io/bin/scoverage/de/nowchess/io/GameContextExport.scala` — class GameContextExport, function exportGameContext -- `modules/io/bin/scoverage/de/nowchess/io/GameContextImport.scala` — class GameContextImport, function importGameContext -- `modules/io/bin/scoverage/de/nowchess/io/GameFileService.scala` - - class GameFileService - - function saveGameToFile - - function loadGameFromFile - - class FileSystemGameService - - function saveGameToFile - - function loadGameFromFile -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenExporter.scala` - - class FenExporter - - function boardToFen - - function gameContextToFen - - function exportGameContext -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenParser.scala` - - class FenParser - - function parseFen - - function importGameContext - - function parseBoard -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenParserCombinators.scala` - - class FenParserCombinators - - function parseFen - - function parseBoard - - function importGameContext -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenParserFastParse.scala` - - class FenParserFastParse - - function parseFen - - function parseBoard - - function importGameContext -- `modules/io/bin/scoverage/de/nowchess/io/fen/FenParserSupport.scala` — function buildSquares -- `modules/io/bin/scoverage/de/nowchess/io/json/JsonExporter.scala` — class JsonExporter, function exportGameContext -- `modules/io/bin/scoverage/de/nowchess/io/json/JsonParser.scala` — class JsonParser, function importGameContext -- `modules/io/bin/scoverage/de/nowchess/io/pgn/PgnExporter.scala` - - class PgnExporter - - function exportGameContext - - function exportGame -- `modules/io/bin/scoverage/de/nowchess/io/pgn/PgnParser.scala` - - class PgnParser - - function validatePgn - - function importGameContext - - function parsePgn - - function parseAlgebraicMove + - _...9 more_ +- `modules/core/src/main/scala/de/nowchess/chess/service/InstanceHeartbeatService.scala` + - class InstanceHeartbeatService + - function onStart + - function onShutdown + - function setRedisPrefix + - function setSubscriptionCount + - function setLocalCacheSize + - _...2 more_ - `modules/io/src/main/scala/de/nowchess/io/GameFileService.scala` - class GameFileService - function saveGameToFile @@ -562,6 +459,15 @@ - function parseBoard - function importGameContext - `modules/io/src/main/scala/de/nowchess/io/fen/FenParserSupport.scala` — function buildSquares +- `modules/io/src/main/scala/de/nowchess/io/grpc/IoGrpcService.scala` — class IoGrpcService +- `modules/io/src/main/scala/de/nowchess/io/grpc/IoProtoMapper.scala` + - class IoProtoMapper + - function toProtoColor + - function fromProtoColor + - function toProtoPieceType + - function fromProtoPieceType + - function toProtoMoveKind + - _...9 more_ - `modules/io/src/main/scala/de/nowchess/io/json/JsonExporter.scala` — class JsonExporter, function exportGameContext - `modules/io/src/main/scala/de/nowchess/io/json/JsonParser.scala` — class JsonParser, function importGameContext - `modules/io/src/main/scala/de/nowchess/io/pgn/PgnExporter.scala` @@ -582,6 +488,7 @@ - function importPgn - function exportFen - function exportPgn + - function exportCombined - `modules/json/src/main/scala/de/nowchess/json/ChessJacksonModule.scala` — class ChessJacksonModule - `modules/json/src/main/scala/de/nowchess/json/GameResultDeserializer.scala` — class GameResultDeserializer - `modules/json/src/main/scala/de/nowchess/json/GameResultSerializer.scala` — class GameResultSerializer @@ -591,22 +498,17 @@ - `modules/json/src/main/scala/de/nowchess/json/SquareKeyDeserializer.scala` — class SquareKeyDeserializer - `modules/json/src/main/scala/de/nowchess/json/SquareKeySerializer.scala` — class SquareKeySerializer - `modules/json/src/main/scala/de/nowchess/json/SquareSerializer.scala` — class SquareSerializer -- `modules/rule/bin/scoverage/de/nowchess/rules/RuleSet.scala` - - class RuleSet - - function candidateMoves - - function legalMoves - - function allLegalMoves - - function isCheck - - function isCheckmate - - _...5 more_ -- `modules/rule/bin/scoverage/de/nowchess/rules/sets/DefaultRules.scala` - - class DefaultRules - - function positionOf - - function loop - - function toMoves - - function loop - `modules/rule/src/main/scala/de/nowchess/rules/config/JacksonConfig.scala` — class JacksonConfig, function customize - `modules/rule/src/main/scala/de/nowchess/rules/config/NativeReflectionConfig.scala` — class NativeReflectionConfig +- `modules/rule/src/main/scala/de/nowchess/rules/grpc/ProtoMapper.scala` + - class ProtoMapper + - function toProtoColor + - function fromProtoColor + - function toProtoPieceType + - function fromProtoPieceType + - function toProtoMoveKind + - _...9 more_ +- `modules/rule/src/main/scala/de/nowchess/rules/grpc/RuleGrpcService.scala` — class RuleGrpcService - `modules/rule/src/main/scala/de/nowchess/rules/resource/RuleSetResource.scala` - class RuleSetResource - function candidateMoves @@ -614,5 +516,33 @@ - function allLegalMoves - function isCheck - function isCheckmate - - _...5 more_ + - _...6 more_ - `modules/rule/src/main/scala/de/nowchess/rules/sets/DefaultRules.scala` — class DefaultRules, function positionOf +- `modules/store/src/main/scala/de/nowchess/store/config/RedisConfig.scala` — class RedisConfig +- `modules/store/src/main/scala/de/nowchess/store/config/RedissonProducer.scala` + - class RedissonProducer + - function redissonClient + - function close +- `modules/store/src/main/scala/de/nowchess/store/domain/GameRecord.scala` — class GameRecord +- `modules/store/src/main/scala/de/nowchess/store/redis/GameWritebackStreamListener.scala` + - class GameWritebackStreamListener + - function startListening + - function onMessage +- `modules/store/src/main/scala/de/nowchess/store/repository/GameRecordRepository.scala` + - class GameRecordRepository + - function findByGameId + - function persist + - function merge +- `modules/store/src/main/scala/de/nowchess/store/resource/StoreGameResource.scala` — class StoreGameResource, function getGame +- `modules/store/src/main/scala/de/nowchess/store/service/GameWritebackService.scala` — class GameWritebackService, function writeBack +- `modules/ws/src/main/scala/de/nowchess/ws/config/RedisConfig.scala` — class RedisConfig +- `modules/ws/src/main/scala/de/nowchess/ws/config/RedissonProducer.scala` + - class RedissonProducer + - function produceRedissonClient + - function shutdown +- `modules/ws/src/main/scala/de/nowchess/ws/resource/GameWebSocketResource.scala` + - class GameWebSocketResource + - function onOpen + - function onMessage + - function onTextMessage + - function onClose diff --git a/.codesight/routes.md b/.codesight/routes.md new file mode 100644 index 0000000..cd5f7e4 --- /dev/null +++ b/.codesight/routes.md @@ -0,0 +1,44 @@ +# Routes + +## gRPC + +- `/CoordinatorService/BatchResubscribeGames` (BatchResubscribeRequest) → BatchResubscribeResponse +- `/CoordinatorService/UnsubscribeGames` (UnsubscribeGamesRequest) → UnsubscribeGamesResponse +- `/CoordinatorService/EvictGames` (EvictGamesRequest) → EvictGamesResponse +- `/CoordinatorService/DrainInstance` (DrainInstanceRequest) → DrainInstanceResponse +- `/CoordinatorService/BatchResubscribeGames` (BatchResubscribeRequest) → BatchResubscribeResponse +- `/CoordinatorService/UnsubscribeGames` (UnsubscribeGamesRequest) → UnsubscribeGamesResponse +- `/CoordinatorService/EvictGames` (EvictGamesRequest) → EvictGamesResponse +- `/CoordinatorService/DrainInstance` (DrainInstanceRequest) → DrainInstanceResponse +- `/IoService/ImportFen` (ProtoImportFenRequest) → ProtoGameContext +- `/IoService/ImportPgn` (ProtoImportPgnRequest) → ProtoGameContext +- `/IoService/ExportCombined` (ProtoGameContext) → ProtoCombinedExport +- `/IoService/ExportFen` (ProtoGameContext) → ProtoStringResult +- `/IoService/ExportPgn` (ProtoGameContext) → ProtoStringResult +- `/RuleService/CandidateMoves` (ProtoSquareRequest) → ProtoMoveList +- `/RuleService/LegalMoves` (ProtoSquareRequest) → ProtoMoveList +- `/RuleService/AllLegalMoves` (ProtoGameContext) → ProtoMoveList +- `/RuleService/IsCheck` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsCheckmate` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsStalemate` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsInsufficientMaterial` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsFiftyMoveRule` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsThreefoldRepetition` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/ApplyMove` (ProtoMoveRequest) → ProtoGameContext +- `/RuleService/PostMoveStatus` (ProtoGameContext) → ProtoPostMoveStatus +- `/IoService/ImportFen` (ProtoImportFenRequest) → ProtoGameContext +- `/IoService/ImportPgn` (ProtoImportPgnRequest) → ProtoGameContext +- `/IoService/ExportCombined` (ProtoGameContext) → ProtoCombinedExport +- `/IoService/ExportFen` (ProtoGameContext) → ProtoStringResult +- `/IoService/ExportPgn` (ProtoGameContext) → ProtoStringResult +- `/RuleService/CandidateMoves` (ProtoSquareRequest) → ProtoMoveList +- `/RuleService/LegalMoves` (ProtoSquareRequest) → ProtoMoveList +- `/RuleService/AllLegalMoves` (ProtoGameContext) → ProtoMoveList +- `/RuleService/IsCheck` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsCheckmate` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsStalemate` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsInsufficientMaterial` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsFiftyMoveRule` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/IsThreefoldRepetition` (ProtoGameContext) → ProtoBoolResult +- `/RuleService/ApplyMove` (ProtoMoveRequest) → ProtoGameContext +- `/RuleService/PostMoveStatus` (ProtoGameContext) → ProtoPostMoveStatus diff --git a/modules/bot/src/main/resources/META-INF.native-image.de.nowchess.bot/reachability-metadata.json b/modules/bot/src/main/resources/META-INF.native-image.de.nowchess.bot/reachability-metadata.json new file mode 100644 index 0000000..7245246 --- /dev/null +++ b/modules/bot/src/main/resources/META-INF.native-image.de.nowchess.bot/reachability-metadata.json @@ -0,0 +1,27 @@ +{ + "reflection": [ + { "type": "scala.Tuple1[]" }, + { "type": "scala.Tuple2[]" }, + { "type": "scala.Tuple3[]" }, + { "type": "scala.Tuple4[]" }, + { "type": "scala.Tuple5[]" }, + { "type": "scala.Tuple6[]" }, + { "type": "scala.Tuple7[]" }, + { "type": "scala.Tuple8[]" }, + { "type": "scala.Tuple9[]" }, + { "type": "scala.Tuple10[]" }, + { "type": "scala.Tuple11[]" }, + { "type": "scala.Tuple12[]" }, + { "type": "scala.Tuple13[]" }, + { "type": "scala.Tuple14[]" }, + { "type": "scala.Tuple15[]" }, + { "type": "scala.Tuple16[]" }, + { "type": "scala.Tuple17[]" }, + { "type": "scala.Tuple18[]" }, + { "type": "scala.Tuple19[]" }, + { "type": "scala.Tuple20[]" }, + { "type": "scala.Tuple21[]" }, + { "type": "scala.Tuple22[]" }, + { "type": "com.fasterxml.jackson.module.scala.introspect.PropertyDescriptor[]" } + ] +} diff --git a/modules/coordinator/build.gradle.kts b/modules/coordinator/build.gradle.kts index d765fdb..05d82bb 100644 --- a/modules/coordinator/build.gradle.kts +++ b/modules/coordinator/build.gradle.kts @@ -63,12 +63,15 @@ dependencies { implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")) implementation("io.quarkus:quarkus-rest") + implementation("io.quarkus:quarkus-rest-jackson") implementation("io.quarkus:quarkus-grpc") implementation("io.quarkus:quarkus-arc") implementation("io.quarkus:quarkus-config-yaml") implementation("io.quarkus:quarkus-smallrye-health") + implementation("io.quarkus:quarkus-smallrye-openapi") implementation("io.quarkus:quarkus-rest-client") implementation("io.quarkus:quarkus-rest-client-jackson") + implementation("com.fasterxml.jackson.module:jackson-module-scala_3:${versions["JACKSON_SCALA"]!!}") implementation("org.redisson:redisson:${versions["REDISSON"]!!}") implementation("io.fabric8:kubernetes-client:6.13.0") diff --git a/modules/coordinator/src/main/resources/META-INF.native-image.de.nowchess.coordinator/reachability-metadata.json b/modules/coordinator/src/main/resources/META-INF.native-image.de.nowchess.coordinator/reachability-metadata.json new file mode 100644 index 0000000..7245246 --- /dev/null +++ b/modules/coordinator/src/main/resources/META-INF.native-image.de.nowchess.coordinator/reachability-metadata.json @@ -0,0 +1,27 @@ +{ + "reflection": [ + { "type": "scala.Tuple1[]" }, + { "type": "scala.Tuple2[]" }, + { "type": "scala.Tuple3[]" }, + { "type": "scala.Tuple4[]" }, + { "type": "scala.Tuple5[]" }, + { "type": "scala.Tuple6[]" }, + { "type": "scala.Tuple7[]" }, + { "type": "scala.Tuple8[]" }, + { "type": "scala.Tuple9[]" }, + { "type": "scala.Tuple10[]" }, + { "type": "scala.Tuple11[]" }, + { "type": "scala.Tuple12[]" }, + { "type": "scala.Tuple13[]" }, + { "type": "scala.Tuple14[]" }, + { "type": "scala.Tuple15[]" }, + { "type": "scala.Tuple16[]" }, + { "type": "scala.Tuple17[]" }, + { "type": "scala.Tuple18[]" }, + { "type": "scala.Tuple19[]" }, + { "type": "scala.Tuple20[]" }, + { "type": "scala.Tuple21[]" }, + { "type": "scala.Tuple22[]" }, + { "type": "com.fasterxml.jackson.module.scala.introspect.PropertyDescriptor[]" } + ] +} diff --git a/modules/coordinator/src/main/resources/application.yml b/modules/coordinator/src/main/resources/application.yml index c07cdc0..0880dcb 100644 --- a/modules/coordinator/src/main/resources/application.yml +++ b/modules/coordinator/src/main/resources/application.yml @@ -1,10 +1,22 @@ quarkus: - application.name: nowchess-coordinator - http.port: 8086 - grpc.server.port: 9086 - config.yaml.enabled: true - rest-client.connection-timeout: 5000 - rest-client.read-timeout: 10000 + application: + name: nowchess-coordinator + http: + port: 8086 + grpc: + server: + port: 9086 + rest-client: + connection-timeout: 5000 + read-timeout: 10000 + smallrye-openapi: + info-title: NowChess Coordinator Service + info-version: 1.0.0 + info-description: Coordination endpoints for instance health, balancing, failover, and scaling + path: /openapi + swagger-ui: + always-include: true + path: /swagger-ui nowchess: redis: @@ -18,7 +30,7 @@ nowchess: rebalance-interval: 30s rebalance-min-interval: 60s heartbeat-ttl: 5s - stream-heartbeat-interval: 200ms + stream-heartbeat-interval: PT0.2S cache-eviction-interval: 10m game-idle-threshold: 45m auto-scale-enabled: false @@ -34,6 +46,5 @@ nowchess: # dev profile "%dev": quarkus: - log.level: DEBUG - log.category: - "de.nowchess": DEBUG + log: + level: DEBUG diff --git a/modules/coordinator/src/main/scala/de/nowchess/coordinator/config/CoordinatorConfig.scala b/modules/coordinator/src/main/scala/de/nowchess/coordinator/config/CoordinatorConfig.scala index 45fdd92..cff6e41 100644 --- a/modules/coordinator/src/main/scala/de/nowchess/coordinator/config/CoordinatorConfig.scala +++ b/modules/coordinator/src/main/scala/de/nowchess/coordinator/config/CoordinatorConfig.scala @@ -5,51 +5,51 @@ import io.smallrye.config.WithName import java.time.Duration @ConfigMapping(prefix = "nowchess.coordinator") -class CoordinatorConfig: +trait CoordinatorConfig: @WithName("max-games-per-core") - def maxGamesPerCore: Int = ??? + def maxGamesPerCore: Int @WithName("max-deviation-percent") - def maxDeviationPercent: Int = ??? + def maxDeviationPercent: Int @WithName("rebalance-interval") - def rebalanceInterval: Duration = ??? + def rebalanceInterval: Duration @WithName("rebalance-min-interval") - def rebalanceMinInterval: Duration = ??? + def rebalanceMinInterval: Duration @WithName("heartbeat-ttl") - def heartbeatTtl: Duration = ??? + def heartbeatTtl: Duration @WithName("stream-heartbeat-interval") - def streamHeartbeatInterval: Duration = ??? + def streamHeartbeatInterval: Duration @WithName("cache-eviction-interval") - def cacheEvictionInterval: Duration = ??? + def cacheEvictionInterval: Duration @WithName("game-idle-threshold") - def gameIdleThreshold: Duration = ??? + def gameIdleThreshold: Duration @WithName("auto-scale-enabled") - def autoScaleEnabled: Boolean = ??? + def autoScaleEnabled: Boolean @WithName("scale-up-threshold") - def scaleUpThreshold: Double = ??? + def scaleUpThreshold: Double @WithName("scale-down-threshold") - def scaleDownThreshold: Double = ??? + def scaleDownThreshold: Double @WithName("scale-min-replicas") - def scaleMinReplicas: Int = ??? + def scaleMinReplicas: Int @WithName("scale-max-replicas") - def scaleMaxReplicas: Int = ??? + def scaleMaxReplicas: Int @WithName("k8s-namespace") - def k8sNamespace: String = ??? + def k8sNamespace: String @WithName("k8s-rollout-name") - def k8sRolloutName: String = ??? + def k8sRolloutName: String @WithName("k8s-rollout-label-selector") - def k8sRolloutLabelSelector: String = ??? + def k8sRolloutLabelSelector: String diff --git a/modules/coordinator/src/main/scala/de/nowchess/coordinator/config/JacksonConfig.scala b/modules/coordinator/src/main/scala/de/nowchess/coordinator/config/JacksonConfig.scala new file mode 100644 index 0000000..8abeeed --- /dev/null +++ b/modules/coordinator/src/main/scala/de/nowchess/coordinator/config/JacksonConfig.scala @@ -0,0 +1,18 @@ +package de.nowchess.coordinator.config + +import com.fasterxml.jackson.core.Version +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.scala.DefaultScalaModule +import io.quarkus.jackson.ObjectMapperCustomizer +import jakarta.inject.Singleton + +@Singleton +class JacksonConfig extends ObjectMapperCustomizer: + def customize(mapper: ObjectMapper): Unit = + mapper.registerModule(new DefaultScalaModule() { + override def version(): Version = + // scalafix:off DisableSyntax.null + new Version(2, 21, 1, null, "com.fasterxml.jackson.module", "jackson-module-scala") + // scalafix:on DisableSyntax.null + }) + diff --git a/modules/coordinator/src/main/scala/de/nowchess/coordinator/config/NativeReflectionConfig.scala b/modules/coordinator/src/main/scala/de/nowchess/coordinator/config/NativeReflectionConfig.scala new file mode 100644 index 0000000..2e6d6da --- /dev/null +++ b/modules/coordinator/src/main/scala/de/nowchess/coordinator/config/NativeReflectionConfig.scala @@ -0,0 +1,14 @@ +package de.nowchess.coordinator.config + +import de.nowchess.coordinator.dto.InstanceMetadata +import de.nowchess.coordinator.resource.MetricsDto +import io.quarkus.runtime.annotations.RegisterForReflection + +@RegisterForReflection( + targets = Array( + classOf[InstanceMetadata], + classOf[MetricsDto], + ), +) +class NativeReflectionConfig + diff --git a/modules/core/src/main/resources/application.yml b/modules/core/src/main/resources/application.yml index 31a2130..75ada85 100644 --- a/modules/core/src/main/resources/application.yml +++ b/modules/core/src/main/resources/application.yml @@ -24,6 +24,7 @@ nowchess: prefix: nowchess coordinator: + enabled: ${NOWCHESS_COORDINATOR_ENABLED:false} host: localhost grpc-port: 9086 stream-heartbeat-interval: 200ms @@ -99,6 +100,7 @@ nowchess: prefix: ${REDIS_PREFIX:nowchess} coordinator: + enabled: ${NOWCHESS_COORDINATOR_ENABLED:true} host: ${COORDINATOR_SERVICE_HOST:localhost} grpc-port: ${COORDINATOR_SERVICE_GRPC_PORT:9086} stream-heartbeat-interval: 200ms diff --git a/modules/core/src/main/scala/de/nowchess/chess/redis/C2sMessage.scala b/modules/core/src/main/scala/de/nowchess/chess/redis/C2sMessage.scala index af0e0a2..70adcf9 100644 --- a/modules/core/src/main/scala/de/nowchess/chess/redis/C2sMessage.scala +++ b/modules/core/src/main/scala/de/nowchess/chess/redis/C2sMessage.scala @@ -3,6 +3,6 @@ package de.nowchess.chess.redis sealed trait C2sMessage object C2sMessage: - case object Connected extends C2sMessage - case class Move(uci: String) extends C2sMessage - case object Ping extends C2sMessage + case object Connected extends C2sMessage + case class Move(uci: String, playerId: Option[String] = None) extends C2sMessage + case object Ping extends C2sMessage diff --git a/modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisSubscriberManager.scala b/modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisSubscriberManager.scala index cdd1b6d..2b328fe 100644 --- a/modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisSubscriberManager.scala +++ b/modules/core/src/main/scala/de/nowchess/chess/redis/GameRedisSubscriberManager.scala @@ -1,7 +1,9 @@ package de.nowchess.chess.redis import com.fasterxml.jackson.databind.ObjectMapper +import de.nowchess.api.board.Color import de.nowchess.api.dto.GameFullEventDto +import de.nowchess.api.game.GameMode import de.nowchess.chess.config.RedisConfig import de.nowchess.chess.grpc.IoGrpcClientWrapper import de.nowchess.chess.observer.Observer @@ -82,10 +84,10 @@ class GameRedisSubscriberManager: private def handleC2sMessage(gameId: String, msg: String): Unit = parseC2sMessage(msg) match - case Some(C2sMessage.Connected) => handleConnected(gameId) - case Some(C2sMessage.Move(uci)) => handleMove(gameId, uci) - case Some(C2sMessage.Ping) => () - case None => () + case Some(C2sMessage.Connected) => handleConnected(gameId) + case Some(C2sMessage.Move(uci, playerId)) => handleMove(gameId, uci, playerId) + case Some(C2sMessage.Ping) => () + case None => () private def handleConnected(gameId: String): Unit = registry.get(gameId).foreach { entry => @@ -94,16 +96,30 @@ class GameRedisSubscriberManager: redisson.getTopic(s2cTopicName(gameId)).publish(json) } - private def handleMove(gameId: String, uci: String): Unit = + private def handleMove(gameId: String, uci: String, playerId: Option[String]): Unit = registry.get(gameId).foreach { entry => - entry.engine.processUserInput(uci) + entry.mode match + case GameMode.Open => entry.engine.processUserInput(uci) + case GameMode.Authenticated => + playerId match + case None => () + case Some(pid) => + val turn = entry.engine.context.turn + val authorised = + (entry.white.id.value == pid && turn == Color.White) || + (entry.black.id.value == pid && turn == Color.Black) + if authorised then entry.engine.processUserInput(uci) } private def parseC2sMessage(msg: String): Option[C2sMessage] = Try(objectMapper.readTree(msg)).toOption.flatMap { node => Option(node.get("type")).map(_.asText()).flatMap { case "CONNECTED" => Some(C2sMessage.Connected) - case "MOVE" => Option(node.get("uci")).map(u => C2sMessage.Move(u.asText())) + case "MOVE" => + Option(node.get("uci")).map { u => + val pid = Option(node.get("playerId")).map(_.asText()).filter(_.nonEmpty) + C2sMessage.Move(u.asText(), pid) + } case "PING" => Some(C2sMessage.Ping) case _ => None } diff --git a/modules/core/src/main/scala/de/nowchess/chess/service/InstanceHeartbeatService.scala b/modules/core/src/main/scala/de/nowchess/chess/service/InstanceHeartbeatService.scala index dfb5bd0..ea851eb 100644 --- a/modules/core/src/main/scala/de/nowchess/chess/service/InstanceHeartbeatService.scala +++ b/modules/core/src/main/scala/de/nowchess/chess/service/InstanceHeartbeatService.scala @@ -33,6 +33,9 @@ class InstanceHeartbeatService: @ConfigProperty(name = "quarkus.grpc.server.port", defaultValue = "9000") private var grpcPort: Int = 0 + @ConfigProperty(name = "nowchess.coordinator.enabled", defaultValue = "true") + private var coordinatorEnabled: Boolean = true + private var coordinatorStub: CoordinatorServiceStub = uninitialized private val log = Logger.getLogger(classOf[InstanceHeartbeatService]) @@ -45,20 +48,36 @@ class InstanceHeartbeatService: private var redisHeartbeatExecutor = Executors.newScheduledThreadPool(1) private var subscriptionCount = 0 private var localCacheSize = 0 + private var serviceActive = false + private var shuttingDown = false def onStart(@Observes event: StartupEvent): Unit = + if !coordinatorEnabled then + log.info("Coordinator support disabled via config; skipping heartbeat service startup") + return + try + shuttingDown = false generateInstanceId() initializeHeartbeatStream() scheduleHeartbeats() + serviceActive = true log.infof("Instance heartbeat service started with ID: %s", instanceId) catch case ex: Exception => + serviceActive = false log.errorf(ex, "Failed to start instance heartbeat service") def onShutdown(@Observes event: ShutdownEvent): Unit = + shuttingDown = true + + if !serviceActive then + log.info("Instance heartbeat service stopped") + return + try cleanup() + serviceActive = false log.info("Instance heartbeat service stopped") catch case ex: Exception => @@ -74,12 +93,16 @@ class InstanceHeartbeatService: localCacheSize = count def addGameSubscription(gameId: String): Unit = + if !coordinatorEnabled then return + val setKey = s"$redisPrefix:instance:$instanceId:games" val gameSet = redissonClient.getSet[String](setKey) gameSet.add(gameId) subscriptionCount += 1 def removeGameSubscription(gameId: String): Unit = + if !coordinatorEnabled then return + val setKey = s"$redisPrefix:instance:$instanceId:games" val gameSet = redissonClient.getSet[String](setKey) gameSet.remove(gameId) @@ -103,7 +126,8 @@ class InstanceHeartbeatService: override def onError(t: Throwable): Unit = log.warnf(t, "Heartbeat stream error") streamObserver = None - heartbeatExecutor.schedule((() => initializeHeartbeatStream()): Runnable, 5, TimeUnit.SECONDS) + if !shuttingDown then + heartbeatExecutor.schedule((() => initializeHeartbeatStream()): Runnable, 5, TimeUnit.SECONDS) override def onCompleted: Unit = log.info("Heartbeat stream completed") @@ -182,11 +206,12 @@ class InstanceHeartbeatService: streamObserver.foreach(_.onCompleted()) streamObserver = None - val key = s"$redisPrefix:instances:$instanceId" - redissonClient.getBucket[String](key).delete() + if instanceId.nonEmpty then + val key = s"$redisPrefix:instances:$instanceId" + redissonClient.getBucket[String](key).delete() - val setKey = s"$redisPrefix:instance:$instanceId:games" - redissonClient.getSet[String](setKey).delete() + val setKey = s"$redisPrefix:instance:$instanceId:games" + redissonClient.getSet[String](setKey).delete() heartbeatExecutor.shutdown() redisHeartbeatExecutor.shutdown() diff --git a/modules/core/src/test/resources/application.yml b/modules/core/src/test/resources/application.yml index 08040c7..1fdafa6 100644 --- a/modules/core/src/test/resources/application.yml +++ b/modules/core/src/test/resources/application.yml @@ -12,6 +12,8 @@ quarkus: url: http://localhost:8085 nowchess: + coordinator: + enabled: false redis: host: localhost port: 6379 diff --git a/modules/core/src/test/scala/de/nowchess/chess/config/MockRedissonProducer.scala b/modules/core/src/test/scala/de/nowchess/chess/config/MockRedissonProducer.scala new file mode 100644 index 0000000..7ba923d --- /dev/null +++ b/modules/core/src/test/scala/de/nowchess/chess/config/MockRedissonProducer.scala @@ -0,0 +1,17 @@ +package de.nowchess.chess.config + +import jakarta.annotation.Priority +import jakarta.enterprise.context.ApplicationScoped +import jakarta.enterprise.inject.Alternative +import jakarta.enterprise.inject.Produces +import org.mockito.Mockito +import org.redisson.api.RedissonClient + +@Alternative +@Priority(1) +@ApplicationScoped +class MockRedissonProducer: + @Produces + @ApplicationScoped + def produceRedissonClient(): RedissonClient = + Mockito.mock(classOf[RedissonClient], Mockito.RETURNS_DEEP_STUBS) diff --git a/modules/store/src/main/resources/META-INF.native-image.de.nowchess.store/reachability-metadata.json b/modules/store/src/main/resources/META-INF.native-image.de.nowchess.store/reachability-metadata.json new file mode 100644 index 0000000..7245246 --- /dev/null +++ b/modules/store/src/main/resources/META-INF.native-image.de.nowchess.store/reachability-metadata.json @@ -0,0 +1,27 @@ +{ + "reflection": [ + { "type": "scala.Tuple1[]" }, + { "type": "scala.Tuple2[]" }, + { "type": "scala.Tuple3[]" }, + { "type": "scala.Tuple4[]" }, + { "type": "scala.Tuple5[]" }, + { "type": "scala.Tuple6[]" }, + { "type": "scala.Tuple7[]" }, + { "type": "scala.Tuple8[]" }, + { "type": "scala.Tuple9[]" }, + { "type": "scala.Tuple10[]" }, + { "type": "scala.Tuple11[]" }, + { "type": "scala.Tuple12[]" }, + { "type": "scala.Tuple13[]" }, + { "type": "scala.Tuple14[]" }, + { "type": "scala.Tuple15[]" }, + { "type": "scala.Tuple16[]" }, + { "type": "scala.Tuple17[]" }, + { "type": "scala.Tuple18[]" }, + { "type": "scala.Tuple19[]" }, + { "type": "scala.Tuple20[]" }, + { "type": "scala.Tuple21[]" }, + { "type": "scala.Tuple22[]" }, + { "type": "com.fasterxml.jackson.module.scala.introspect.PropertyDescriptor[]" } + ] +} diff --git a/modules/store/src/main/scala/de/nowchess/store/config/JacksonConfig.scala b/modules/store/src/main/scala/de/nowchess/store/config/JacksonConfig.scala new file mode 100644 index 0000000..c6c5c16 --- /dev/null +++ b/modules/store/src/main/scala/de/nowchess/store/config/JacksonConfig.scala @@ -0,0 +1,18 @@ +package de.nowchess.store.config + +import com.fasterxml.jackson.core.Version +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.scala.DefaultScalaModule +import io.quarkus.jackson.ObjectMapperCustomizer +import jakarta.inject.Singleton + +@Singleton +class JacksonConfig extends ObjectMapperCustomizer: + def customize(mapper: ObjectMapper): Unit = + mapper.registerModule(new DefaultScalaModule() { + override def version(): Version = + // scalafix:off DisableSyntax.null + new Version(2, 21, 1, null, "com.fasterxml.jackson.module", "jackson-module-scala") + // scalafix:on DisableSyntax.null + }) + diff --git a/modules/store/src/main/scala/de/nowchess/store/config/NativeReflectionConfig.scala b/modules/store/src/main/scala/de/nowchess/store/config/NativeReflectionConfig.scala new file mode 100644 index 0000000..6e552a0 --- /dev/null +++ b/modules/store/src/main/scala/de/nowchess/store/config/NativeReflectionConfig.scala @@ -0,0 +1,14 @@ +package de.nowchess.store.config + +import de.nowchess.store.domain.GameRecord +import de.nowchess.store.redis.GameWritebackEventDto +import io.quarkus.runtime.annotations.RegisterForReflection + +@RegisterForReflection( + targets = Array( + classOf[GameRecord], + classOf[GameWritebackEventDto], + ), +) +class NativeReflectionConfig + diff --git a/modules/ws/build.gradle.kts b/modules/ws/build.gradle.kts index d072f4f..05992e6 100644 --- a/modules/ws/build.gradle.kts +++ b/modules/ws/build.gradle.kts @@ -48,9 +48,12 @@ dependencies { implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")) implementation("io.quarkus:quarkus-websockets-next") + implementation("io.quarkus:quarkus-jackson") implementation("io.quarkus:quarkus-arc") + implementation("io.quarkus:quarkus-smallrye-jwt") implementation("io.quarkus:quarkus-config-yaml") implementation("io.quarkus:quarkus-smallrye-health") + implementation("com.fasterxml.jackson.module:jackson-module-scala_3:${versions["JACKSON_SCALA"]!!}") implementation("org.redisson:redisson:${versions["REDISSON"]!!}") testImplementation(platform("org.junit:junit-bom:${versions["JUNIT_BOM"]!!}")) diff --git a/modules/ws/src/main/resources/application.yml b/modules/ws/src/main/resources/application.yml index ebafb69..5710691 100644 --- a/modules/ws/src/main/resources/application.yml +++ b/modules/ws/src/main/resources/application.yml @@ -3,6 +3,9 @@ quarkus: port: 8084 application: name: nowchess-ws + swagger-ui: + always-include: true + path: /swagger-ui grpc: server: use-separate-server: false @@ -19,6 +22,12 @@ nowchess: host: localhost port: 6379 prefix: nowchess + mp: + jwt: + verify: + publickey: + location: keys/public.pem + issuer: nowchess "%deployed": nowchess: @@ -26,3 +35,9 @@ nowchess: host: ${REDIS_HOST} port: ${REDIS_PORT:6379} prefix: ${REDIS_PREFIX:nowchess} + mp: + jwt: + verify: + publickey: + location: ${JWT_PUBLIC_KEY_PATH:keys/public.pem} + issuer: nowchess diff --git a/modules/ws/src/main/resources/keys/public.pem b/modules/ws/src/main/resources/keys/public.pem new file mode 100644 index 0000000..6b6b842 --- /dev/null +++ b/modules/ws/src/main/resources/keys/public.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxDsnsCAl0vQx7Vu9CLDZ +g0SG05NgUzu9T+3DTEaHGq60T2uriO8BenwyvsF3BnDqTbKf4voohZ1DNfzdbT1J +Fj8B62FrDmxcO+sp1/b5HUCJP6y2uSRCmzOHe5k7Pk1IEi72FgBpKXSRkFibRlVf +634g7mgsPZAQ9PJEsv4Qvm05T9L6+Gmq6N3bMVLKRXs4RhDhaFbYH9GtUg1eI0yH +YjGyRfqzW/nqVMstOLHt8CuPouq4p7eMzeDH3YHkxPm4GG5foCXMOd2DZrW0SCcr +7dhFeNVWzQ2m53eOhBzNQX+v3pgjVStsePhBRt2LyGfwkNzmqDgqWsMzSHRMY+cn +WQIDAQAB +-----END PUBLIC KEY----- diff --git a/modules/ws/src/main/scala/de/nowchess/ws/config/JacksonConfig.scala b/modules/ws/src/main/scala/de/nowchess/ws/config/JacksonConfig.scala new file mode 100644 index 0000000..eee4318 --- /dev/null +++ b/modules/ws/src/main/scala/de/nowchess/ws/config/JacksonConfig.scala @@ -0,0 +1,18 @@ +package de.nowchess.ws.config + +import com.fasterxml.jackson.core.Version +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.scala.DefaultScalaModule +import io.quarkus.jackson.ObjectMapperCustomizer +import jakarta.inject.Singleton + +@Singleton +class JacksonConfig extends ObjectMapperCustomizer: + def customize(mapper: ObjectMapper): Unit = + mapper.registerModule(new DefaultScalaModule() { + override def version(): Version = + // scalafix:off DisableSyntax.null + new Version(2, 21, 1, null, "com.fasterxml.jackson.module", "jackson-module-scala") + // scalafix:on DisableSyntax.null + }) + diff --git a/modules/ws/src/main/scala/de/nowchess/ws/config/NativeReflectionConfig.scala b/modules/ws/src/main/scala/de/nowchess/ws/config/NativeReflectionConfig.scala new file mode 100644 index 0000000..31285dd --- /dev/null +++ b/modules/ws/src/main/scala/de/nowchess/ws/config/NativeReflectionConfig.scala @@ -0,0 +1,12 @@ +package de.nowchess.ws.config + +import de.nowchess.ws.resource.ConnectionMeta +import io.quarkus.runtime.annotations.RegisterForReflection + +@RegisterForReflection( + targets = Array( + classOf[ConnectionMeta], + ), +) +class NativeReflectionConfig + diff --git a/modules/ws/src/main/scala/de/nowchess/ws/resource/ConnectionMeta.scala b/modules/ws/src/main/scala/de/nowchess/ws/resource/ConnectionMeta.scala new file mode 100644 index 0000000..af1043d --- /dev/null +++ b/modules/ws/src/main/scala/de/nowchess/ws/resource/ConnectionMeta.scala @@ -0,0 +1,7 @@ +package de.nowchess.ws.resource + +final case class ConnectionMeta( + gameId: String, + listenerId: Int, + playerId: Option[String], +) diff --git a/modules/ws/src/main/scala/de/nowchess/ws/resource/GameWebSocketResource.scala b/modules/ws/src/main/scala/de/nowchess/ws/resource/GameWebSocketResource.scala index 6e944e2..6d84874 100644 --- a/modules/ws/src/main/scala/de/nowchess/ws/resource/GameWebSocketResource.scala +++ b/modules/ws/src/main/scala/de/nowchess/ws/resource/GameWebSocketResource.scala @@ -2,10 +2,13 @@ package de.nowchess.ws.resource import de.nowchess.ws.config.RedisConfig import io.quarkus.websockets.next.* +import io.smallrye.jwt.auth.principal.JWTParser import jakarta.inject.Inject import org.redisson.api.listener.MessageListener import org.redisson.api.RedissonClient + import scala.compiletime.uninitialized +import scala.util.Try import java.util.concurrent.ConcurrentHashMap @WebSocket(path = "/api/board/game/{gameId}/ws") @@ -17,9 +20,12 @@ class GameWebSocketResource: @Inject var redisConfig: RedisConfig = uninitialized + + @Inject + var jwtParser: JWTParser = uninitialized // scalafix:on DisableSyntax.var - private val listenerIds = new ConcurrentHashMap[String, (String, Int)]() + private val connections = new ConcurrentHashMap[String, ConnectionMeta]() private def s2cTopic(gameId: String): String = s"${redisConfig.prefix}:game:$gameId:s2c" @@ -28,27 +34,41 @@ class GameWebSocketResource: s"${redisConfig.prefix}:game:$gameId:c2s" @OnOpen - def onOpen(connection: WebSocketConnection): Unit = - val gameId = connection.pathParam("gameId") - val topic = redisson.getTopic(s2cTopic(gameId)) + def onOpen(connection: WebSocketConnection, handshake: HandshakeRequest): Unit = + val gameId = connection.pathParam("gameId") + val playerId = Option(handshake.header("Authorization")) + .filter(_.nonEmpty) + .flatMap(token => Try(jwtParser.parse(token)).toOption) + .map(_.getSubject) + val topic = redisson.getTopic(s2cTopic(gameId)) val listenerId = topic.addListener( classOf[String], new MessageListener[String]: def onMessage(channel: CharSequence, msg: String): Unit = connection.sendText(msg).subscribe().`with`(_ => (), _ => ()), ) - listenerIds.put(connection.id(), (gameId, listenerId)) - val connectedMsg = s"""{"type":"CONNECTED","gameId":"$gameId"}""" + connections.put(connection.id(), ConnectionMeta(gameId, listenerId, playerId)) + val connectedMsg = playerId match + case Some(pid) => s"""{"type":"CONNECTED","gameId":"$gameId","playerId":"$pid"}""" + case None => s"""{"type":"CONNECTED","gameId":"$gameId"}""" redisson.getTopic(c2sTopic(gameId)).publish(connectedMsg) @OnTextMessage def onTextMessage(connection: WebSocketConnection, message: String): Unit = - Option(listenerIds.get(connection.id())).foreach { case (gameId, _) => - redisson.getTopic(c2sTopic(gameId)).publish(message) + Option(connections.get(connection.id())).foreach { meta => + val enriched = meta.playerId match + case Some(pid) => injectPlayerId(message, pid) + case None => message + redisson.getTopic(c2sTopic(meta.gameId)).publish(enriched) } @OnClose def onClose(connection: WebSocketConnection): Unit = - Option(listenerIds.remove(connection.id())).foreach { case (gameId, listenerId) => - redisson.getTopic(s2cTopic(gameId)).removeListener(listenerId) + Option(connections.remove(connection.id())).foreach { meta => + redisson.getTopic(s2cTopic(meta.gameId)).removeListener(meta.listenerId) } + + private def injectPlayerId(msg: String, pid: String): String = + val trimmed = msg.trim + if trimmed.endsWith("}") then trimmed.dropRight(1) + s""","playerId":"$pid"}""" + else msg