From 440bee16fb3b6e1382ff1e36455fb0a82f313dc9 Mon Sep 17 00:00:00 2001 From: SquidSpirit Date: Sat, 12 Jul 2025 18:48:08 +0800 Subject: [PATCH] MCSI-8 feat: implement server properties management with DTO and file storage --- .../gateway/server_properties_dto.dart | 84 +++++++++++++++++++ .../server_properties_file_storage.dart | 5 ++ .../server_properties_repository_impl.dart | 17 ++++ .../server_properties_repository.dart | 5 ++ .../write_server_properties_use_case.dart | 11 +++ .../domain/entity/server_properties.dart | 43 ++++++++++ lib/properties/domain/enum/difficulty.dart | 6 ++ lib/properties/domain/enum/game_mode.dart | 6 ++ .../server_properties_file_storage_impl.dart | 15 ++++ 9 files changed, 192 insertions(+) create mode 100644 lib/properties/adapter/gateway/server_properties_dto.dart create mode 100644 lib/properties/adapter/gateway/server_properties_file_storage.dart create mode 100644 lib/properties/adapter/gateway/server_properties_repository_impl.dart create mode 100644 lib/properties/application/repository/server_properties_repository.dart create mode 100644 lib/properties/application/use_case/write_server_properties_use_case.dart create mode 100644 lib/properties/domain/entity/server_properties.dart create mode 100644 lib/properties/domain/enum/difficulty.dart create mode 100644 lib/properties/domain/enum/game_mode.dart create mode 100644 lib/properties/framework/storage/server_properties_file_storage_impl.dart diff --git a/lib/properties/adapter/gateway/server_properties_dto.dart b/lib/properties/adapter/gateway/server_properties_dto.dart new file mode 100644 index 0000000..aa774bf --- /dev/null +++ b/lib/properties/adapter/gateway/server_properties_dto.dart @@ -0,0 +1,84 @@ +import 'package:minecraft_server_installer/properties/domain/entity/server_properties.dart'; +import 'package:minecraft_server_installer/properties/domain/enum/difficulty.dart'; +import 'package:minecraft_server_installer/properties/domain/enum/game_mode.dart'; + +class ServerPropertiesDto { + final int serverPort; + final int maxPlayers; + final int spawnProtection; + final int viewDistance; + final bool pvp; + final String gameMode; + final String difficulty; + final bool enableCommandBlock; + final bool onlineMode; + final String motd; + + const ServerPropertiesDto({ + required this.serverPort, + required this.maxPlayers, + required this.spawnProtection, + required this.viewDistance, + required this.pvp, + required this.gameMode, + required this.difficulty, + required this.enableCommandBlock, + required this.onlineMode, + required this.motd, + }); + + ServerPropertiesDto.fromEntity(ServerProperties serverProperties) + : serverPort = serverProperties.serverPort, + maxPlayers = serverProperties.maxPlayers, + spawnProtection = serverProperties.spawnProtection, + viewDistance = serverProperties.viewDistance, + pvp = serverProperties.pvp, + gameMode = serverProperties.gameMode.value, + difficulty = serverProperties.difficulty.value, + enableCommandBlock = serverProperties.enableCommandBlock, + onlineMode = serverProperties.onlineMode, + motd = serverProperties.motd; + + Map toStringMap() => { + 'server-port': serverPort.toString(), + 'max-players': maxPlayers.toString(), + 'spawn-protection': spawnProtection.toString(), + 'view-distance': viewDistance.toString(), + 'pvp': pvp.toString(), + 'gamemode': gameMode, + 'difficulty': difficulty, + 'enable-command-block': enableCommandBlock.toString(), + 'online-mode': onlineMode.toString(), + 'motd': motd, + }; +} + +extension _GameModeExtension on GameMode { + String get value { + switch (this) { + case GameMode.survival: + return 'survival'; + case GameMode.creative: + return 'creative'; + case GameMode.adventure: + return 'adventure'; + case GameMode.spectator: + return 'spectator'; + } + } +} + +extension _DifficultyExtension on Difficulty { + String get value { + switch (this) { + case Difficulty.peaceful: + return 'peaceful'; + case Difficulty.easy: + return 'easy'; + case Difficulty.normal: + return 'normal'; + case Difficulty.hard: + return 'hard'; + } + } +} diff --git a/lib/properties/adapter/gateway/server_properties_file_storage.dart b/lib/properties/adapter/gateway/server_properties_file_storage.dart new file mode 100644 index 0000000..4960b70 --- /dev/null +++ b/lib/properties/adapter/gateway/server_properties_file_storage.dart @@ -0,0 +1,5 @@ +import 'package:minecraft_server_installer/properties/adapter/gateway/server_properties_dto.dart'; + +abstract interface class ServerPropertiesFileStorage { + Future writeServerProperties(ServerPropertiesDto serverPropertiesDto, String directoryPath); +} diff --git a/lib/properties/adapter/gateway/server_properties_repository_impl.dart b/lib/properties/adapter/gateway/server_properties_repository_impl.dart new file mode 100644 index 0000000..a300837 --- /dev/null +++ b/lib/properties/adapter/gateway/server_properties_repository_impl.dart @@ -0,0 +1,17 @@ +import 'package:minecraft_server_installer/properties/adapter/gateway/server_properties_dto.dart'; +import 'package:minecraft_server_installer/properties/adapter/gateway/server_properties_file_storage.dart'; +import 'package:minecraft_server_installer/properties/application/repository/server_properties_repository.dart'; +import 'package:minecraft_server_installer/properties/domain/entity/server_properties.dart'; + +class ServerPropertiesRepositoryImpl implements ServerPropertiesRepository { + final ServerPropertiesFileStorage _serverPropertiesFileStorage; + + ServerPropertiesRepositoryImpl(this._serverPropertiesFileStorage); + + @override + Future writeServerProperties(ServerProperties serverProperties, String directoryPath) => + _serverPropertiesFileStorage.writeServerProperties( + ServerPropertiesDto.fromEntity(serverProperties), + directoryPath, + ); +} diff --git a/lib/properties/application/repository/server_properties_repository.dart b/lib/properties/application/repository/server_properties_repository.dart new file mode 100644 index 0000000..77e07cd --- /dev/null +++ b/lib/properties/application/repository/server_properties_repository.dart @@ -0,0 +1,5 @@ +import 'package:minecraft_server_installer/properties/domain/entity/server_properties.dart'; + +abstract interface class ServerPropertiesRepository { + Future writeServerProperties(ServerProperties serverProperties, String directoryPath); +} diff --git a/lib/properties/application/use_case/write_server_properties_use_case.dart b/lib/properties/application/use_case/write_server_properties_use_case.dart new file mode 100644 index 0000000..ed8914c --- /dev/null +++ b/lib/properties/application/use_case/write_server_properties_use_case.dart @@ -0,0 +1,11 @@ +import 'package:minecraft_server_installer/properties/application/repository/server_properties_repository.dart'; +import 'package:minecraft_server_installer/properties/domain/entity/server_properties.dart'; + +class WriteServerPropertiesUseCase { + final ServerPropertiesRepository _serverPropertiesRepository; + + WriteServerPropertiesUseCase(this._serverPropertiesRepository); + + Future call(ServerProperties serverProperties, String directoryPath) => + _serverPropertiesRepository.writeServerProperties(serverProperties, directoryPath); +} diff --git a/lib/properties/domain/entity/server_properties.dart b/lib/properties/domain/entity/server_properties.dart new file mode 100644 index 0000000..e3c4d79 --- /dev/null +++ b/lib/properties/domain/entity/server_properties.dart @@ -0,0 +1,43 @@ +import 'package:equatable/equatable.dart'; +import 'package:minecraft_server_installer/properties/domain/enum/difficulty.dart'; +import 'package:minecraft_server_installer/properties/domain/enum/game_mode.dart'; + +class ServerProperties with EquatableMixin { + final int serverPort; + final int maxPlayers; + final int spawnProtection; + final int viewDistance; + final bool pvp; + final GameMode gameMode; + final Difficulty difficulty; + final bool enableCommandBlock; + final bool onlineMode; + final String motd; + + const ServerProperties({ + required this.serverPort, + required this.maxPlayers, + required this.spawnProtection, + required this.viewDistance, + required this.pvp, + required this.gameMode, + required this.difficulty, + required this.enableCommandBlock, + required this.onlineMode, + required this.motd, + }); + + @override + List get props => [ + serverPort, + maxPlayers, + spawnProtection, + viewDistance, + pvp, + gameMode, + difficulty, + enableCommandBlock, + onlineMode, + motd, + ]; +} diff --git a/lib/properties/domain/enum/difficulty.dart b/lib/properties/domain/enum/difficulty.dart new file mode 100644 index 0000000..3e25f69 --- /dev/null +++ b/lib/properties/domain/enum/difficulty.dart @@ -0,0 +1,6 @@ +enum Difficulty { + peaceful, + easy, + normal, + hard, +} diff --git a/lib/properties/domain/enum/game_mode.dart b/lib/properties/domain/enum/game_mode.dart new file mode 100644 index 0000000..70f5ecb --- /dev/null +++ b/lib/properties/domain/enum/game_mode.dart @@ -0,0 +1,6 @@ +enum GameMode { + survival, + creative, + adventure, + spectator, +} diff --git a/lib/properties/framework/storage/server_properties_file_storage_impl.dart b/lib/properties/framework/storage/server_properties_file_storage_impl.dart new file mode 100644 index 0000000..183db27 --- /dev/null +++ b/lib/properties/framework/storage/server_properties_file_storage_impl.dart @@ -0,0 +1,15 @@ +import 'dart:io'; + +import 'package:minecraft_server_installer/properties/adapter/gateway/server_properties_dto.dart'; +import 'package:minecraft_server_installer/properties/adapter/gateway/server_properties_file_storage.dart'; + +class ServerPropertiesFileStorageImpl implements ServerPropertiesFileStorage { + @override + Future writeServerProperties(ServerPropertiesDto serverPropertiesDto, String directoryPath) async { + File file = File('$directoryPath/server.properties'); + await file.create(recursive: true); + + final propertiesMap = serverPropertiesDto.toStringMap(); + await file.writeAsString(propertiesMap.entries.map((e) => '${e.key}=${e.value}').join('\n')); + } +}