├── .github └── workflows │ └── maven.yml ├── .gitignore ├── LICENSE ├── README.md ├── VERSION ├── bukkit ├── pom.xml └── src │ └── main │ ├── java │ └── ru │ │ └── overwrite │ │ └── protect │ │ └── bukkit │ │ ├── PasswordHandler.java │ │ ├── ServerProtector.java │ │ ├── ServerProtectorManager.java │ │ ├── api │ │ ├── CaptureReason.java │ │ ├── ServerProtectorAPI.java │ │ └── events │ │ │ ├── ServerProtectorCaptureEvent.java │ │ │ ├── ServerProtectorLogoutEvent.java │ │ │ ├── ServerProtectorPasswordEnterEvent.java │ │ │ ├── ServerProtectorPasswordFailEvent.java │ │ │ ├── ServerProtectorPasswordSuccessEvent.java │ │ │ └── ServerProtectorPlayerEvent.java │ │ ├── commands │ │ ├── PasCommand.java │ │ ├── UspCommand.java │ │ └── subcommands │ │ │ ├── AbstractSubCommand.java │ │ │ ├── AddipSubcommand.java │ │ │ ├── AddopSubcommand.java │ │ │ ├── EncryptSubcommand.java │ │ │ ├── LogoutSubcommand.java │ │ │ ├── RebootSubcommand.java │ │ │ ├── ReloadSubcommand.java │ │ │ ├── RemipSubcommand.java │ │ │ ├── RemopSubcommand.java │ │ │ ├── RempassSubcommand.java │ │ │ ├── SetpassSubcommand.java │ │ │ ├── SubCommand.java │ │ │ └── UpdateSubcommand.java │ │ ├── configuration │ │ ├── Config.java │ │ └── data │ │ │ ├── AccessData.java │ │ │ ├── ApiSettings.java │ │ │ ├── BlockingSettings.java │ │ │ ├── BossbarSettings.java │ │ │ ├── Broadcasts.java │ │ │ ├── Commands.java │ │ │ ├── EffectSettings.java │ │ │ ├── EncryptionSettings.java │ │ │ ├── ExcludedPlayers.java │ │ │ ├── GeyserSettings.java │ │ │ ├── LogMessages.java │ │ │ ├── LoggingSettings.java │ │ │ ├── MainSettings.java │ │ │ ├── MessageSettings.java │ │ │ ├── Messages.java │ │ │ ├── PunishSettings.java │ │ │ ├── SecureSettings.java │ │ │ ├── SessionSettings.java │ │ │ ├── SoundSettings.java │ │ │ ├── SystemMessages.java │ │ │ ├── Titles.java │ │ │ └── UspMessages.java │ │ ├── listeners │ │ ├── ChatListener.java │ │ ├── ConnectionListener.java │ │ ├── MainListener.java │ │ └── TabCompleteListener.java │ │ ├── task │ │ ├── BukkitRunner.java │ │ ├── PaperRunner.java │ │ ├── Runner.java │ │ └── TaskManager.java │ │ └── utils │ │ ├── PAPIUtils.java │ │ ├── PluginMessage.java │ │ ├── Utils.java │ │ ├── color │ │ ├── Colorizer.java │ │ ├── LegacyAdvancedColorizer.java │ │ ├── LegacyColorizer.java │ │ ├── MiniMessageColorizer.java │ │ └── VanillaColorizer.java │ │ └── logging │ │ ├── BukkitLogger.java │ │ ├── Logger.java │ │ └── PaperLogger.java │ ├── resources-common │ └── plugin.yml │ ├── resources-en │ ├── config.yml │ ├── data.yml │ └── message.yml │ └── resources-ru │ ├── config.yml │ ├── data.yml │ └── message.yml └── pom.xml /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | build: 10 | 11 | if: "! contains(toJSON(github.event.commits.*.message), '[SKIP-CI]')" 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@main 17 | - name: Set up JDK 21 18 | uses: actions/setup-java@main 19 | with: 20 | distribution: 'temurin' 21 | java-version: '21' 22 | 23 | - uses: actions/cache@main 24 | with: 25 | path: ~/.m2/repository 26 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 27 | restore-keys: | 28 | ${{ runner.os }}-maven- 29 | 30 | - name: Build with Maven | EN 31 | run: mvn -B clean package --file pom.xml 32 | - uses: actions/upload-artifact@main 33 | with: 34 | name: UltimateServerProtect (English) 35 | path: bukkit/target/UltimateServerProtector-*-en.jar 36 | 37 | - name: Build with Maven | RU 38 | run: mvn -B clean package -P ru --file pom.xml 39 | - uses: actions/upload-artifact@main 40 | with: 41 | name: UltimateServerProtect (Russian) 42 | path: bukkit/target/UltimateServerProtector-*-ru.jar -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea/ 3 | .gradle/ 4 | target/ 5 | build 6 | bukkit/build 7 | bukkit/dependency-reduced-pom.xml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UltimateServerProtector [![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/overwrite987/ultimateserverprotector?style=flat-square)](https://www.codefactor.io/repository/github/overwrite987/ultimateserverprotector) 2 | 3 | **• This is an incredibly lightweight plugin, that add an "admin-password" to your server.** 4 | 5 | • The main features should be considered the function of adding rights to check and creating a personal admin password for each player! All together, this creates an almost insurmountable barrier for the "hackers". 6 | 7 | Each admin login attempt can be recorded in logs in a separate file in the plugin folder. Each activation and deactivation of the plugin can also be logged. 8 | You can add a list of admin IP addresses and if someone wants to hack the admin's account, punishment will be applied to him. 9 | It is also possible to add commands that the player can write even before entering the admin password, which is convenient if you use plugins like AuthMe. 10 | It is worth saying that if a player is not recorded in the config, but has admin rights, then with the punish function enabled, you can punish a player who illegally obtained admin permissions as you like. 11 | 12 | • Advantages over others "sequrity plugins" 13 | 1) Plugin regularly checks players for admin's permissions. Not just for OP and not just on join. 14 | 2) Large and fully customizable functionality that is not available in any other plugin 15 | 3) Asynchrony and multithreading, which ensure high performance. Plugin does not load the server at all. 16 | 4) Support for multiple servers 17 | 18 | **• Permissions** 19 |
*serverprotector.protect* - if available, asks the player to enter the admin password. Inserted into the plugin so that you don't have to specify an extra permission in the config. 20 |
*serverprotector.admin* - allows you to use the /usp command and see notifications about successful/failed password entry attempts 21 | 22 | **• Commands** 23 |
/pas - you need to have admin rights or OP to enter it. (you can change this command in the config) 24 |
/usp reload - config reload command 25 |
/usp reboot - plugin restart command 26 | 27 | Admin commands that can be included in the config: 28 |
/usp setpass (nickname) (pass) - add a player and his pass to the config 29 |
/usp addop (nickname) - add a player to the list of operators 30 |
/usp addip (ip) - add IP to adminipwhitelist 31 |
/ultimateserverprotector and /serverprotector - analogs of the /usp command 32 | 33 | **• bStats** 34 |
35 | 36 | **• Downloads** 37 |
**en:** 38 |
**SpigotMc.org** 39 |
**Modrinth.com** 40 |
**ru:** 41 |
**RuBukkit.org** 42 |
**Black-Minecraft.com** 43 | 44 | **• Build** 45 |
Maven required 46 | ```bash 47 | # For English locale 48 | mvn clean package 49 | # For Russian locale 50 | mvn clean package -P ru 51 | ``` 52 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 34.0 -------------------------------------------------------------------------------- /bukkit/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | ru.overwrite.protect 9 | ultimateserverprotector-project 10 | 34.0 11 | 12 | bukkit-plugin 13 | jar 14 | 15 | UltimateServerProtector 16 | UltimateServerProtector Plugin 17 | 18 | 19 | ${project.name}-v${project.version}-${lang} 20 | 21 | 22 | src/main/resources-common 23 | true 24 | 25 | 26 | src/main/resources-${lang} 27 | true 28 | 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-compiler-plugin 34 | 3.13.0 35 | 36 | 17 37 | 17 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-jar-plugin 43 | 3.4.1 44 | 45 | 46 | 47 | mojang 48 | 49 | 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-shade-plugin 55 | 3.5.2 56 | 57 | 58 | 59 | org.bstats 60 | ru.overwrite.protect.bukkit.utils.metrics 61 | 62 | 63 | 64 | 65 | org.bstats:** 66 | 67 | META-INF/*.MF 68 | 69 | 70 | 71 | *:* 72 | 73 | META-INF/maven/ 74 | 75 | 76 | 77 | true 78 | 79 | 80 | 81 | package 82 | 83 | shade 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | io.papermc.paper 94 | paper-api 95 | 1.20.4-R0.1-SNAPSHOT 96 | provided 97 | 98 | 99 | org.bstats 100 | bstats-bukkit 101 | 3.1.0 102 | compile 103 | true 104 | 105 | 106 | me.clip 107 | placeholderapi 108 | 2.11.6 109 | provided 110 | 111 | 112 | org.projectlombok 113 | lombok 114 | RELEASE 115 | true 116 | provided 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/PasswordHandler.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit; 2 | 3 | import lombok.Getter; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.boss.BossBar; 6 | import org.bukkit.entity.Player; 7 | import ru.overwrite.protect.bukkit.api.ServerProtectorAPI; 8 | import ru.overwrite.protect.bukkit.api.events.ServerProtectorPasswordEnterEvent; 9 | import ru.overwrite.protect.bukkit.api.events.ServerProtectorPasswordFailEvent; 10 | import ru.overwrite.protect.bukkit.api.events.ServerProtectorPasswordSuccessEvent; 11 | import ru.overwrite.protect.bukkit.configuration.Config; 12 | import ru.overwrite.protect.bukkit.configuration.data.BlockingSettings; 13 | import ru.overwrite.protect.bukkit.configuration.data.EncryptionSettings; 14 | import ru.overwrite.protect.bukkit.utils.Utils; 15 | 16 | import java.time.LocalDateTime; 17 | import java.util.HashMap; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | public final class PasswordHandler { 22 | 23 | private final ServerProtectorManager plugin; 24 | private final ServerProtectorAPI api; 25 | private final Config pluginConfig; 26 | 27 | @Getter 28 | private final Map attempts = new HashMap<>(); 29 | 30 | @Getter 31 | private final Map bossbars = new HashMap<>(); 32 | 33 | public PasswordHandler(ServerProtectorManager plugin) { 34 | this.plugin = plugin; 35 | this.pluginConfig = plugin.getPluginConfig(); 36 | this.api = plugin.getApi(); 37 | } 38 | 39 | public void checkPassword(Player player, String input, boolean resync) { 40 | Runnable run = () -> { 41 | ServerProtectorPasswordEnterEvent enterEvent = new ServerProtectorPasswordEnterEvent(player, input); 42 | if (pluginConfig.getApiSettings().callEventOnPasswordEnter()) { 43 | enterEvent.callEvent(); 44 | } 45 | if (enterEvent.isCancelled()) { 46 | return; 47 | } 48 | String playerPass = pluginConfig.getPerPlayerPasswords().get(player.getName()); 49 | if (playerPass == null) { 50 | this.failedPassword(player); 51 | return; 52 | } 53 | EncryptionSettings encryptionSettings = pluginConfig.getEncryptionSettings(); 54 | String salt = null; 55 | String pass = encryptionSettings.enableEncryption() 56 | ? Utils.encryptPassword(input, salt = playerPass.split(":")[0], encryptionSettings.encryptMethods()) 57 | : input; 58 | if (pass.equals(playerPass)) { 59 | this.correctPassword(player); 60 | return; 61 | } 62 | if (encryptionSettings.enableEncryption() && !encryptionSettings.oldEncryptMethods().isEmpty()) { 63 | for (List oldEncryptMethod : encryptionSettings.oldEncryptMethods()) { 64 | String oldgenPass = Utils.encryptPassword(input, salt, oldEncryptMethod); 65 | if (oldgenPass.equals(playerPass)) { 66 | this.correctPassword(player); 67 | return; 68 | } 69 | } 70 | } 71 | this.failedPassword(player); 72 | if (pluginConfig.getPunishSettings().enableAttempts() && isAttemptsMax(player.getName())) { 73 | plugin.checkFail(player.getName(), pluginConfig.getCommands().failedPass()); 74 | } 75 | }; 76 | if (resync) { 77 | plugin.getRunner().runPlayer(run, player); 78 | } else { 79 | run.run(); 80 | } 81 | } 82 | 83 | private boolean isAttemptsMax(String playerName) { 84 | int playerAttempts = attempts.getOrDefault(playerName, 0); 85 | return playerAttempts >= pluginConfig.getPunishSettings().maxAttempts(); 86 | } 87 | 88 | public void failedPassword(Player player) { 89 | if (!plugin.isCalledFromAllowedApplication()) { 90 | return; 91 | } 92 | String playerName = player.getName(); 93 | if (pluginConfig.getPunishSettings().enableAttempts()) { 94 | attempts.put(playerName, attempts.getOrDefault(playerName, 0) + 1); 95 | } 96 | ServerProtectorPasswordFailEvent failEvent = new ServerProtectorPasswordFailEvent(player, attempts.get(playerName)); 97 | failEvent.callEvent(); 98 | if (failEvent.isCancelled()) { 99 | return; 100 | } 101 | player.sendMessage(pluginConfig.getMessages().incorrect()); 102 | if (pluginConfig.getMessageSettings().sendTitle()) { 103 | Utils.sendTitleMessage(pluginConfig.getTitles().incorrect(), player); 104 | } 105 | if (pluginConfig.getSoundSettings().enableSounds()) { 106 | Utils.sendSound(pluginConfig.getSoundSettings().onPasFail(), player); 107 | } 108 | if (pluginConfig.getLoggingSettings().loggingPas()) { 109 | plugin.logAction(pluginConfig.getLogMessages().failed(), player, LocalDateTime.now()); 110 | } 111 | if (pluginConfig.getBroadcasts() != null) { 112 | plugin.sendAlert(player, pluginConfig.getBroadcasts().failed()); 113 | } 114 | } 115 | 116 | public void correctPassword(Player player) { 117 | if (!plugin.isCalledFromAllowedApplication()) { 118 | return; 119 | } 120 | ServerProtectorPasswordSuccessEvent successEvent = new ServerProtectorPasswordSuccessEvent(player); 121 | successEvent.callEvent(); 122 | if (successEvent.isCancelled()) { 123 | return; 124 | } 125 | String playerName = player.getName(); 126 | api.uncapturePlayer(playerName); 127 | player.sendMessage(pluginConfig.getMessages().correct()); 128 | if (pluginConfig.getMessageSettings().sendTitle()) { 129 | Utils.sendTitleMessage(pluginConfig.getTitles().correct(), player); 130 | } 131 | plugin.getPerPlayerTime().remove(playerName); 132 | if (pluginConfig.getSoundSettings().enableSounds()) { 133 | Utils.sendSound(pluginConfig.getSoundSettings().onPasCorrect(), player); 134 | } 135 | if (pluginConfig.getEffectSettings().enableEffects()) { 136 | plugin.removeEffects(player); 137 | } 138 | this.showPlayer(player); 139 | api.authorisePlayer(player); 140 | if (pluginConfig.getSessionSettings().sessionTimeEnabled()) { 141 | plugin.getRunner().runDelayedAsync(() -> { 142 | if (!api.isAuthorised(player)) { 143 | api.deauthorisePlayer(player); 144 | } 145 | }, pluginConfig.getSessionSettings().sessionTime() * 20L); 146 | } 147 | if (pluginConfig.getLoggingSettings().loggingPas()) { 148 | plugin.logAction(pluginConfig.getLogMessages().passed(), player, LocalDateTime.now()); 149 | } 150 | BossBar playerBossBar; 151 | if (pluginConfig.getBossbarSettings().enableBossbar() && (playerBossBar = bossbars.get(playerName)) != null) { 152 | playerBossBar.removeAll(); 153 | bossbars.remove(playerName); 154 | } 155 | if (pluginConfig.getBroadcasts() != null) { 156 | plugin.sendAlert(player, pluginConfig.getBroadcasts().passed()); 157 | } 158 | } 159 | 160 | private void showPlayer(Player player) { 161 | BlockingSettings blockingSettings = pluginConfig.getBlockingSettings(); 162 | if (!blockingSettings.hideOnEntering() && !blockingSettings.hideOtherOnEntering()) { 163 | return; 164 | } 165 | for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { 166 | if (blockingSettings.hideOnEntering()) { 167 | onlinePlayer.showPlayer(plugin, player); 168 | } 169 | if (blockingSettings.hideOtherOnEntering()) { 170 | player.showPlayer(plugin, onlinePlayer); 171 | } 172 | } 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/ServerProtector.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit; 2 | 3 | import org.bstats.bukkit.Metrics; 4 | import org.bukkit.configuration.ConfigurationSection; 5 | import org.bukkit.configuration.file.FileConfiguration; 6 | import org.bukkit.entity.Player; 7 | import org.bukkit.plugin.PluginManager; 8 | import org.bukkit.plugin.messaging.Messenger; 9 | 10 | import java.time.LocalDateTime; 11 | 12 | public final class ServerProtector extends ServerProtectorManager { 13 | 14 | @Override 15 | public void onEnable() { 16 | long startTime = System.currentTimeMillis(); 17 | saveDefaultConfig(); 18 | final FileConfiguration config = getConfig(); 19 | final ConfigurationSection mainSettings = config.getConfigurationSection("main-settings"); 20 | setupLogger(config); 21 | setupProxy(config); 22 | loadConfigs(config); 23 | PluginManager pluginManager = server.getPluginManager(); 24 | checkSafe(pluginManager); 25 | checkPaper(); 26 | registerListeners(pluginManager); 27 | registerCommands(pluginManager, mainSettings); 28 | startTasks(config); 29 | logEnableDisable(getPluginConfig().getLogMessages().enabled(), LocalDateTime.now()); 30 | if (mainSettings.getBoolean("enable-metrics", true)) { 31 | new Metrics(this, 13347); 32 | } 33 | checkForUpdates(mainSettings); 34 | long endTime = System.currentTimeMillis(); 35 | getPluginLogger().info("Plugin started in " + (endTime - startTime) + " ms"); 36 | } 37 | 38 | @Override 39 | public void onDisable() { 40 | if (getMessageFile() != null) { 41 | logEnableDisable(getPluginConfig().getLogMessages().disabled(), LocalDateTime.now()); 42 | } 43 | if (getPluginConfig().getMessageSettings().enableBroadcasts()) { 44 | for (Player onlinePlayer : server.getOnlinePlayers()) { 45 | if (onlinePlayer.hasPermission("serverprotector.admin") && getMessageFile() != null) { 46 | onlinePlayer.sendMessage(getPluginConfig().getBroadcasts().disabled()); 47 | } 48 | } 49 | } 50 | getRunner().cancelTasks(); 51 | if (getPluginMessage() != null) { 52 | Messenger messenger = server.getMessenger(); 53 | messenger.unregisterOutgoingPluginChannel(this); 54 | messenger.unregisterIncomingPluginChannel(this); 55 | } 56 | if (getConfig().getBoolean("secure-settings.shutdown-on-disable")) { 57 | server.shutdown(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/ServerProtectorManager.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import org.bukkit.Server; 7 | import org.bukkit.command.CommandMap; 8 | import org.bukkit.command.PluginCommand; 9 | import org.bukkit.configuration.ConfigurationSection; 10 | import org.bukkit.configuration.file.FileConfiguration; 11 | import org.bukkit.entity.Player; 12 | import org.bukkit.plugin.Plugin; 13 | import org.bukkit.plugin.PluginManager; 14 | import org.bukkit.plugin.java.JavaPlugin; 15 | import org.bukkit.plugin.messaging.Messenger; 16 | import org.bukkit.potion.PotionEffect; 17 | import ru.overwrite.protect.bukkit.api.CaptureReason; 18 | import ru.overwrite.protect.bukkit.api.ServerProtectorAPI; 19 | import ru.overwrite.protect.bukkit.commands.PasCommand; 20 | import ru.overwrite.protect.bukkit.commands.UspCommand; 21 | import ru.overwrite.protect.bukkit.configuration.Config; 22 | import ru.overwrite.protect.bukkit.configuration.data.BlockingSettings; 23 | import ru.overwrite.protect.bukkit.configuration.data.SecureSettings; 24 | import ru.overwrite.protect.bukkit.configuration.data.SystemMessages; 25 | import ru.overwrite.protect.bukkit.listeners.ChatListener; 26 | import ru.overwrite.protect.bukkit.listeners.ConnectionListener; 27 | import ru.overwrite.protect.bukkit.listeners.MainListener; 28 | import ru.overwrite.protect.bukkit.listeners.TabCompleteListener; 29 | import ru.overwrite.protect.bukkit.task.BukkitRunner; 30 | import ru.overwrite.protect.bukkit.task.PaperRunner; 31 | import ru.overwrite.protect.bukkit.task.Runner; 32 | import ru.overwrite.protect.bukkit.task.TaskManager; 33 | import ru.overwrite.protect.bukkit.utils.PAPIUtils; 34 | import ru.overwrite.protect.bukkit.utils.PluginMessage; 35 | import ru.overwrite.protect.bukkit.utils.Utils; 36 | import ru.overwrite.protect.bukkit.utils.logging.BukkitLogger; 37 | import ru.overwrite.protect.bukkit.utils.logging.Logger; 38 | import ru.overwrite.protect.bukkit.utils.logging.PaperLogger; 39 | 40 | import java.io.BufferedWriter; 41 | import java.io.File; 42 | import java.io.FileWriter; 43 | import java.io.IOException; 44 | import java.lang.reflect.Constructor; 45 | import java.time.LocalDateTime; 46 | import java.time.format.DateTimeFormatter; 47 | import java.util.Collection; 48 | import java.util.HashMap; 49 | import java.util.List; 50 | import java.util.Map; 51 | import java.util.stream.Collectors; 52 | 53 | @Getter 54 | public class ServerProtectorManager extends JavaPlugin { 55 | 56 | private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("'['dd-MM-yyyy']' HH:mm:ss -"); 57 | 58 | private final Logger pluginLogger = Utils.FOLIA ? 59 | new PaperLogger(this) : 60 | new BukkitLogger(this); 61 | 62 | private boolean paper; 63 | 64 | private FileConfiguration messageFile; 65 | 66 | @Setter 67 | private FileConfiguration dataFile; 68 | private String dataFileName; 69 | private String dataFilePath; 70 | private final Config pluginConfig = new Config(this); 71 | private final ServerProtectorAPI api = new ServerProtectorAPI(this); 72 | private final PasswordHandler passwordHandler = new PasswordHandler(this); 73 | private final Runner runner = Utils.FOLIA ? new PaperRunner(this) : new BukkitRunner(this); 74 | 75 | private PluginMessage pluginMessage; 76 | 77 | private final Map perPlayerTime = new HashMap<>(); 78 | 79 | @Getter(AccessLevel.NONE) 80 | private File logFile; 81 | 82 | @Getter(AccessLevel.NONE) 83 | public final Server server = getServer(); 84 | 85 | public void checkPaper() { 86 | if (server.getName().equals("CraftBukkit")) { 87 | SystemMessages systemMessages = pluginConfig.getSystemMessages(); 88 | runner.runPeriodical(() -> { 89 | pluginLogger.info(systemMessages.baselineWarn()); 90 | pluginLogger.info(systemMessages.paper1()); 91 | pluginLogger.info(systemMessages.paper2()); 92 | pluginLogger.info(systemMessages.baselineWarn()); 93 | }, 0L, 20L * 1800); 94 | return; 95 | } 96 | this.paper = true; 97 | } 98 | 99 | private boolean safe; 100 | 101 | public void checkSafe(PluginManager pluginManager) { 102 | if (server.spigot().getConfig().getBoolean("settings.bungeecord")) { 103 | if (pluginManager.isPluginEnabled("BungeeGuard") || pluginManager.isPluginEnabled("SafeNET")) { 104 | this.safe = true; 105 | return; 106 | } 107 | logUnsafe(); 108 | return; 109 | } 110 | this.safe = true; 111 | } 112 | 113 | public void logUnsafe() { 114 | SystemMessages systemMessages = pluginConfig.getSystemMessages(); 115 | pluginLogger.info(systemMessages.baselineWarn()); 116 | pluginLogger.info(systemMessages.bungeecord1()); 117 | pluginLogger.info(systemMessages.bungeecord2()); 118 | pluginLogger.info(systemMessages.bungeecord3()); 119 | pluginLogger.info(systemMessages.baselineWarn()); 120 | } 121 | 122 | public void setupProxy(FileConfiguration config) { 123 | if (config.getBoolean("main-settings.proxy", false)) { 124 | Messenger messenger = server.getMessenger(); 125 | messenger.registerOutgoingPluginChannel(this, "BungeeCord"); 126 | pluginMessage = new PluginMessage(this); 127 | messenger.registerIncomingPluginChannel(this, "BungeeCord", pluginMessage); 128 | } 129 | } 130 | 131 | public void loadConfigs(FileConfiguration config) { 132 | Utils.setupColorizer(config.getConfigurationSection("main-settings")); 133 | final ConfigurationSection fileSettings = config.getConfigurationSection("file-settings"); 134 | boolean fullPath = fileSettings.getBoolean("use-full-path", false); 135 | dataFilePath = fullPath ? fileSettings.getString("data-file-path") : getDataFolder().getAbsolutePath(); 136 | dataFileName = fileSettings.getString("data-file"); 137 | dataFile = pluginConfig.getFile(dataFilePath, dataFileName); 138 | pluginConfig.save(dataFilePath, dataFile, dataFileName); 139 | messageFile = pluginConfig.getFile(getDataFolder().getAbsolutePath(), "message.yml"); 140 | pluginConfig.save(getDataFolder().getAbsolutePath(), messageFile, "message.yml"); 141 | setupPluginConfig(config); 142 | pluginConfig.setupPasswords(dataFile); 143 | } 144 | 145 | public void reloadConfigs() { 146 | runner.runAsync(() -> { 147 | reloadConfig(); 148 | final FileConfiguration config = getConfig(); 149 | Utils.setupColorizer(config.getConfigurationSection("main-settings")); 150 | messageFile = pluginConfig.getFile(getDataFolder().getAbsolutePath(), "message.yml"); 151 | final ConfigurationSection fileSettings = config.getConfigurationSection("file-settings"); 152 | boolean fullPath = fileSettings.getBoolean("use-full-path", false); 153 | dataFilePath = fullPath ? fileSettings.getString("data-file-path") : getDataFolder().getAbsolutePath(); 154 | dataFileName = fileSettings.getString("data-file"); 155 | dataFile = pluginConfig.getFile(dataFilePath, dataFileName); 156 | setupPluginConfig(config); 157 | pluginConfig.setupPasswords(dataFile); 158 | }); 159 | } 160 | 161 | private void setupPluginConfig(FileConfiguration config) { 162 | pluginConfig.loadAccessData(config); 163 | pluginConfig.setupExcluded(config); 164 | final FileConfiguration configFile = pluginConfig.getFile(dataFilePath, "config.yml"); 165 | pluginConfig.loadMainSettings(config, configFile); 166 | pluginConfig.loadEncryptionSettings(config, configFile); 167 | pluginConfig.loadSecureSettings(config, configFile); 168 | pluginConfig.loadApiSettings(config, configFile); 169 | pluginConfig.loadGeyserSettings(config, configFile); 170 | pluginConfig.loadAdditionalChecks(config, configFile); 171 | pluginConfig.loadPunishSettings(config, configFile); 172 | pluginConfig.loadSessionSettings(config, configFile); 173 | pluginConfig.loadMessageSettings(config, configFile); 174 | pluginConfig.loadBossbarSettings(config, configFile); 175 | pluginConfig.loadSoundSettings(config, configFile); 176 | pluginConfig.loadEffects(config, configFile); 177 | pluginConfig.loadLoggingSettings(config, configFile); 178 | pluginConfig.loadFailCommands(config, configFile); 179 | pluginConfig.loadMsgMessages(messageFile); 180 | pluginConfig.loadUspMessages(messageFile); 181 | pluginConfig.loadLogFormats(messageFile); 182 | pluginConfig.loadSystemMessages(messageFile); 183 | final ConfigurationSection messageSettings = config.getConfigurationSection("message-settings"); 184 | if (messageSettings.getBoolean("send-titles")) { 185 | pluginConfig.loadTitleMessages(messageFile); 186 | } 187 | if (messageSettings.getBoolean("enable-broadcasts") 188 | || messageSettings.getBoolean("enable-console-broadcasts")) { 189 | pluginConfig.loadBroadcastMessages(messageFile); 190 | } 191 | } 192 | 193 | public void registerListeners(PluginManager pluginManager) { 194 | pluginManager.registerEvents(new ChatListener(this), this); 195 | pluginManager.registerEvents(new ConnectionListener(this), this); 196 | pluginManager.registerEvents(new MainListener(this), this); 197 | if (paper && pluginConfig.getBlockingSettings().blockTabComplete()) { 198 | pluginManager.registerEvents(new TabCompleteListener(this), this); 199 | } 200 | } 201 | 202 | public void registerCommands(PluginManager pluginManager, ConfigurationSection mainSettings) { 203 | if (paper && mainSettings.getBoolean("use-command", true)) { 204 | try { 205 | CommandMap commandMap = server.getCommandMap(); 206 | Constructor constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class); 207 | constructor.setAccessible(true); 208 | PluginCommand command = constructor.newInstance(mainSettings.getString("pas-command", "pas"), this); 209 | command.setExecutor(new PasCommand(this)); 210 | commandMap.register(getDescription().getName(), command); 211 | } catch (Exception ex) { 212 | pluginLogger.info("Unable to register password command! " + ex.getMessage()); 213 | pluginManager.disablePlugin(this); 214 | } 215 | } else { 216 | pluginLogger.info("Command for password entering will not be registered."); 217 | } 218 | PluginCommand uspCommand = getCommand("ultimateserverprotector"); 219 | UspCommand uspCommandClass = new UspCommand(this); 220 | uspCommand.setExecutor(uspCommandClass); 221 | } 222 | 223 | public void startTasks(FileConfiguration config) { 224 | TaskManager taskManager = new TaskManager(this); 225 | taskManager.startMainCheck(pluginConfig.getMainSettings().checkInterval()); 226 | taskManager.startCapturesMessages(config); 227 | if (pluginConfig.getPunishSettings().enableTime()) { 228 | taskManager.startCapturesTimer(); 229 | } 230 | SecureSettings secureSettings = pluginConfig.getSecureSettings(); 231 | if (secureSettings.enableNotAdminPunish()) { 232 | taskManager.startAdminCheck(); 233 | } 234 | if (secureSettings.enableOpWhitelist()) { 235 | taskManager.startOpCheck(); 236 | } 237 | if (secureSettings.enablePermissionBlacklist()) { 238 | taskManager.startPermsCheck(); 239 | } 240 | } 241 | 242 | public void setupLogger(FileConfiguration config) { 243 | File dataFolder = getDataFolder(); 244 | if (!dataFolder.exists() && !dataFolder.mkdirs()) { 245 | throw new RuntimeException("Unable to create data folder"); 246 | } 247 | ConfigurationSection fileSettings = config.getConfigurationSection("file-settings"); 248 | boolean fullPath = fileSettings.getBoolean("use-full-path"); 249 | String logFilePath = fullPath ? fileSettings.getString("log-file-path") : dataFolder.getPath(); 250 | logFile = new File(logFilePath, fileSettings.getString("log-file")); 251 | } 252 | 253 | public void checkForUpdates(ConfigurationSection mainSettings) { 254 | if (!mainSettings.getBoolean("update-checker", true)) { 255 | return; 256 | } 257 | Utils.checkUpdates(this, version -> { 258 | SystemMessages systemMessages = pluginConfig.getSystemMessages(); 259 | pluginLogger.info(systemMessages.baselineDefault()); 260 | if (getDescription().getVersion().equals(version)) { 261 | pluginLogger.info(systemMessages.updateLatest()); 262 | } else { 263 | pluginLogger.info(systemMessages.updateOutdated1()); 264 | pluginLogger.info(systemMessages.updateOutdated2()); 265 | pluginLogger.info(systemMessages.updateOutdated3()); 266 | } 267 | pluginLogger.info(systemMessages.baselineDefault()); 268 | }); 269 | } 270 | 271 | public void checkFail(String playerName, List commands) { 272 | if (commands.isEmpty()) { 273 | return; 274 | } 275 | runner.run(() -> { 276 | for (String command : commands) { 277 | server.dispatchCommand(server.getConsoleSender(), command.replace("%player%", playerName)); 278 | if (pluginConfig.getLoggingSettings().loggingCommandExecution()) { 279 | LocalDateTime date = LocalDateTime.now(); 280 | logToFile(pluginConfig.getLogMessages().command() 281 | .replace("%player%", playerName) 282 | .replace("%cmd%", command) 283 | .replace("%date%", date.format(TIME_FORMATTER))); 284 | } 285 | } 286 | }); 287 | } 288 | 289 | @Getter(AccessLevel.NONE) 290 | private final Map> oldEffects = new HashMap<>(); 291 | 292 | public void giveEffects(Player player) { 293 | runner.runPlayer(() -> { 294 | if (!player.getActivePotionEffects().isEmpty()) { 295 | oldEffects.put(player.getName(), player.getActivePotionEffects()); 296 | } 297 | player.addPotionEffects(pluginConfig.getEffectSettings().effects()); 298 | }, player); 299 | } 300 | 301 | public void removeEffects(Player player) { 302 | runner.runPlayer(() -> { 303 | for (PotionEffect effect : player.getActivePotionEffects()) { // Old versions compatibility 304 | player.removePotionEffect(effect.getType()); 305 | } 306 | if (oldEffects.isEmpty()) { 307 | return; 308 | } 309 | Collection effects = oldEffects.get(player.getName()); 310 | if (effects != null) { 311 | player.addPotionEffects(effects); 312 | } 313 | }, player); 314 | } 315 | 316 | public void applyHide(Player player) { 317 | runner.runPlayer(() -> { 318 | BlockingSettings blockingSettings = pluginConfig.getBlockingSettings(); 319 | if (!blockingSettings.hideOnEntering() && !blockingSettings.hideOtherOnEntering()) { 320 | return; 321 | } 322 | for (Player onlinePlayer : server.getOnlinePlayers()) { 323 | if (blockingSettings.hideOnEntering()) { 324 | onlinePlayer.hidePlayer(this, player); 325 | } 326 | if (blockingSettings.hideOtherOnEntering()) { 327 | player.hidePlayer(this, onlinePlayer); 328 | } 329 | } 330 | }, player); 331 | } 332 | 333 | public void logEnableDisable(String msg, LocalDateTime date) { 334 | if (getConfig().getBoolean("logging-settings.logging-enable-disable", true)) { 335 | logToFile(msg.replace("%date%", date.format(TIME_FORMATTER))); 336 | } 337 | } 338 | 339 | public CaptureReason checkPermissions(Player player) { 340 | if (player.isOp()) { 341 | return new CaptureReason(null); 342 | } 343 | if (player.hasPermission("serverprotector.protect")) { 344 | return new CaptureReason("serverprotector.protect"); 345 | } 346 | for (String perm : pluginConfig.getAccessData().perms()) { 347 | if (player.hasPermission(perm)) { 348 | return new CaptureReason(perm); 349 | } 350 | } 351 | return null; 352 | } 353 | 354 | public boolean isExcluded(Player player, List list) { 355 | return pluginConfig.getSecureSettings().enableExcludedPlayers() && !list.isEmpty() && list.contains(player.getName()); 356 | } 357 | 358 | public boolean isAdmin(String nick) { 359 | return pluginConfig.getPerPlayerPasswords().containsKey(nick); 360 | } 361 | 362 | public void sendAlert(Player player, String msg) { 363 | msg = msg.replace("%player%", player.getName()).replace("%ip%", Utils.getIp(player)); 364 | if (pluginConfig.getMainSettings().papiSupport()) { 365 | msg = PAPIUtils.parsePlaceholders(player, msg); 366 | } 367 | if (pluginConfig.getMessageSettings().enableBroadcasts()) { 368 | for (Player onlinePlayer : server.getOnlinePlayers()) { 369 | if (onlinePlayer.hasPermission("serverprotector.admin") && player != onlinePlayer) { 370 | onlinePlayer.sendMessage(msg); 371 | } 372 | } 373 | if (this.pluginMessage != null) { 374 | pluginMessage.sendCrossProxy(player, msg); 375 | } 376 | } 377 | if (pluginConfig.getMessageSettings().enableConsoleBroadcasts()) { 378 | server.getConsoleSender().sendMessage(msg); 379 | } 380 | } 381 | 382 | public void logAction(String message, Player player, LocalDateTime date) { 383 | runner.runAsync(() -> 384 | logToFile(message 385 | .replace("%player%", player.getName()) 386 | .replace("%ip%", Utils.getIp(player)) 387 | .replace("%date%", date.format(TIME_FORMATTER))) 388 | ); 389 | } 390 | 391 | public void logToFile(String message) { 392 | try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(logFile, true))) { 393 | bufferedWriter.write(message); 394 | bufferedWriter.newLine(); 395 | } catch (IOException ex) { 396 | ex.printStackTrace(); 397 | } 398 | } 399 | 400 | public boolean isCalledFromAllowedApplication() { 401 | StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); 402 | 403 | List> callStack = walker.walk(frames -> 404 | frames.map(StackWalker.StackFrame::getDeclaringClass) 405 | .collect(Collectors.toList()) 406 | ); 407 | String className = callStack.get(2).getName(); 408 | 409 | if (className.startsWith("ru.overwrite.protect.bukkit")) { 410 | return true; 411 | } 412 | List allowedAuthApiCallsPackages = pluginConfig.getApiSettings().allowedAuthApiCallsPackages(); 413 | if (allowedAuthApiCallsPackages.isEmpty()) { 414 | pluginLogger.warn("Found illegal method call from " + className); 415 | return false; 416 | } 417 | for (int i = 0; i < allowedAuthApiCallsPackages.size(); i++) { 418 | String allowed = allowedAuthApiCallsPackages.get(i); 419 | if (className.startsWith(allowed)) { 420 | return true; 421 | } 422 | } 423 | pluginLogger.warn("Found illegal method call from " + className); 424 | return false; 425 | } 426 | } 427 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/api/CaptureReason.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.api; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | public record CaptureReason(String permission) { 6 | 7 | @NotNull 8 | public Reason getReason() { 9 | return permission != null ? Reason.PERMISSION : Reason.OPERATOR; 10 | } 11 | 12 | public enum Reason { 13 | OPERATOR, 14 | PERMISSION 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/api/ServerProtectorAPI.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.api; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.Cancellable; 5 | import org.jetbrains.annotations.NotNull; 6 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 7 | import ru.overwrite.protect.bukkit.configuration.Config; 8 | import ru.overwrite.protect.bukkit.utils.Utils; 9 | import ru.overwrite.protect.bukkit.utils.logging.Logger; 10 | 11 | import java.util.HashMap; 12 | import java.util.HashSet; 13 | import java.util.Map; 14 | import java.util.Set; 15 | 16 | public final class ServerProtectorAPI { 17 | 18 | private final ServerProtectorManager plugin; 19 | 20 | private final Config pluginConfig; 21 | private final Logger pluginLogger; 22 | 23 | private final Set captured = new HashSet<>(); 24 | private final Map sessions = new HashMap<>(); 25 | private final Set saved = new HashSet<>(); 26 | 27 | public ServerProtectorAPI(@NotNull ServerProtectorManager plugin) { 28 | this.plugin = plugin; 29 | this.pluginConfig = plugin.getPluginConfig(); 30 | this.pluginLogger = plugin.getPluginLogger(); 31 | } 32 | 33 | public boolean isAnybodyCaptured() { 34 | return !this.captured.isEmpty(); 35 | } 36 | 37 | public boolean isCaptured(@NotNull Player player) { 38 | return this.isCaptured(player.getName()); 39 | } 40 | 41 | public boolean isCaptured(@NotNull String playerName) { 42 | if (!this.isAnybodyCaptured()) { 43 | return false; 44 | } 45 | return this.captured.contains(playerName); 46 | } 47 | 48 | public void capturePlayer(@NotNull Player player) { 49 | this.capturePlayer(player.getName()); 50 | } 51 | 52 | public void capturePlayer(@NotNull String playerName) { 53 | if (this.isCaptured(playerName)) { 54 | this.warning("Unable to capture " + playerName + " Reason: Already captured"); 55 | return; 56 | } 57 | this.captured.add(playerName); 58 | } 59 | 60 | public void uncapturePlayer(@NotNull Player player) { 61 | this.uncapturePlayer(player.getName()); 62 | } 63 | 64 | public void uncapturePlayer(@NotNull String playerName) { 65 | if (!plugin.isCalledFromAllowedApplication()) { 66 | this.warning("Unable to uncapture " + playerName + " Reason: Action not allowed"); 67 | return; 68 | } 69 | if (!this.captured.remove(playerName)) { 70 | this.warning("Unable to uncapture " + playerName + " Reason: Not captured"); 71 | } 72 | } 73 | 74 | public boolean isAuthorised(@NotNull Player player) { 75 | return this.isAuthorised(player.getName(), Utils.getIp(player)); 76 | } 77 | 78 | public boolean isAuthorised(@NotNull Player player, @NotNull String ip) { 79 | return this.isAuthorised(player.getName(), ip); 80 | } 81 | 82 | public boolean isAuthorised(@NotNull String playerName, @NotNull String ip) { 83 | return pluginConfig.getSessionSettings().session() ? 84 | this.hasSession(playerName, ip) : 85 | this.saved.contains(playerName); 86 | } 87 | 88 | public boolean hasSession(@NotNull Player player) { 89 | return this.hasSession(player.getName(), Utils.getIp(player)); 90 | } 91 | 92 | public boolean hasSession(@NotNull Player player, @NotNull String ip) { 93 | return this.hasSession(player.getName(), ip); 94 | } 95 | 96 | public boolean hasSession(@NotNull String playerName, @NotNull String ip) { 97 | if (this.sessions.isEmpty()) { 98 | return false; 99 | } 100 | String sessionIp = this.sessions.get(playerName); 101 | return sessionIp != null && sessionIp.equals(ip); 102 | } 103 | 104 | public void authorisePlayer(@NotNull Player player) { 105 | this.authorisePlayer(player.getName(), Utils.getIp(player)); 106 | } 107 | 108 | public void authorisePlayer(@NotNull Player player, @NotNull String ip) { 109 | this.authorisePlayer(player.getName(), ip); 110 | } 111 | 112 | public void authorisePlayer(@NotNull String playerName, @NotNull String ip) { 113 | if (!plugin.isCalledFromAllowedApplication()) { 114 | this.warning("Unable to authorise " + playerName + " Reason: Action not allowed"); 115 | return; 116 | } 117 | if (isAuthorised(playerName, ip)) { 118 | this.warning("Unable to authorise " + playerName + " Reason: Already authorised"); 119 | return; 120 | } 121 | if (pluginConfig.getSessionSettings().session()) { 122 | this.sessions.put(playerName, ip); 123 | return; 124 | } 125 | this.saved.add(playerName); 126 | } 127 | 128 | public void deauthorisePlayer(@NotNull Player player) { 129 | this.deauthorisePlayer(player.getName(), Utils.getIp(player)); 130 | } 131 | 132 | public void deauthorisePlayer(@NotNull Player player, @NotNull String ip) { 133 | this.deauthorisePlayer(player.getName(), ip); 134 | } 135 | 136 | public void deauthorisePlayer(@NotNull String playerName, @NotNull String ip) { 137 | if (!plugin.isCalledFromAllowedApplication()) { 138 | this.warning("Unable to deauthorise " + playerName + " Reason: Action not allowed"); 139 | return; 140 | } 141 | if (!this.isAuthorised(playerName, ip)) { 142 | this.warning("Unable to deauthorise " + playerName + " Reason: Is not authorised"); 143 | return; 144 | } 145 | if (pluginConfig.getSessionSettings().session()) { 146 | this.sessions.remove(playerName); 147 | return; 148 | } 149 | this.saved.remove(playerName); 150 | } 151 | 152 | public void unsavePlayer(@NotNull Player player) { 153 | this.unsavePlayer(player.getName()); 154 | } 155 | 156 | public void unsavePlayer(@NotNull String playerName) { 157 | this.saved.remove(playerName); 158 | } 159 | 160 | public void handleInteraction(@NotNull Player player, Cancellable e) { 161 | if (this.isCaptured(player)) { 162 | e.setCancelled(true); 163 | } 164 | } 165 | 166 | public void clearCaptured() { 167 | if (!plugin.isCalledFromAllowedApplication()) { 168 | this.warning("Unable to clear captured players. Reason: Action not allowed"); 169 | return; 170 | } 171 | this.captured.clear(); 172 | } 173 | 174 | public void clearSessions() { 175 | if (!plugin.isCalledFromAllowedApplication()) { 176 | this.warning("Unable to clear active sessions. Reason: Action not allowed"); 177 | return; 178 | } 179 | this.sessions.clear(); 180 | } 181 | 182 | public void clearSaved() { 183 | if (!plugin.isCalledFromAllowedApplication()) { 184 | this.warning("Unable to clear saved players. Reason: Action not allowed"); 185 | return; 186 | } 187 | this.saved.clear(); 188 | } 189 | 190 | private void warning(String message) { 191 | if (!pluginConfig.getMainSettings().suppressApiWarnings()) { 192 | pluginLogger.warn(message); 193 | } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/api/events/ServerProtectorCaptureEvent.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.api.events; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.Cancellable; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | import ru.overwrite.protect.bukkit.api.CaptureReason; 8 | 9 | public class ServerProtectorCaptureEvent extends ServerProtectorPlayerEvent implements Cancellable { 10 | 11 | private static final HandlerList HANDLERS = new HandlerList(); 12 | 13 | private final String ip; 14 | 15 | private final CaptureReason captureReason; 16 | 17 | private boolean isCancelled = false; 18 | 19 | public ServerProtectorCaptureEvent(Player player, String ip, CaptureReason captureReason) { 20 | super(player, true); 21 | this.player = player; 22 | this.ip = ip; 23 | this.captureReason = captureReason; 24 | } 25 | 26 | @NotNull 27 | public static HandlerList getHandlerList() { 28 | return HANDLERS; 29 | } 30 | 31 | @NotNull 32 | @Override 33 | public HandlerList getHandlers() { 34 | return HANDLERS; 35 | } 36 | 37 | @Override 38 | public boolean isCancelled() { 39 | return this.isCancelled; 40 | } 41 | 42 | @Override 43 | public void setCancelled(boolean cancel) { 44 | this.isCancelled = cancel; 45 | } 46 | 47 | @NotNull 48 | public String getIp() { 49 | return this.ip; 50 | } 51 | 52 | @NotNull 53 | public CaptureReason getCaptureReason() { 54 | return this.captureReason; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/api/events/ServerProtectorLogoutEvent.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.api.events; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.HandlerList; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public class ServerProtectorLogoutEvent extends ServerProtectorPlayerEvent { 8 | 9 | private static final HandlerList HANDLERS = new HandlerList(); 10 | 11 | private final String ip; 12 | 13 | public ServerProtectorLogoutEvent(Player player, String ip) { 14 | super(player, true); 15 | this.player = player; 16 | this.ip = ip; 17 | } 18 | 19 | @NotNull 20 | public static HandlerList getHandlerList() { 21 | return HANDLERS; 22 | } 23 | 24 | @NotNull 25 | @Override 26 | public HandlerList getHandlers() { 27 | return HANDLERS; 28 | } 29 | 30 | @NotNull 31 | public String getIp() { 32 | return this.ip; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/api/events/ServerProtectorPasswordEnterEvent.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.api.events; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.Cancellable; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | public class ServerProtectorPasswordEnterEvent extends ServerProtectorPlayerEvent implements Cancellable { 9 | 10 | private static final HandlerList HANDLERS = new HandlerList(); 11 | 12 | private final String password; 13 | 14 | private boolean isCancelled = false; 15 | 16 | public ServerProtectorPasswordEnterEvent(Player player, String password) { 17 | super(player); 18 | this.player = player; 19 | this.password = password; 20 | } 21 | 22 | @NotNull 23 | public static HandlerList getHandlerList() { 24 | return HANDLERS; 25 | } 26 | 27 | @NotNull 28 | @Override 29 | public HandlerList getHandlers() { 30 | return HANDLERS; 31 | } 32 | 33 | @Override 34 | public boolean isCancelled() { 35 | return this.isCancelled; 36 | } 37 | 38 | @Override 39 | public void setCancelled(boolean cancel) { 40 | this.isCancelled = cancel; 41 | } 42 | 43 | @NotNull 44 | public String getEnteredPassword() { 45 | return this.password; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/api/events/ServerProtectorPasswordFailEvent.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.api.events; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.Cancellable; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | public class ServerProtectorPasswordFailEvent extends ServerProtectorPlayerEvent implements Cancellable { 9 | 10 | private static final HandlerList HANDLERS = new HandlerList(); 11 | 12 | private final int attempts; 13 | 14 | private boolean isCancelled = false; 15 | 16 | public ServerProtectorPasswordFailEvent(Player player, Integer attempts) { 17 | super(player); 18 | this.player = player; 19 | this.attempts = attempts; 20 | } 21 | 22 | @NotNull 23 | public static HandlerList getHandlerList() { 24 | return HANDLERS; 25 | } 26 | 27 | @NotNull 28 | @Override 29 | public HandlerList getHandlers() { 30 | return HANDLERS; 31 | } 32 | 33 | @Override 34 | public boolean isCancelled() { 35 | return isCancelled; 36 | } 37 | 38 | @Override 39 | public void setCancelled(boolean cancel) { 40 | this.isCancelled = cancel; 41 | } 42 | 43 | public int getAttempts() { 44 | return this.attempts; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/api/events/ServerProtectorPasswordSuccessEvent.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.api.events; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.Cancellable; 5 | import org.bukkit.event.HandlerList; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | public class ServerProtectorPasswordSuccessEvent extends ServerProtectorPlayerEvent implements Cancellable { 9 | 10 | private static final HandlerList HANDLERS = new HandlerList(); 11 | 12 | private boolean isCancelled = false; 13 | 14 | public ServerProtectorPasswordSuccessEvent(Player player) { 15 | super(player); 16 | this.player = player; 17 | } 18 | 19 | @NotNull 20 | public static HandlerList getHandlerList() { 21 | return HANDLERS; 22 | } 23 | 24 | @NotNull 25 | @Override 26 | public HandlerList getHandlers() { 27 | return HANDLERS; 28 | } 29 | 30 | @Override 31 | public boolean isCancelled() { 32 | return this.isCancelled; 33 | } 34 | 35 | @Override 36 | public void setCancelled(boolean cancel) { 37 | this.isCancelled = cancel; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/api/events/ServerProtectorPlayerEvent.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.api.events; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.Event; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | // Literally just copied PlayerEvent from Paper 8 | public abstract class ServerProtectorPlayerEvent extends Event { 9 | 10 | protected Player player; 11 | 12 | public ServerProtectorPlayerEvent(@NotNull final Player who) { 13 | this.player = who; 14 | } 15 | 16 | public ServerProtectorPlayerEvent(@NotNull final Player who, boolean async) { 17 | super(async); 18 | this.player = who; 19 | } 20 | 21 | /** 22 | * Returns the player involved in this event 23 | * 24 | * @return Player who is involved in this event 25 | */ 26 | @NotNull 27 | public final Player getPlayer() { 28 | return this.player; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/PasCommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands; 2 | 3 | import org.bukkit.command.Command; 4 | import org.bukkit.command.CommandExecutor; 5 | import org.bukkit.command.CommandSender; 6 | import org.bukkit.entity.Player; 7 | import org.jetbrains.annotations.NotNull; 8 | import ru.overwrite.protect.bukkit.PasswordHandler; 9 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 10 | import ru.overwrite.protect.bukkit.api.ServerProtectorAPI; 11 | import ru.overwrite.protect.bukkit.configuration.Config; 12 | import ru.overwrite.protect.bukkit.configuration.data.Messages; 13 | 14 | public final class PasCommand implements CommandExecutor { 15 | 16 | private final ServerProtectorManager plugin; 17 | private final ServerProtectorAPI api; 18 | private final PasswordHandler passwordHandler; 19 | private final Config pluginConfig; 20 | 21 | public PasCommand(ServerProtectorManager plugin) { 22 | this.plugin = plugin; 23 | this.pluginConfig = plugin.getPluginConfig(); 24 | this.passwordHandler = plugin.getPasswordHandler(); 25 | this.api = plugin.getApi(); 26 | } 27 | 28 | @Override 29 | public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) { 30 | Messages messages = pluginConfig.getMessages(); 31 | if (!(sender instanceof Player player)) { 32 | plugin.getPluginLogger().info(messages.playerOnly()); 33 | return true; 34 | } 35 | if (!api.isCaptured(player)) { 36 | sender.sendMessage(messages.noNeed()); 37 | return true; 38 | } 39 | if (args.length == 0) { 40 | sender.sendMessage(messages.cantBeNull()); 41 | return true; 42 | } 43 | passwordHandler.checkPassword(player, args[0], false); 44 | return true; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/UspCommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands; 2 | 3 | import org.bukkit.command.*; 4 | import org.bukkit.util.StringUtil; 5 | import org.jetbrains.annotations.NotNull; 6 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 7 | import ru.overwrite.protect.bukkit.commands.subcommands.*; 8 | import ru.overwrite.protect.bukkit.configuration.Config; 9 | import ru.overwrite.protect.bukkit.configuration.data.UspMessages; 10 | 11 | import java.util.*; 12 | 13 | public final class UspCommand implements TabExecutor { 14 | 15 | private final ServerProtectorManager plugin; 16 | private final Config pluginConfig; 17 | 18 | private final Map subCommands = new HashMap<>(); 19 | 20 | public UspCommand(ServerProtectorManager plugin) { 21 | this.plugin = plugin; 22 | this.pluginConfig = plugin.getPluginConfig(); 23 | this.registerSubCommands(plugin); 24 | } 25 | 26 | private void registerSubCommands(ServerProtectorManager plugin) { 27 | registerSubCommand(new LogoutSubcommand(plugin)); 28 | registerSubCommand(new ReloadSubcommand(plugin)); 29 | registerSubCommand(new RebootSubcommand(plugin)); 30 | registerSubCommand(new EncryptSubcommand(plugin)); 31 | registerSubCommand(new SetpassSubcommand(plugin)); 32 | registerSubCommand(new AddopSubcommand(plugin)); 33 | registerSubCommand(new AddipSubcommand(plugin)); 34 | registerSubCommand(new RempassSubcommand(plugin)); 35 | registerSubCommand(new RemopSubcommand(plugin)); 36 | registerSubCommand(new RemipSubcommand(plugin)); 37 | registerSubCommand(new UpdateSubcommand(plugin)); 38 | } 39 | 40 | private void registerSubCommand(AbstractSubCommand subCmd) { 41 | subCommands.put(subCmd.getName(), subCmd); 42 | } 43 | 44 | @Override 45 | public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) { 46 | if (args.length == 0) { 47 | sendHelp(sender, label); 48 | return true; 49 | } 50 | AbstractSubCommand subCommand = subCommands.get(args[0].toLowerCase()); 51 | if (subCommand != null) { 52 | if (subCommand.isAdminCommand()) { 53 | if (!pluginConfig.getMainSettings().enableAdminCommands()) { 54 | sendHelp(sender, label); 55 | return false; 56 | } 57 | if (pluginConfig.getSecureSettings().onlyConsoleUsp() && !(sender instanceof ConsoleCommandSender)) { 58 | sender.sendMessage(pluginConfig.getUspMessages().consoleOnly()); 59 | return false; 60 | } 61 | } 62 | if (!sender.hasPermission(subCommand.getPermission())) { 63 | sendHelp(sender, label); 64 | return false; 65 | } 66 | return subCommand.execute(sender, label, args); 67 | } 68 | if (sender.hasPermission("serverprotector.protect")) { 69 | sendHelp(sender, label); 70 | return true; 71 | } 72 | sender.sendMessage("§6❖ §7Running §c§lUltimateServerProtector " + plugin.getDescription().getVersion() + "§7 by §5OverwriteMC"); 73 | return true; 74 | } 75 | 76 | private void sendHelp(CommandSender sender, String label) { 77 | UspMessages uspMessages = pluginConfig.getUspMessages(); 78 | sendCmdMessage(sender, uspMessages.usage(), label, "protect"); 79 | sendCmdMessage(sender, uspMessages.usageLogout(), label, "protect"); 80 | if (!sender.hasPermission("admin")) { 81 | return; 82 | } 83 | sendCmdMessage(sender, uspMessages.usageReload(), label, "reload"); 84 | sendCmdMessage(sender, uspMessages.usageReboot(), label, "reboot"); 85 | if (pluginConfig.getEncryptionSettings().enableEncryption()) { 86 | sendCmdMessage(sender, uspMessages.usageEncrypt(), label, "encrypt"); 87 | } 88 | if (!pluginConfig.getMainSettings().enableAdminCommands()) { 89 | sender.sendMessage(uspMessages.otherDisabled()); 90 | return; 91 | } 92 | sendCmdMessage(sender, uspMessages.setPassUsage(), label, "setpass"); 93 | sendCmdMessage(sender, uspMessages.usageRemPass(), label, "rempass"); 94 | sendCmdMessage(sender, uspMessages.usageAddOp(), label, "addop"); 95 | sendCmdMessage(sender, uspMessages.usageRemOp(), label, "remop"); 96 | sendCmdMessage(sender, uspMessages.usageAddIp(), label, "addip"); 97 | sendCmdMessage(sender, uspMessages.usageRemIp(), label, "remip"); 98 | } 99 | 100 | private void sendCmdMessage(CommandSender sender, String msg, String label, String permission) { 101 | if (sender.hasPermission("serverprotector." + permission)) { 102 | sender.sendMessage(msg.replace("%cmd%", label)); 103 | } 104 | } 105 | 106 | @Override 107 | public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) { 108 | if (pluginConfig.getSecureSettings().onlyConsoleUsp() && !(sender instanceof ConsoleCommandSender)) { 109 | return List.of(); 110 | } 111 | final List completions = new ArrayList<>(); 112 | if (args.length == 1) { 113 | completions.add("logout"); 114 | completions.add("reload"); 115 | completions.add("reboot"); 116 | if (pluginConfig.getEncryptionSettings().enableEncryption()) { 117 | completions.add("encrypt"); 118 | } 119 | if (pluginConfig.getMainSettings().enableAdminCommands()) { 120 | completions.add("setpass"); 121 | completions.add("rempass"); 122 | completions.add("addop"); 123 | completions.add("remop"); 124 | completions.add("addip"); 125 | completions.add("remip"); 126 | } 127 | } 128 | return getResult(args, completions); 129 | } 130 | 131 | private List getResult(String[] args, List completions) { 132 | if (completions.isEmpty()) { 133 | return completions; 134 | } 135 | final List result = new ArrayList<>(); 136 | for (int i = 0; i < completions.size(); i++) { 137 | String c = completions.get(i); 138 | if (StringUtil.startsWithIgnoreCase(c, args[args.length - 1])) { 139 | result.add(c); 140 | } 141 | } 142 | return result; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/AbstractSubCommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import lombok.Getter; 4 | import org.bukkit.command.CommandSender; 5 | import ru.overwrite.protect.bukkit.PasswordHandler; 6 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 7 | import ru.overwrite.protect.bukkit.api.ServerProtectorAPI; 8 | import ru.overwrite.protect.bukkit.configuration.Config; 9 | 10 | public abstract class AbstractSubCommand implements SubCommand { 11 | 12 | @Getter 13 | protected final String name; 14 | @Getter 15 | protected final String permission; 16 | @Getter 17 | protected final boolean adminCommand; 18 | 19 | protected final ServerProtectorManager plugin; 20 | protected final ServerProtectorAPI api; 21 | protected final Config pluginConfig; 22 | protected final PasswordHandler passwordHandler; 23 | 24 | protected AbstractSubCommand(ServerProtectorManager plugin, String name, String permission, boolean adminCommand) { 25 | this.plugin = plugin; 26 | this.api = plugin.getApi(); 27 | this.pluginConfig = plugin.getPluginConfig(); 28 | this.passwordHandler = plugin.getPasswordHandler(); 29 | this.name = name; 30 | this.permission = permission; 31 | this.adminCommand = adminCommand; 32 | } 33 | 34 | protected void sendCmdUsage(CommandSender sender, String msg, String label) { 35 | sender.sendMessage(msg.replace("%cmd%", label)); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/AddipSubcommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.command.CommandSender; 4 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 5 | import ru.overwrite.protect.bukkit.configuration.data.UspMessages; 6 | 7 | import java.util.List; 8 | 9 | public class AddipSubcommand extends AbstractSubCommand { 10 | 11 | public AddipSubcommand(ServerProtectorManager plugin) { 12 | super(plugin, "addip", "serverprotector.addip", true); 13 | } 14 | 15 | @Override 16 | public boolean execute(CommandSender sender, String label, String[] args) { 17 | UspMessages uspMessages = pluginConfig.getUspMessages(); 18 | if (args.length > 2) { 19 | String nickname = args[1]; 20 | List ipwl = pluginConfig.getAccessData().ipWhitelist().get(nickname); 21 | if (ipwl == null || ipwl.isEmpty()) { 22 | sender.sendMessage(uspMessages.playerNotFound().replace("%nick%", nickname)); 23 | return true; 24 | } 25 | List ips = List.of(args).subList(2, args.length); 26 | ipwl.addAll(ips); 27 | plugin.getConfig().set("ip-whitelist." + nickname, ipwl); 28 | plugin.saveConfig(); 29 | sender.sendMessage(uspMessages.ipAdded().replace("%nick%", nickname).replace("%ip%", ips.toString())); 30 | return true; 31 | } 32 | sendCmdUsage(sender, uspMessages.addIpUsage(), label); 33 | return true; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/AddopSubcommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.OfflinePlayer; 5 | import org.bukkit.command.CommandSender; 6 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 7 | import ru.overwrite.protect.bukkit.configuration.data.UspMessages; 8 | import ru.overwrite.protect.bukkit.utils.Utils; 9 | 10 | import java.util.List; 11 | 12 | public class AddopSubcommand extends AbstractSubCommand { 13 | 14 | public AddopSubcommand(ServerProtectorManager plugin) { 15 | super(plugin, "addop", "serverprotector.addop", true); 16 | } 17 | 18 | @Override 19 | public boolean execute(CommandSender sender, String label, String[] args) { 20 | UspMessages uspMessages = pluginConfig.getUspMessages(); 21 | if (args.length > 1) { 22 | String nickname = args[1]; 23 | 24 | if (Utils.SUB_VERSION >= 16) { 25 | OfflinePlayer targetPlayer = Bukkit.getOfflinePlayerIfCached(nickname); 26 | if (targetPlayer == null) { 27 | sender.sendMessage(uspMessages.playerNotFound().replace("%nick%", nickname)); 28 | return true; 29 | } 30 | nickname = targetPlayer.getName(); 31 | } 32 | 33 | List whitelist = pluginConfig.getAccessData().opWhitelist(); 34 | whitelist.add(nickname); 35 | plugin.getConfig().set("op-whitelist", whitelist); 36 | plugin.saveConfig(); 37 | sender.sendMessage(uspMessages.playerAdded().replace("%nick%", nickname)); 38 | return true; 39 | } 40 | 41 | sendCmdUsage(sender, uspMessages.addOpUsage(), label); 42 | return true; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/EncryptSubcommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.command.CommandSender; 4 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 5 | import ru.overwrite.protect.bukkit.configuration.data.EncryptionSettings; 6 | import ru.overwrite.protect.bukkit.utils.Utils; 7 | 8 | public class EncryptSubcommand extends AbstractSubCommand { 9 | 10 | public EncryptSubcommand(ServerProtectorManager plugin) { 11 | super(plugin, "encrypt", "serverprotector.encrypt", false); 12 | } 13 | 14 | @Override 15 | public boolean execute(CommandSender sender, String label, String[] args) { 16 | EncryptionSettings encryptionSettings = pluginConfig.getEncryptionSettings(); 17 | if (encryptionSettings.enableEncryption() && args.length == 2) { 18 | sender.sendMessage( 19 | Utils.encryptPassword( 20 | args[1], 21 | Utils.generateSalt(encryptionSettings.saltLength()), 22 | encryptionSettings.encryptMethods() 23 | ) 24 | ); 25 | return true; 26 | } 27 | return false; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/LogoutSubcommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.command.CommandSender; 4 | import org.bukkit.entity.Player; 5 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 6 | import ru.overwrite.protect.bukkit.api.events.ServerProtectorLogoutEvent; 7 | import ru.overwrite.protect.bukkit.configuration.data.UspMessages; 8 | import ru.overwrite.protect.bukkit.utils.Utils; 9 | 10 | public class LogoutSubcommand extends AbstractSubCommand { 11 | 12 | public LogoutSubcommand(ServerProtectorManager plugin) { 13 | super(plugin, "logout", "serverprotector.protect", false); 14 | } 15 | 16 | @Override 17 | public boolean execute(CommandSender sender, String label, String[] args) { 18 | UspMessages uspMessages = pluginConfig.getUspMessages(); 19 | if (!(sender instanceof Player player)) { 20 | sender.sendMessage(uspMessages.playerOnly()); 21 | return false; 22 | } 23 | if (api.isAuthorised(player)) { 24 | plugin.getRunner().run(() -> { 25 | new ServerProtectorLogoutEvent(player, Utils.getIp(player)).callEvent(); 26 | api.deauthorisePlayer(player); 27 | }); 28 | player.kickPlayer(uspMessages.logout()); 29 | return true; 30 | } 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/RebootSubcommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.command.CommandSender; 4 | import org.bukkit.configuration.file.FileConfiguration; 5 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 6 | 7 | public class RebootSubcommand extends AbstractSubCommand { 8 | 9 | public RebootSubcommand(ServerProtectorManager plugin) { 10 | super(plugin, "reboot", "serverprotector.reboot", false); 11 | } 12 | 13 | @Override 14 | public boolean execute(CommandSender sender, String label, String[] args) { 15 | plugin.getRunner().cancelTasks(); 16 | plugin.reloadConfigs(); 17 | plugin.getPerPlayerTime().clear(); 18 | api.clearCaptured(); 19 | api.clearSaved(); 20 | api.clearSessions(); 21 | for (String playerName : passwordHandler.getBossbars().keySet()) { 22 | passwordHandler.getBossbars().get(playerName).removeAll(); 23 | } 24 | passwordHandler.getBossbars().clear(); 25 | passwordHandler.getAttempts().clear(); 26 | FileConfiguration newconfig = plugin.getConfig(); 27 | plugin.startTasks(newconfig); 28 | sender.sendMessage(pluginConfig.getUspMessages().rebooted()); 29 | return true; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/ReloadSubcommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.command.CommandSender; 4 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 5 | 6 | public class ReloadSubcommand extends AbstractSubCommand { 7 | 8 | public ReloadSubcommand(ServerProtectorManager plugin) { 9 | super(plugin, "reload", "serverprotector.reload", false); 10 | } 11 | 12 | @Override 13 | public boolean execute(CommandSender sender, String label, String[] args) { 14 | plugin.reloadConfigs(); 15 | sender.sendMessage(pluginConfig.getUspMessages().reloaded()); 16 | return true; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/RemipSubcommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.command.CommandSender; 4 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 5 | import ru.overwrite.protect.bukkit.configuration.data.UspMessages; 6 | 7 | import java.util.List; 8 | 9 | public class RemipSubcommand extends AbstractSubCommand { 10 | 11 | public RemipSubcommand(ServerProtectorManager plugin) { 12 | super(plugin, "remip", "serverprotector.remip", true); 13 | } 14 | 15 | @Override 16 | public boolean execute(CommandSender sender, String label, String[] args) { 17 | UspMessages uspMessages = pluginConfig.getUspMessages(); 18 | if (args.length > 2) { 19 | String nickname = args[1]; 20 | List ipwl = pluginConfig.getAccessData().ipWhitelist().get(nickname); 21 | if (ipwl == null || ipwl.isEmpty()) { 22 | sender.sendMessage(uspMessages.playerNotFound().replace("%nick%", nickname)); 23 | return true; 24 | } 25 | List ips = List.of(args).subList(2, args.length); 26 | ipwl.removeAll(ips); 27 | plugin.getConfig().set("ip-whitelist." + nickname, ipwl); 28 | plugin.saveConfig(); 29 | sender.sendMessage(uspMessages.ipRemoved().replace("%nick%", nickname).replace("%ip%", ips.toString())); 30 | return true; 31 | } 32 | sendCmdUsage(sender, uspMessages.remIpUsage(), label); 33 | return true; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/RemopSubcommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.command.CommandSender; 4 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 5 | import ru.overwrite.protect.bukkit.configuration.data.UspMessages; 6 | 7 | import java.util.List; 8 | 9 | public class RemopSubcommand extends AbstractSubCommand { 10 | 11 | public RemopSubcommand(ServerProtectorManager plugin) { 12 | super(plugin, "remop", "serverprotector.remop", true); 13 | } 14 | 15 | @Override 16 | public boolean execute(CommandSender sender, String label, String[] args) { 17 | UspMessages uspMessages = pluginConfig.getUspMessages(); 18 | if (args.length > 1) { 19 | String nickname = args[1]; 20 | List wl = pluginConfig.getAccessData().opWhitelist(); 21 | if (!wl.remove(nickname)) { 22 | sender.sendMessage(uspMessages.playerNotFound().replace("%nick%", nickname)); 23 | return true; 24 | } 25 | plugin.getConfig().set("op-whitelist", wl); 26 | plugin.saveConfig(); 27 | sender.sendMessage(uspMessages.playerRemoved().replace("%nick%", nickname)); 28 | return true; 29 | } 30 | sendCmdUsage(sender, uspMessages.remOpUsage(), label); 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/RempassSubcommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.command.CommandSender; 4 | import org.bukkit.configuration.file.FileConfiguration; 5 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 6 | import ru.overwrite.protect.bukkit.configuration.data.UspMessages; 7 | 8 | public class RempassSubcommand extends AbstractSubCommand { 9 | 10 | public RempassSubcommand(ServerProtectorManager plugin) { 11 | super(plugin, "rempass", "serverprotector.rempass", true); 12 | } 13 | 14 | @Override 15 | public boolean execute(CommandSender sender, String label, String[] args) { 16 | UspMessages uspMessages = pluginConfig.getUspMessages(); 17 | if (args.length > 1) { 18 | String nickname = args[1]; 19 | if (!plugin.isAdmin(nickname) && !plugin.isAdmin(pluginConfig.getGeyserSettings().prefix() + nickname)) { 20 | sender.sendMessage(uspMessages.notInConfig()); 21 | return true; 22 | } 23 | if (args.length < 3) { 24 | removeAdmin(nickname); 25 | sender.sendMessage(uspMessages.playerRemoved()); 26 | return true; 27 | } 28 | } 29 | sendCmdUsage(sender, uspMessages.remPassUsage(), label); 30 | return true; 31 | } 32 | 33 | private void removeAdmin(String nick) { 34 | FileConfiguration dataFile = pluginConfig.getFile(plugin.getDataFilePath(), plugin.getDataFileName()); 35 | if (!pluginConfig.getEncryptionSettings().enableEncryption()) { 36 | dataFile.set("data." + nick + ".pass", null); 37 | } else { 38 | dataFile.set("data." + nick + ".encrypted-pass", null); 39 | } 40 | dataFile.set("data." + nick, null); 41 | pluginConfig.save(plugin.getDataFilePath(), dataFile, plugin.getDataFileName()); 42 | plugin.setDataFile(dataFile); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/SetpassSubcommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.OfflinePlayer; 5 | import org.bukkit.command.CommandSender; 6 | import org.bukkit.configuration.file.FileConfiguration; 7 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 8 | import ru.overwrite.protect.bukkit.configuration.data.EncryptionSettings; 9 | import ru.overwrite.protect.bukkit.configuration.data.UspMessages; 10 | import ru.overwrite.protect.bukkit.utils.Utils; 11 | 12 | public class SetpassSubcommand extends AbstractSubCommand { 13 | 14 | public SetpassSubcommand(ServerProtectorManager plugin) { 15 | super(plugin, "setpass", "serverprotector.setpass", true); 16 | } 17 | 18 | @Override 19 | public boolean execute(CommandSender sender, String label, String[] args) { 20 | UspMessages uspMessages = pluginConfig.getUspMessages(); 21 | if (args.length > 1) { 22 | String nickname = args[1]; 23 | if (Utils.SUB_VERSION >= 16) { 24 | OfflinePlayer targetPlayer = Bukkit.getOfflinePlayerIfCached(nickname); 25 | if (targetPlayer == null) { 26 | sender.sendMessage(uspMessages.playerNotFound().replace("%nick%", nickname)); 27 | return true; 28 | } 29 | nickname = targetPlayer.getName(); 30 | } 31 | if (plugin.isAdmin(nickname)) { 32 | sender.sendMessage(uspMessages.alreadyInConfig()); 33 | return true; 34 | } 35 | if (args.length < 4) { 36 | addAdmin(nickname, args[2]); 37 | sender.sendMessage(uspMessages.playerAdded().replace("%nick%", nickname)); 38 | return true; 39 | } 40 | } 41 | sendCmdUsage(sender, uspMessages.setPassUsage(), label); 42 | return true; 43 | } 44 | 45 | private void addAdmin(String nick, String pas) { 46 | FileConfiguration dataFile = pluginConfig.getFile(plugin.getDataFilePath(), plugin.getDataFileName()); 47 | EncryptionSettings encryptionSettings = pluginConfig.getEncryptionSettings(); 48 | if (!encryptionSettings.enableEncryption()) { 49 | dataFile.set("data." + nick + ".pass", pas); 50 | } else if (encryptionSettings.autoEncryptPasswords()) { 51 | String encryptedPas = Utils.encryptPassword(pas, Utils.generateSalt(encryptionSettings.saltLength()), encryptionSettings.encryptMethods()); 52 | dataFile.set("data." + nick + ".encrypted-pass", encryptedPas); 53 | } else { 54 | dataFile.set("data." + nick + ".encrypted-pass", pas); 55 | } 56 | pluginConfig.save(plugin.getDataFilePath(), dataFile, plugin.getDataFileName()); 57 | plugin.setDataFile(dataFile); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/SubCommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.command.CommandSender; 4 | 5 | public interface SubCommand { 6 | 7 | boolean execute(CommandSender sender, String label, String[] args); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/commands/subcommands/UpdateSubcommand.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.commands.subcommands; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.command.CommandSender; 5 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 6 | import ru.overwrite.protect.bukkit.configuration.data.SystemMessages; 7 | import ru.overwrite.protect.bukkit.utils.Utils; 8 | 9 | import java.io.BufferedInputStream; 10 | import java.io.File; 11 | import java.io.FileOutputStream; 12 | import java.io.IOException; 13 | import java.net.URL; 14 | import java.net.URLConnection; 15 | 16 | public class UpdateSubcommand extends AbstractSubCommand { 17 | 18 | public UpdateSubcommand(ServerProtectorManager plugin) { 19 | super(plugin, "update", "serverprotector.update", true); 20 | } 21 | 22 | @Override 23 | public boolean execute(CommandSender sender, String label, String[] args) { 24 | checkAndUpdatePlugin(sender, plugin); 25 | return true; 26 | } 27 | 28 | public void checkAndUpdatePlugin(CommandSender sender, ServerProtectorManager plugin) { 29 | plugin.getRunner().runAsync(() -> Utils.checkUpdates(plugin, version -> { 30 | SystemMessages systemMessages = pluginConfig.getSystemMessages(); 31 | sender.sendMessage(systemMessages.baselineDefault()); 32 | 33 | String currentVersion = plugin.getDescription().getVersion(); 34 | 35 | if (currentVersion.equals(version)) { 36 | sender.sendMessage(systemMessages.updateLatest()); 37 | } else { 38 | String currentJarName = new File(plugin.getClass().getProtectionDomain().getCodeSource().getLocation().getPath()).getName(); 39 | String downloadUrl = "https://github.com/Overwrite987/UltimateServerProtector/releases/download/" + version + "/" + "UltimateServerProtector.jar"; 40 | try { 41 | File updateFolder = Bukkit.getUpdateFolderFile(); 42 | File targetFile = new File(updateFolder, currentJarName); 43 | 44 | downloadFile(downloadUrl, targetFile, sender); 45 | 46 | sender.sendMessage(systemMessages.updateSuccess1()); 47 | sender.sendMessage(systemMessages.updateSuccess2()); 48 | } catch (IOException ex) { 49 | sender.sendMessage("Unable to download update: " + ex.getMessage()); 50 | } 51 | } 52 | sender.sendMessage(systemMessages.baselineDefault()); 53 | })); 54 | } 55 | 56 | public void downloadFile(String fileURL, File targetFile, CommandSender sender) throws IOException { 57 | URL url = new URL(fileURL); 58 | URLConnection connection = url.openConnection(); 59 | int fileSize = connection.getContentLength(); 60 | 61 | try (BufferedInputStream in = new BufferedInputStream(connection.getInputStream()); 62 | FileOutputStream out = new FileOutputStream(targetFile)) { 63 | 64 | byte[] data = new byte[1024]; 65 | int bytesRead; 66 | int totalBytesRead = 0; 67 | int lastPercentage = 0; 68 | 69 | while ((bytesRead = in.read(data, 0, 1024)) != -1) { 70 | out.write(data, 0, bytesRead); 71 | totalBytesRead += bytesRead; 72 | int progressPercentage = (int) ((double) totalBytesRead / fileSize * 100); 73 | 74 | if (progressPercentage >= lastPercentage + 10) { 75 | lastPercentage = progressPercentage; 76 | int downloadedKB = totalBytesRead / 1024; 77 | int fullSizeKB = fileSize / 1024; 78 | sender.sendMessage(downloadedKB + "/" + fullSizeKB + "KB) (" + progressPercentage + "%)"); 79 | } 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/Config.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration; 2 | 3 | import lombok.AccessLevel; 4 | import lombok.Getter; 5 | import org.bukkit.boss.BarColor; 6 | import org.bukkit.boss.BarStyle; 7 | import org.bukkit.configuration.ConfigurationSection; 8 | import org.bukkit.configuration.file.FileConfiguration; 9 | import org.bukkit.configuration.file.YamlConfiguration; 10 | import org.bukkit.potion.PotionEffect; 11 | import org.bukkit.potion.PotionEffectType; 12 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 13 | import ru.overwrite.protect.bukkit.configuration.data.*; 14 | import ru.overwrite.protect.bukkit.utils.Utils; 15 | import ru.overwrite.protect.bukkit.utils.logging.Logger; 16 | 17 | import java.io.File; 18 | import java.io.IOException; 19 | import java.util.*; 20 | 21 | @Getter 22 | public final class Config { 23 | 24 | @Getter(AccessLevel.NONE) 25 | private final ServerProtectorManager plugin; 26 | @Getter(AccessLevel.NONE) 27 | private final Logger pluginLogger; 28 | 29 | public Config(ServerProtectorManager plugin) { 30 | this.plugin = plugin; 31 | this.pluginLogger = plugin.getPluginLogger(); 32 | } 33 | 34 | private Map perPlayerPasswords; 35 | 36 | public void setupPasswords(FileConfiguration dataFile) { 37 | ConfigurationSection data = dataFile.getConfigurationSection("data"); 38 | boolean shouldSave = false; 39 | Map perPlayerPasswords = new HashMap<>(); 40 | for (String nick : data.getKeys(false)) { 41 | String playerNick = (this.geyserSettings.prefix() != null && 42 | !this.geyserSettings.prefix().isBlank() && 43 | this.geyserSettings.nicknames().contains(nick)) 44 | ? this.geyserSettings.prefix() + nick 45 | : nick; 46 | if (!this.encryptionSettings.enableEncryption()) { 47 | perPlayerPasswords.put(playerNick, data.getString(nick + ".pass")); 48 | continue; 49 | } 50 | if (this.encryptionSettings.autoEncryptPasswords()) { 51 | if (data.getString(nick + ".pass") != null) { 52 | String encryptedPas = Utils.encryptPassword(data.getString(nick + ".pass"), Utils.generateSalt(this.encryptionSettings.saltLength()), this.encryptionSettings.encryptMethods()); 53 | dataFile.set("data." + nick + ".encrypted-pass", encryptedPas); 54 | dataFile.set("data." + nick + ".pass", null); 55 | shouldSave = true; 56 | plugin.setDataFile(dataFile); 57 | } 58 | } 59 | perPlayerPasswords.put(playerNick, data.getString(nick + ".encrypted-pass")); 60 | } 61 | this.perPlayerPasswords = Map.copyOf(perPlayerPasswords); 62 | if (shouldSave) { 63 | save(plugin.getDataFilePath(), dataFile, plugin.getDataFileName()); 64 | } 65 | } 66 | 67 | private MainSettings mainSettings; 68 | 69 | public void loadMainSettings(FileConfiguration config, FileConfiguration configFile) { 70 | ConfigurationSection mainSettings = config.getConfigurationSection("main-settings"); 71 | if (!configFile.contains("main-settings")) { 72 | pluginLogger.warn("Configuration section main-settings not found!"); 73 | ConfigurationSection section = configFile.createSection("main-settings"); 74 | section.set("serializer", "LEGACY"); 75 | section.set("prefix", "[UltimateServerProtector]"); 76 | section.set("pas-command", "pas"); 77 | section.set("use-command", true); 78 | section.set("enable-admin-commands", false); 79 | section.set("check-interval", 40); 80 | section.set("papi-support", false); 81 | section.set("suppress-api-warnings", false); 82 | save(plugin.getDataFilePath(), configFile, "config.yml"); 83 | pluginLogger.info("Created section main-settings"); 84 | mainSettings = configFile.getConfigurationSection("main-settings"); 85 | } 86 | this.mainSettings = new MainSettings( 87 | mainSettings.getString("prefix", "[UltimateServerProtector]"), 88 | mainSettings.getString("pas-command", "pas"), 89 | mainSettings.getBoolean("use-command", true), 90 | mainSettings.getBoolean("enable-admin-commands", false), 91 | mainSettings.getLong("check-interval", 40), 92 | mainSettings.getBoolean("papi-support", false), 93 | mainSettings.getBoolean("suppress-api-warnings", false) 94 | ); 95 | } 96 | 97 | private EncryptionSettings encryptionSettings; 98 | 99 | public void loadEncryptionSettings(FileConfiguration config, FileConfiguration configFile) { 100 | ConfigurationSection encryptionSettings = config.getConfigurationSection("encryption-settings"); 101 | if (!configFile.contains("encryption-settings")) { 102 | pluginLogger.warn("Configuration section encryption-settings not found!"); 103 | ConfigurationSection section = configFile.createSection("encryption-settings"); 104 | section.set("enable-encryption", false); 105 | section.set("encrypt-method", ""); 106 | section.set("old-encrypt-methods", List.of()); 107 | section.set("salt-length", 24); 108 | section.set("auto-encrypt-passwords", true); 109 | save(plugin.getDataFilePath(), configFile, "config.yml"); 110 | pluginLogger.info("Created section encryption-settings"); 111 | encryptionSettings = configFile.getConfigurationSection("encryption-settings"); 112 | } 113 | this.encryptionSettings = new EncryptionSettings( 114 | encryptionSettings.getBoolean("enable-encryption", false), 115 | getEncryptionMethods(encryptionSettings), 116 | encryptionSettings.getInt("salt-length", 24), 117 | encryptionSettings.getBoolean("auto-encrypt-passwords", true), 118 | getOldEncryptionMethods(encryptionSettings) 119 | ); 120 | } 121 | 122 | private List getEncryptionMethods(ConfigurationSection section) { 123 | String encryptionMethod = section.getString("encrypt-method", "").trim(); 124 | return encryptionMethod.isEmpty() ? List.of() : List.of(encryptionMethod.split(";")); 125 | } 126 | 127 | private List> getOldEncryptionMethods(ConfigurationSection section) { 128 | List> oldMethods = new ArrayList<>(); 129 | List oldEncryptionMethods = section.getStringList("old-encrypt-methods"); 130 | 131 | for (String oldEncryptionMethod : oldEncryptionMethods) { 132 | if (oldEncryptionMethod.contains(";")) { 133 | oldMethods.add(List.of(oldEncryptionMethod.trim().split(";"))); 134 | } else { 135 | oldMethods.add(List.of(oldEncryptionMethod.trim())); 136 | } 137 | } 138 | return List.copyOf(oldMethods); 139 | } 140 | 141 | private GeyserSettings geyserSettings; 142 | 143 | public void loadGeyserSettings(FileConfiguration config, FileConfiguration configFile) { 144 | ConfigurationSection geyserSettings = config.getConfigurationSection("geyser-settings"); 145 | if (!configFile.contains("geyser-settings")) { 146 | pluginLogger.warn("Configuration section geyser-settings not found!"); 147 | ConfigurationSection section = configFile.createSection("geyser-settings"); 148 | section.set("geyser-prefix", "."); 149 | section.set("geyser-nicknames", List.of("test99999")); 150 | save(plugin.getDataFilePath(), configFile, "config.yml"); 151 | pluginLogger.info("Created section geyser-settings"); 152 | geyserSettings = configFile.getConfigurationSection("geyser-settings"); 153 | } 154 | this.geyserSettings = new GeyserSettings( 155 | geyserSettings.getString("geyser-prefix", "."), 156 | Set.copyOf(geyserSettings.getStringList("geyser-nicknames")) 157 | ); 158 | } 159 | 160 | private BlockingSettings blockingSettings; 161 | 162 | public void loadAdditionalChecks(FileConfiguration config, FileConfiguration configFile) { 163 | ConfigurationSection blockingSettings = config.getConfigurationSection("blocking-settings"); 164 | if (!configFile.contains("blocking-settings")) { 165 | pluginLogger.warn("Configuration section blocking-settings not found!"); 166 | ConfigurationSection section = configFile.createSection("blocking-settings"); 167 | section.set("block-item-drop", true); 168 | section.set("block-item-pickup", true); 169 | section.set("block-tab-complete", true); 170 | section.set("block-damage", true); 171 | section.set("block-damaging-entity", true); 172 | section.set("block-inventory-open", false); 173 | section.set("hide-on-entering", true); 174 | section.set("hide-other-on-entering", true); 175 | section.set("allow-orientation-change", false); 176 | save(plugin.getDataFilePath(), configFile, "config.yml"); 177 | pluginLogger.info("Created section blocking-settings"); 178 | blockingSettings = configFile.getConfigurationSection("blocking-settings"); 179 | } 180 | this.blockingSettings = new BlockingSettings( 181 | blockingSettings.getBoolean("block-item-drop", true), 182 | blockingSettings.getBoolean("block-item-pickup", true), 183 | blockingSettings.getBoolean("block-tab-complete", true), 184 | blockingSettings.getBoolean("block-damage", true), 185 | blockingSettings.getBoolean("block-damaging-entity", true), 186 | blockingSettings.getBoolean("block-inventory-open", false), 187 | blockingSettings.getBoolean("hide-on-entering", true), 188 | blockingSettings.getBoolean("hide-other-on-entering", true), 189 | blockingSettings.getBoolean("allow-orientation-change", false) 190 | ); 191 | } 192 | 193 | private SessionSettings sessionSettings; 194 | 195 | public void loadSessionSettings(FileConfiguration config, FileConfiguration configFile) { 196 | ConfigurationSection sessionSettings = config.getConfigurationSection("session-settings"); 197 | if (!configFile.contains("session-settings")) { 198 | pluginLogger.warn("Configuration section session-settings not found!"); 199 | ConfigurationSection section = configFile.createSection("session-settings"); 200 | section.set("session", true); 201 | section.set("session-time-enabled", true); 202 | section.set("session-time", 21600); 203 | save(plugin.getDataFilePath(), configFile, "config.yml"); 204 | pluginLogger.info("Created section session-settings"); 205 | sessionSettings = configFile.getConfigurationSection("session-settings"); 206 | } 207 | this.sessionSettings = new SessionSettings( 208 | sessionSettings.getBoolean("session", true), 209 | sessionSettings.getBoolean("session-time-enabled", true), 210 | sessionSettings.getInt("session-time", 21600) 211 | ); 212 | } 213 | 214 | private PunishSettings punishSettings; 215 | 216 | public void loadPunishSettings(FileConfiguration config, FileConfiguration configFile) { 217 | ConfigurationSection punishSettings = config.getConfigurationSection("punish-settings"); 218 | if (!configFile.contains("punish-settings")) { 219 | pluginLogger.warn("Configuration section punish-settings not found!"); 220 | ConfigurationSection section = configFile.createSection("punish-settings"); 221 | section.set("enable-attempts", true); 222 | section.set("max-attempts", 3); 223 | section.set("enable-time", true); 224 | section.set("time", 60); 225 | section.set("enable-rejoin", true); 226 | section.set("max-rejoins", 3); 227 | save(plugin.getDataFilePath(), configFile, "config.yml"); 228 | pluginLogger.info("Created section punish-settings"); 229 | punishSettings = configFile.getConfigurationSection("punish-settings"); 230 | } 231 | this.punishSettings = new PunishSettings( 232 | punishSettings.getBoolean("enable-attempts", true), 233 | punishSettings.getInt("max-attempts", 3), 234 | punishSettings.getBoolean("enable-time", true), 235 | punishSettings.getInt("time", 60), 236 | punishSettings.getBoolean("enable-rejoin", true), 237 | punishSettings.getInt("max-rejoins", 3) 238 | ); 239 | } 240 | 241 | private SecureSettings secureSettings; 242 | 243 | public void loadSecureSettings(FileConfiguration config, FileConfiguration configFile) { 244 | ConfigurationSection secureSettings = config.getConfigurationSection("secure-settings"); 245 | if (!configFile.contains("secure-settings")) { 246 | pluginLogger.warn("Configuration section secure-settings not found!"); 247 | ConfigurationSection section = configFile.createSection("secure-settings"); 248 | section.set("enable-op-whitelist", false); 249 | section.set("enable-notadmin-punish", false); 250 | section.set("enable-permission-blacklist", false); 251 | section.set("enable-ip-whitelist", false); 252 | section.set("only-console-usp", false); 253 | section.set("enable-excluded-players", false); 254 | save(plugin.getDataFilePath(), configFile, "config.yml"); 255 | pluginLogger.info("Created section secure-settings"); 256 | secureSettings = configFile.getConfigurationSection("secure-settings"); 257 | } 258 | this.secureSettings = new SecureSettings( 259 | secureSettings.getBoolean("enable-op-whitelist", false), 260 | secureSettings.getBoolean("enable-notadmin-punish", false), 261 | secureSettings.getBoolean("enable-permission-blacklist", false), 262 | secureSettings.getBoolean("enable-ip-whitelist", false), 263 | secureSettings.getBoolean("only-console-usp", false), 264 | secureSettings.getBoolean("enable-excluded-players", false) 265 | ); 266 | } 267 | 268 | private ApiSettings apiSettings; 269 | 270 | public void loadApiSettings(FileConfiguration config, FileConfiguration configFile) { 271 | ConfigurationSection apiSettings = config.getConfigurationSection("api-settings"); 272 | if (!configFile.contains("api-settings")) { 273 | pluginLogger.warn("Configuration section api-settings not found!"); 274 | ConfigurationSection section = configFile.createSection("api-settings"); 275 | section.set("allow-cancel-capture-event", false); 276 | section.set("call-event-on-password-enter", false); 277 | section.set("allowed-auth-api-calls-packages", List.of()); 278 | save(plugin.getDataFilePath(), configFile, "config.yml"); 279 | pluginLogger.info("Created section api-settings"); 280 | apiSettings = configFile.getConfigurationSection("api-settings"); 281 | } 282 | this.apiSettings = new ApiSettings( 283 | apiSettings.getBoolean("allow-cancel-capture-event", false), 284 | apiSettings.getBoolean("call-event-on-password-enter", false), 285 | List.copyOf(apiSettings.getStringList("allowed-auth-api-calls-packages")) 286 | ); 287 | } 288 | 289 | private MessageSettings messageSettings; 290 | 291 | public void loadMessageSettings(FileConfiguration config, FileConfiguration configFile) { 292 | ConfigurationSection messageSettings = config.getConfigurationSection("message-settings"); 293 | if (!configFile.contains("message-settings")) { 294 | pluginLogger.warn("Configuration section message-settings not found!"); 295 | ConfigurationSection section = configFile.createSection("message-settings"); 296 | section.set("send-titles", true); 297 | section.set("enable-broadcasts", true); 298 | section.set("enable-console-broadcasts", true); 299 | save(plugin.getDataFilePath(), configFile, "config.yml"); 300 | pluginLogger.info("Created section message-settings"); 301 | messageSettings = configFile.getConfigurationSection("message-settings"); 302 | } 303 | this.messageSettings = new MessageSettings( 304 | messageSettings.getBoolean("send-titles", true), 305 | messageSettings.getBoolean("enable-broadcasts", true), 306 | messageSettings.getBoolean("enable-console-broadcasts", true) 307 | ); 308 | } 309 | 310 | private BossbarSettings bossbarSettings; 311 | 312 | public void loadBossbarSettings(FileConfiguration config, FileConfiguration configFile) { 313 | ConfigurationSection bossbarSettings = config.getConfigurationSection("bossbar-settings"); 314 | if (!configFile.contains("bossbar-settings")) { 315 | pluginLogger.warn("Configuration section bossbar-settings not found!"); 316 | ConfigurationSection section = configFile.createSection("bossbar-settings"); 317 | section.set("enable-bossbar", false); 318 | section.set("bar-color", "RED"); 319 | section.set("bar-style", "SEGMENTED_12"); 320 | save(plugin.getDataFilePath(), configFile, "config.yml"); 321 | pluginLogger.info("Created section bossbar-settings"); 322 | bossbarSettings = configFile.getConfigurationSection("bossbar-settings"); 323 | } 324 | ConfigurationSection bossbar = plugin.getMessageFile().getConfigurationSection("bossbar"); 325 | String bossbarMessage = getMessage(bossbar, "message"); 326 | 327 | this.bossbarSettings = new BossbarSettings( 328 | bossbarSettings.getBoolean("enable-bossbar", true), 329 | BarColor.valueOf(bossbarSettings.getString("bar-color", "RED")), 330 | BarStyle.valueOf(bossbarSettings.getString("bar-style", "SEGMENTED_12")), 331 | bossbarMessage 332 | ); 333 | } 334 | 335 | private SoundSettings soundSettings; 336 | 337 | public void loadSoundSettings(FileConfiguration config, FileConfiguration configFile) { 338 | ConfigurationSection soundSettings = config.getConfigurationSection("sound-settings"); 339 | if (!configFile.contains("sound-settings")) { 340 | pluginLogger.warn("Configuration section sound-settings not found!"); 341 | ConfigurationSection section = configFile.createSection("sound-settings"); 342 | section.set("enable-sounds", false); 343 | section.set("on-capture", "ENTITY_ITEM_BREAK;1.0;1.0"); 344 | section.set("on-pas-fail", "ENTITY_VILLAGER_NO;1.0;1.0"); 345 | section.set("on-pas-correct", "ENTITY_PLAYER_LEVELUP;1.0;1.0"); 346 | save(plugin.getDataFilePath(), configFile, "config.yml"); 347 | pluginLogger.info("Created section sound-settings"); 348 | soundSettings = configFile.getConfigurationSection("sound-settings"); 349 | } 350 | this.soundSettings = new SoundSettings( 351 | soundSettings.getBoolean("enable-sounds"), 352 | soundSettings.getString("on-capture", "ENTITY_ITEM_BREAK;1.0;1.0").split(";"), 353 | soundSettings.getString("on-pas-fail", "ENTITY_VILLAGER_NO;1.0;1.0").split(";"), 354 | soundSettings.getString("on-pas-correct", "ENTITY_PLAYER_LEVELUP;1.0;1.0").split(";") 355 | ); 356 | } 357 | 358 | private EffectSettings effectSettings; 359 | 360 | public void loadEffects(FileConfiguration config, FileConfiguration configFile) { 361 | ConfigurationSection effectSettings = config.getConfigurationSection("effect-settings"); 362 | if (!configFile.contains("effect-settings")) { 363 | pluginLogger.warn("Configuration section effect-settings not found!"); 364 | ConfigurationSection section = configFile.createSection("effect-settings"); 365 | section.set("enable-effects", true); 366 | section.set("effects", List.of("BLINDNESS;3")); 367 | save(plugin.getDataFilePath(), configFile, "config.yml"); 368 | pluginLogger.info("Created section effect-settings"); 369 | effectSettings = configFile.getConfigurationSection("effect-settings"); 370 | } 371 | List effectList = getEffectList(effectSettings.getStringList("effects")); 372 | this.effectSettings = new EffectSettings( 373 | effectSettings.getBoolean("enable-effects", true), 374 | effectList 375 | ); 376 | } 377 | 378 | private List getEffectList(List effects) { 379 | if (effects.isEmpty()) { 380 | return List.of(); 381 | } 382 | List effectList = new ArrayList<>(effects.size()); 383 | for (String effect : effects) { 384 | int separatorIndex = effect.indexOf(';'); 385 | String effectName = separatorIndex > 0 ? effect.substring(0, separatorIndex) : effect; 386 | PotionEffectType type = PotionEffectType.getByName(effectName.toUpperCase()); 387 | int level = separatorIndex > 0 ? Integer.parseInt(effect.substring(separatorIndex + 1)) - 1 : 0; 388 | if (type != null) { 389 | effectList.add(new PotionEffect(type, Integer.MAX_VALUE, level)); 390 | } 391 | } 392 | return List.copyOf(effectList); 393 | } 394 | 395 | private LoggingSettings loggingSettings; 396 | 397 | public void loadLoggingSettings(FileConfiguration config, FileConfiguration configFile) { 398 | ConfigurationSection loggingSettings = config.getConfigurationSection("logging-settings"); 399 | if (!configFile.contains("logging-settings")) { 400 | pluginLogger.warn("Configuration section logging-settings not found!"); 401 | ConfigurationSection section = configFile.createSection("logging-settings"); 402 | section.set("logging-pas", true); 403 | section.set("logging-join", true); 404 | section.set("logging-enable-disable", true); 405 | section.set("logging-command-execution", true); 406 | save(plugin.getDataFilePath(), configFile, "config.yml"); 407 | pluginLogger.info("Created section logging-settings"); 408 | loggingSettings = configFile.getConfigurationSection("logging-settings"); 409 | } 410 | this.loggingSettings = new LoggingSettings( 411 | loggingSettings.getBoolean("logging-pas", true), 412 | loggingSettings.getBoolean("logging-join", true), 413 | loggingSettings.getBoolean("logging-enable-disable", true), 414 | loggingSettings.getBoolean("logging-command-execution", true) 415 | ); 416 | } 417 | 418 | private Commands commands; 419 | 420 | public void loadFailCommands(FileConfiguration config, FileConfiguration configFile) { 421 | ConfigurationSection commands = config.getConfigurationSection("commands"); 422 | if (!configFile.contains("commands")) { 423 | pluginLogger.warn("Configuration section commands not found!"); 424 | ConfigurationSection section = configFile.createSection("commands"); 425 | section.set("not-in-config", List.of()); 426 | section.set("not-in-opwhitelist", List.of()); 427 | section.set("have-blacklisted-perm", List.of()); 428 | section.set("not-admin-ip", List.of()); 429 | section.set("failed-pass", List.of()); 430 | section.set("failed-time", List.of()); 431 | section.set("failed-rejoin", List.of()); 432 | save(plugin.getDataFilePath(), configFile, "config.yml"); 433 | pluginLogger.info("Created section main-settings"); 434 | commands = configFile.getConfigurationSection("commands"); 435 | } 436 | this.commands = new Commands( 437 | List.copyOf(commands.getStringList("not-in-config")), 438 | List.copyOf(commands.getStringList("not-in-opwhitelist")), 439 | List.copyOf(commands.getStringList("have-blacklisted-perm")), 440 | List.copyOf(commands.getStringList("not-admin-ip")), 441 | List.copyOf(commands.getStringList("failed-pass")), 442 | List.copyOf(commands.getStringList("failed-time")), 443 | List.copyOf(commands.getStringList("failed-rejoin")) 444 | ); 445 | } 446 | 447 | private AccessData accessData; 448 | 449 | public void loadAccessData(FileConfiguration config) { 450 | Set perms = Set.copyOf(config.getStringList("permissions")); 451 | List allowedCommands = List.copyOf(config.getStringList("allowed-commands")); 452 | 453 | ConfigurationSection secureSettings = config.getConfigurationSection("secure-settings"); 454 | 455 | List opWhitelist = List.of(); 456 | Set blacklistedPerms = Set.of(); 457 | Map> ipWhitelist = Map.of(); 458 | 459 | if (secureSettings.getBoolean("enable-op-whitelist")) { 460 | opWhitelist = List.copyOf(config.getStringList("op-whitelist")); 461 | } 462 | if (secureSettings.getBoolean("enable-permission-blacklist")) { 463 | blacklistedPerms = Set.copyOf(config.getStringList("blacklisted-perms")); 464 | } 465 | if (secureSettings.getBoolean("enable-ip-whitelist")) { 466 | Map> ipWhitelistTemp = new HashMap<>(); 467 | for (String ipwlPlayer : config.getConfigurationSection("ip-whitelist").getKeys(false)) { 468 | List ips = List.copyOf(config.getStringList("ip-whitelist." + ipwlPlayer)); 469 | ipWhitelistTemp.put(ipwlPlayer, ips); 470 | } 471 | ipWhitelist = Map.copyOf(ipWhitelistTemp); 472 | } 473 | this.accessData = new AccessData( 474 | perms, 475 | allowedCommands, 476 | opWhitelist, 477 | blacklistedPerms, 478 | ipWhitelist); 479 | } 480 | 481 | private ExcludedPlayers excludedPlayers; 482 | 483 | public void setupExcluded(FileConfiguration config) { 484 | ConfigurationSection excludedPlayers = config.getConfigurationSection("excluded-players"); 485 | this.excludedPlayers = new ExcludedPlayers( 486 | List.copyOf(excludedPlayers.getStringList("admin-pass")), 487 | List.copyOf(excludedPlayers.getStringList("op-whitelist")), 488 | List.copyOf(excludedPlayers.getStringList("ip-whitelist")), 489 | List.copyOf(excludedPlayers.getStringList("blacklisted-perms")) 490 | ); 491 | } 492 | 493 | private UspMessages uspMessages; 494 | 495 | public void loadUspMessages(FileConfiguration message) { 496 | ConfigurationSection uspmsg = message.getConfigurationSection("uspmsg"); 497 | this.uspMessages = new UspMessages( 498 | getMessage(uspmsg, "consoleonly"), 499 | getMessage(uspmsg, "reloaded"), 500 | getMessage(uspmsg, "rebooted"), 501 | getMessage(uspmsg, "playernotfound"), 502 | getMessage(uspmsg, "alreadyinconfig"), 503 | getMessage(uspmsg, "playeronly"), 504 | getMessage(uspmsg, "logout"), 505 | getMessage(uspmsg, "notinconfig"), 506 | getMessage(uspmsg, "playeradded"), 507 | getMessage(uspmsg, "playerremoved"), 508 | getMessage(uspmsg, "ipadded"), 509 | getMessage(uspmsg, "setpassusage"), 510 | getMessage(uspmsg, "addopusage"), 511 | getMessage(uspmsg, "remopusage"), 512 | getMessage(uspmsg, "ipremoved"), 513 | getMessage(uspmsg, "remipusage"), 514 | getMessage(uspmsg, "addipusage"), 515 | getMessage(uspmsg, "rempassusage"), 516 | getMessage(uspmsg, "usage"), 517 | getMessage(uspmsg, "usage-logout"), 518 | getMessage(uspmsg, "usage-reload"), 519 | getMessage(uspmsg, "usage-reboot"), 520 | getMessage(uspmsg, "usage-encrypt"), 521 | getMessage(uspmsg, "usage-setpass"), 522 | getMessage(uspmsg, "usage-rempass"), 523 | getMessage(uspmsg, "usage-addop"), 524 | getMessage(uspmsg, "usage-remop"), 525 | getMessage(uspmsg, "usage-addip"), 526 | getMessage(uspmsg, "usage-remip"), 527 | getMessage(uspmsg, "otherdisabled") 528 | ); 529 | } 530 | 531 | private Messages messages; 532 | 533 | public void loadMsgMessages(FileConfiguration message) { 534 | ConfigurationSection msg = message.getConfigurationSection("msg"); 535 | this.messages = new Messages( 536 | getMessage(msg, "message"), 537 | getMessage(msg, "incorrect"), 538 | getMessage(msg, "correct"), 539 | getMessage(msg, "noneed"), 540 | getMessage(msg, "cantbenull"), 541 | getMessage(msg, "playeronly") 542 | ); 543 | } 544 | 545 | private Titles titles; 546 | 547 | public void loadTitleMessages(FileConfiguration message) { 548 | ConfigurationSection titles = message.getConfigurationSection("titles"); 549 | this.titles = new Titles( 550 | getMessage(titles, "message").split(";"), 551 | getMessage(titles, "incorrect").split(";"), 552 | getMessage(titles, "correct").split(";") 553 | ); 554 | } 555 | 556 | private Broadcasts broadcasts; 557 | 558 | public void loadBroadcastMessages(FileConfiguration message) { 559 | ConfigurationSection broadcasts = message.getConfigurationSection("broadcasts"); 560 | this.broadcasts = new Broadcasts( 561 | getMessage(broadcasts, "failed"), 562 | getMessage(broadcasts, "passed"), 563 | getMessage(broadcasts, "joined"), 564 | getMessage(broadcasts, "captured"), 565 | getMessage(broadcasts, "disabled") 566 | ); 567 | } 568 | 569 | private LogMessages logMessages; 570 | 571 | public void loadLogFormats(FileConfiguration message) { 572 | ConfigurationSection logMessages = message.getConfigurationSection("log-format"); 573 | this.logMessages = new LogMessages( 574 | getMessage(logMessages, "enabled"), 575 | getMessage(logMessages, "disabled"), 576 | getMessage(logMessages, "failed"), 577 | getMessage(logMessages, "passed"), 578 | getMessage(logMessages, "joined"), 579 | getMessage(logMessages, "captured"), 580 | getMessage(logMessages, "command") 581 | ); 582 | } 583 | 584 | private SystemMessages systemMessages; 585 | 586 | public void loadSystemMessages(FileConfiguration message) { 587 | ConfigurationSection system = message.getConfigurationSection("system"); 588 | this.systemMessages = new SystemMessages( 589 | getMessage(system, "baseline-warn"), 590 | getMessage(system, "baseline-default"), 591 | getMessage(system, "paper-1"), 592 | getMessage(system, "paper-2"), 593 | getMessage(system, "bungeecord-1"), 594 | getMessage(system, "bungeecord-2"), 595 | getMessage(system, "bungeecord-3"), 596 | getMessage(system, "update-latest"), 597 | getMessage(system, "update-success-1"), 598 | getMessage(system, "update-success-2"), 599 | getMessage(system, "update-outdated-1"), 600 | getMessage(system, "update-outdated-2"), 601 | getMessage(system, "update-outdated-3") 602 | ); 603 | } 604 | 605 | public String getMessage(ConfigurationSection section, String key) { 606 | if (section == null) { 607 | return Utils.COLORIZER.colorize("&4&lERROR&r: " + key + " does not exist!"); 608 | } 609 | return Utils.COLORIZER.colorize(section.getString(key, "&4&lERROR&r: " + key + " does not exist!").replace("%prefix%", mainSettings.prefix())); 610 | } 611 | 612 | public FileConfiguration getFile(String path, String fileName) { 613 | File file = new File(path, fileName); 614 | if (!file.exists()) { 615 | plugin.saveResource(fileName, false); 616 | } 617 | return YamlConfiguration.loadConfiguration(file); 618 | } 619 | 620 | public void save(String path, FileConfiguration config, String fileName) { 621 | plugin.getRunner().runAsync(() -> { 622 | try { 623 | config.save(new File(path, fileName)); 624 | } catch (IOException ex) { 625 | ex.printStackTrace(); 626 | } 627 | }); 628 | } 629 | } 630 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/AccessData.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.Set; 6 | 7 | public record AccessData( 8 | Set perms, 9 | List allowedCommands, 10 | List opWhitelist, 11 | Set blacklistedPerms, 12 | Map> ipWhitelist 13 | ) { 14 | } 15 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/ApiSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | import java.util.List; 4 | 5 | public record ApiSettings( 6 | boolean allowCancelCaptureEvent, 7 | boolean callEventOnPasswordEnter, 8 | List allowedAuthApiCallsPackages 9 | ) { 10 | } 11 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/BlockingSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record BlockingSettings( 4 | boolean blockItemDrop, 5 | boolean blockItemPickup, 6 | boolean blockTabComplete, 7 | boolean blockDamage, 8 | boolean blockDamagingEntity, 9 | boolean blockInventoryOpen, 10 | boolean hideOnEntering, 11 | boolean hideOtherOnEntering, 12 | boolean allowOrientationChange 13 | ) { 14 | } 15 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/BossbarSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | import org.bukkit.boss.BarColor; 4 | import org.bukkit.boss.BarStyle; 5 | 6 | public record BossbarSettings( 7 | boolean enableBossbar, 8 | BarColor barColor, 9 | BarStyle barStyle, 10 | String bossbarMessage 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/Broadcasts.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record Broadcasts( 4 | String failed, 5 | String passed, 6 | String joined, 7 | String captured, 8 | String disabled 9 | ) { 10 | } 11 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/Commands.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | import java.util.List; 4 | 5 | public record Commands( 6 | List notInConfig, 7 | List notInOpWhitelist, 8 | List haveBlacklistedPerm, 9 | List notAdminIp, 10 | List failedPass, 11 | List failedTime, 12 | List failedRejoin 13 | ) { 14 | } 15 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/EffectSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | import org.bukkit.potion.PotionEffect; 4 | 5 | import java.util.List; 6 | 7 | public record EffectSettings( 8 | boolean enableEffects, 9 | List effects 10 | ) { 11 | } 12 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/EncryptionSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | import java.util.List; 4 | 5 | public record EncryptionSettings( 6 | boolean enableEncryption, 7 | List encryptMethods, 8 | int saltLength, 9 | boolean autoEncryptPasswords, 10 | List> oldEncryptMethods 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/ExcludedPlayers.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | import java.util.List; 4 | 5 | public record ExcludedPlayers( 6 | List adminPass, 7 | List opWhitelist, 8 | List ipWhitelist, 9 | List blacklistedPerms 10 | ) { 11 | } 12 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/GeyserSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | import java.util.Set; 4 | 5 | public record GeyserSettings( 6 | String prefix, 7 | Set nicknames 8 | ) { 9 | } 10 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/LogMessages.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record LogMessages( 4 | String enabled, 5 | String disabled, 6 | String failed, 7 | String passed, 8 | String joined, 9 | String captured, 10 | String command 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/LoggingSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record LoggingSettings( 4 | boolean loggingPas, 5 | boolean loggingJoin, 6 | boolean loggingEnableDisable, 7 | boolean loggingCommandExecution 8 | ) { 9 | } -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/MainSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record MainSettings( 4 | String prefix, 5 | String pasCommand, 6 | boolean useCommand, 7 | boolean enableAdminCommands, 8 | long checkInterval, 9 | boolean papiSupport, 10 | boolean suppressApiWarnings 11 | ) { 12 | } 13 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/MessageSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record MessageSettings( 4 | boolean sendTitle, 5 | boolean enableBroadcasts, 6 | boolean enableConsoleBroadcasts 7 | ) { 8 | } 9 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/Messages.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record Messages( 4 | String message, 5 | String incorrect, 6 | String correct, 7 | String noNeed, 8 | String cantBeNull, 9 | String playerOnly 10 | ) { 11 | } 12 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/PunishSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record PunishSettings( 4 | boolean enableAttempts, 5 | int maxAttempts, 6 | boolean enableTime, 7 | int time, 8 | boolean enableRejoin, 9 | int maxRejoins 10 | ) { 11 | } 12 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/SecureSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record SecureSettings( 4 | boolean enableOpWhitelist, 5 | boolean enableNotAdminPunish, 6 | boolean enablePermissionBlacklist, 7 | boolean enableIpWhitelist, 8 | boolean onlyConsoleUsp, 9 | boolean enableExcludedPlayers 10 | ) { 11 | } 12 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/SessionSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record SessionSettings( 4 | boolean session, 5 | boolean sessionTimeEnabled, 6 | int sessionTime 7 | ) { 8 | } 9 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/SoundSettings.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record SoundSettings( 4 | boolean enableSounds, 5 | String[] onCapture, 6 | String[] onPasFail, 7 | String[] onPasCorrect 8 | ) { 9 | } 10 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/SystemMessages.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record SystemMessages( 4 | String baselineWarn, 5 | String baselineDefault, 6 | String paper1, 7 | String paper2, 8 | String bungeecord1, 9 | String bungeecord2, 10 | String bungeecord3, 11 | String updateLatest, 12 | String updateSuccess1, 13 | String updateSuccess2, 14 | String updateOutdated1, 15 | String updateOutdated2, 16 | String updateOutdated3 17 | ) { 18 | } 19 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/Titles.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record Titles( 4 | String[] message, 5 | String[] incorrect, 6 | String[] correct 7 | ) { 8 | } 9 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/configuration/data/UspMessages.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.configuration.data; 2 | 3 | public record UspMessages( 4 | String consoleOnly, 5 | String reloaded, 6 | String rebooted, 7 | String playerNotFound, 8 | String alreadyInConfig, 9 | String playerOnly, 10 | String logout, 11 | String notInConfig, 12 | String playerAdded, 13 | String playerRemoved, 14 | String ipAdded, 15 | String setPassUsage, 16 | String addOpUsage, 17 | String remOpUsage, 18 | String ipRemoved, 19 | String remIpUsage, 20 | String addIpUsage, 21 | String remPassUsage, 22 | String usage, 23 | String usageLogout, 24 | String usageReload, 25 | String usageReboot, 26 | String usageEncrypt, 27 | String usageSetPass, 28 | String usageRemPass, 29 | String usageAddOp, 30 | String usageRemOp, 31 | String usageAddIp, 32 | String usageRemIp, 33 | String otherDisabled 34 | ) { 35 | } 36 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/listeners/ChatListener.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.listeners; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.EventHandler; 5 | import org.bukkit.event.EventPriority; 6 | import org.bukkit.event.Listener; 7 | import org.bukkit.event.player.AsyncPlayerChatEvent; 8 | import org.bukkit.event.player.PlayerCommandPreprocessEvent; 9 | import ru.overwrite.protect.bukkit.PasswordHandler; 10 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 11 | import ru.overwrite.protect.bukkit.api.ServerProtectorAPI; 12 | import ru.overwrite.protect.bukkit.configuration.Config; 13 | 14 | import java.util.List; 15 | 16 | public class ChatListener implements Listener { 17 | 18 | private final ServerProtectorManager plugin; 19 | private final ServerProtectorAPI api; 20 | private final PasswordHandler passwordHandler; 21 | private final Config pluginConfig; 22 | 23 | public ChatListener(ServerProtectorManager plugin) { 24 | this.plugin = plugin; 25 | this.pluginConfig = plugin.getPluginConfig(); 26 | this.passwordHandler = plugin.getPasswordHandler(); 27 | this.api = plugin.getApi(); 28 | } 29 | 30 | @EventHandler(priority = EventPriority.LOWEST) 31 | public void onChat(AsyncPlayerChatEvent e) { 32 | Player player = e.getPlayer(); 33 | if (!api.isCaptured(player)) { 34 | return; 35 | } 36 | if (!pluginConfig.getMainSettings().useCommand()) { 37 | String message = e.getMessage(); 38 | passwordHandler.checkPassword(player, message, true); 39 | } 40 | e.setMessage(""); 41 | e.setCancelled(true); 42 | } 43 | 44 | @EventHandler(priority = EventPriority.LOWEST) 45 | public void onCommand(PlayerCommandPreprocessEvent e) { 46 | Player player = e.getPlayer(); 47 | if (!api.isCaptured(player)) { 48 | return; 49 | } 50 | String message = e.getMessage(); 51 | String label = cutCommand(message); 52 | if (pluginConfig.getMainSettings().useCommand()) { 53 | if (label.equalsIgnoreCase("/" + pluginConfig.getMainSettings().pasCommand())) { 54 | if (!plugin.isPaper()) { 55 | passwordHandler.checkPassword(player, cutArguments(message), false); 56 | } 57 | return; 58 | } 59 | } 60 | List allowedCommands = pluginConfig.getAccessData().allowedCommands(); 61 | for (int i = 0; i < allowedCommands.size(); i++) { 62 | final String command = allowedCommands.get(i); 63 | if (label.equalsIgnoreCase(command) || message.equalsIgnoreCase(command)) { 64 | return; 65 | } 66 | } 67 | e.setCancelled(true); 68 | } 69 | 70 | private String cutCommand(String str) { 71 | int index = str.indexOf(' '); 72 | return index == -1 ? str : str.substring(0, index); 73 | } 74 | 75 | private String cutArguments(String str) { 76 | int index = str.indexOf(' '); 77 | return index == -1 ? str : str.substring(index + 1); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/listeners/ConnectionListener.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.listeners; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.EventHandler; 5 | import org.bukkit.event.EventPriority; 6 | import org.bukkit.event.Listener; 7 | import org.bukkit.event.player.*; 8 | import org.bukkit.potion.PotionEffect; 9 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 10 | import ru.overwrite.protect.bukkit.api.CaptureReason; 11 | import ru.overwrite.protect.bukkit.api.ServerProtectorAPI; 12 | import ru.overwrite.protect.bukkit.api.events.ServerProtectorCaptureEvent; 13 | import ru.overwrite.protect.bukkit.configuration.Config; 14 | import ru.overwrite.protect.bukkit.task.Runner; 15 | 16 | import java.time.LocalDateTime; 17 | import java.util.HashMap; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | public class ConnectionListener implements Listener { 22 | 23 | private final ServerProtectorManager plugin; 24 | private final ServerProtectorAPI api; 25 | private final Config pluginConfig; 26 | 27 | private final Runner runner; 28 | 29 | public ConnectionListener(ServerProtectorManager plugin) { 30 | this.plugin = plugin; 31 | this.api = plugin.getApi(); 32 | this.pluginConfig = plugin.getPluginConfig(); 33 | this.runner = plugin.getRunner(); 34 | } 35 | 36 | @EventHandler(priority = EventPriority.LOWEST) 37 | public void onPreLogin(AsyncPlayerPreLoginEvent e) { 38 | if (!plugin.isSafe()) { 39 | plugin.logUnsafe(); 40 | e.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); 41 | } 42 | } 43 | 44 | @EventHandler(priority = EventPriority.LOWEST) 45 | public void onLogin(PlayerLoginEvent e) { 46 | final Player player = e.getPlayer(); 47 | player.loadData(); 48 | runner.runAsync(() -> { 49 | final String playerName = player.getName(); 50 | CaptureReason captureReason = plugin.checkPermissions(player); 51 | if (api.isCaptured(playerName) && captureReason == null) { 52 | api.uncapturePlayer(playerName); 53 | return; 54 | } 55 | if (captureReason != null) { 56 | final String ip = e.getAddress().getHostAddress(); 57 | if (pluginConfig.getSecureSettings().enableIpWhitelist()) { 58 | if (!isIPAllowed(ip, pluginConfig.getAccessData().ipWhitelist().get(playerName))) { 59 | if (!plugin.isExcluded(player, pluginConfig.getExcludedPlayers().ipWhitelist())) { 60 | plugin.checkFail(playerName, pluginConfig.getCommands().notAdminIp()); 61 | } 62 | } 63 | } 64 | if (pluginConfig.getSessionSettings().session() && !api.hasSession(playerName, ip)) { 65 | if (!plugin.isExcluded(player, pluginConfig.getExcludedPlayers().adminPass())) { 66 | ServerProtectorCaptureEvent captureEvent = new ServerProtectorCaptureEvent(player, ip, captureReason); 67 | captureEvent.callEvent(); 68 | if (pluginConfig.getApiSettings().allowCancelCaptureEvent() && captureEvent.isCancelled()) { 69 | return; 70 | } 71 | api.capturePlayer(playerName); 72 | } 73 | } 74 | } 75 | }); 76 | } 77 | 78 | @EventHandler(priority = EventPriority.LOWEST) 79 | public void onJoin(PlayerJoinEvent e) { 80 | runner.runAsync(() -> { 81 | Player player = e.getPlayer(); 82 | CaptureReason captureReason = plugin.checkPermissions(player); 83 | if (captureReason != null) { 84 | if (api.isCaptured(player)) { 85 | if (pluginConfig.getEffectSettings().enableEffects()) { 86 | plugin.giveEffects(player); 87 | } 88 | plugin.applyHide(player); 89 | } 90 | if (pluginConfig.getLoggingSettings().loggingJoin()) { 91 | plugin.logAction(pluginConfig.getLogMessages().joined(), player, LocalDateTime.now()); 92 | } 93 | if (pluginConfig.getBroadcasts() != null) { 94 | plugin.sendAlert(player, pluginConfig.getBroadcasts().joined()); 95 | } 96 | } 97 | }); 98 | } 99 | 100 | private boolean isIPAllowed(String playerIp, List allowedIps) { 101 | if (allowedIps == null || allowedIps.isEmpty()) { 102 | return false; 103 | } 104 | 105 | outer: 106 | for (int i = 0; i < allowedIps.size(); i++) { 107 | final String allowedIp = allowedIps.get(i); 108 | int playerIpLength = playerIp.length(); 109 | int allowedIpLength = allowedIp.length(); 110 | 111 | if (playerIpLength != allowedIpLength && !allowedIp.contains("*")) { 112 | continue; 113 | } 114 | 115 | for (int n = 0; n < allowedIpLength; n++) { 116 | char currentChar = allowedIp.charAt(n); 117 | if (currentChar == '*') { 118 | return true; 119 | } 120 | 121 | if (n >= playerIpLength || currentChar != playerIp.charAt(n)) { 122 | continue outer; 123 | } 124 | } 125 | 126 | if (playerIpLength == allowedIpLength) { 127 | return true; 128 | } 129 | } 130 | 131 | return false; 132 | } 133 | 134 | private final Map rejoins = new HashMap<>(); 135 | 136 | @EventHandler(priority = EventPriority.HIGHEST) 137 | public void onLeave(PlayerQuitEvent event) { 138 | Player player = event.getPlayer(); 139 | handlePlayerLeave(player); 140 | } 141 | 142 | @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) 143 | public void onKick(PlayerKickEvent event) { 144 | Player player = event.getPlayer(); 145 | handlePlayerLeave(player); 146 | } 147 | 148 | private void handlePlayerLeave(Player player) { 149 | String playerName = player.getName(); 150 | if (api.isCaptured(player)) { 151 | for (PotionEffect effect : player.getActivePotionEffects()) { // Old versions compatibility 152 | player.removePotionEffect(effect.getType()); 153 | } 154 | if (pluginConfig.getPunishSettings().enableRejoin()) { 155 | handleRejoin(playerName); 156 | } 157 | } 158 | plugin.getPerPlayerTime().remove(playerName); 159 | api.unsavePlayer(playerName); 160 | } 161 | 162 | private void handleRejoin(String playerName) { 163 | int attempts = rejoins.merge(playerName, 1, Integer::sum); 164 | if (attempts > pluginConfig.getPunishSettings().maxRejoins()) { 165 | plugin.checkFail(playerName, pluginConfig.getCommands().failedRejoin()); 166 | rejoins.remove(playerName); 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/listeners/MainListener.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.listeners; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.EventHandler; 6 | import org.bukkit.event.EventPriority; 7 | import org.bukkit.event.Listener; 8 | import org.bukkit.event.entity.EntityDamageByEntityEvent; 9 | import org.bukkit.event.entity.EntityDamageEvent; 10 | import org.bukkit.event.entity.EntityPickupItemEvent; 11 | import org.bukkit.event.inventory.InventoryOpenEvent; 12 | import org.bukkit.event.player.PlayerDropItemEvent; 13 | import org.bukkit.event.player.PlayerInteractEntityEvent; 14 | import org.bukkit.event.player.PlayerInteractEvent; 15 | import org.bukkit.event.player.PlayerMoveEvent; 16 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 17 | import ru.overwrite.protect.bukkit.api.ServerProtectorAPI; 18 | import ru.overwrite.protect.bukkit.configuration.Config; 19 | 20 | public class MainListener implements Listener { 21 | 22 | private final ServerProtectorAPI api; 23 | private final Config pluginConfig; 24 | 25 | public MainListener(ServerProtectorManager plugin) { 26 | this.api = plugin.getApi(); 27 | this.pluginConfig = plugin.getPluginConfig(); 28 | } 29 | 30 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 31 | public void onMove(PlayerMoveEvent e) { 32 | if (!api.isAnybodyCaptured()) 33 | return; 34 | if (pluginConfig.getBlockingSettings().allowOrientationChange() && hasChangedOrientation(e.getFrom(), e.getTo()) && !hasChangedPosition(e.getFrom(), e.getTo())) { 35 | return; 36 | } 37 | Player player = e.getPlayer(); 38 | api.handleInteraction(player, e); 39 | } 40 | 41 | private boolean hasChangedOrientation(Location from, Location to) { 42 | return from.getPitch() != to.getPitch() || from.getYaw() != to.getYaw(); 43 | } 44 | 45 | public boolean hasChangedPosition(Location from, Location to) { 46 | return from.getX() != to.getX() || from.getY() != to.getY() || from.getZ() != to.getZ(); 47 | } 48 | 49 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 50 | public void onPlayerInteract(PlayerInteractEvent e) { 51 | Player player = e.getPlayer(); 52 | api.handleInteraction(player, e); 53 | } 54 | 55 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 56 | public void onPlayerInteractEntity(PlayerInteractEntityEvent e) { 57 | Player player = e.getPlayer(); 58 | api.handleInteraction(player, e); 59 | } 60 | 61 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 62 | public void onItemDrop(PlayerDropItemEvent e) { 63 | Player player = e.getPlayer(); 64 | if (pluginConfig.getBlockingSettings().blockItemDrop()) { 65 | api.handleInteraction(player, e); 66 | } 67 | } 68 | 69 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 70 | public void onItemPickup(EntityPickupItemEvent e) { 71 | if (!(e.getEntity() instanceof Player player)) 72 | return; 73 | if (pluginConfig.getBlockingSettings().blockItemPickup()) { 74 | api.handleInteraction(player, e); 75 | } 76 | } 77 | 78 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 79 | public void onPlayerDamage(EntityDamageEvent e) { 80 | if (!(e.getEntity() instanceof Player player)) 81 | return; 82 | if (pluginConfig.getBlockingSettings().blockDamage()) { 83 | api.handleInteraction(player, e); 84 | } 85 | } 86 | 87 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 88 | public void onPlayerDamageEntity(EntityDamageByEntityEvent e) { 89 | if (!(e.getDamager() instanceof Player player)) 90 | return; 91 | if (pluginConfig.getBlockingSettings().blockDamagingEntity()) { 92 | api.handleInteraction(player, e); 93 | } 94 | } 95 | 96 | @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) 97 | public void onInventoryOpen(InventoryOpenEvent e) { 98 | Player player = (Player) e.getPlayer(); 99 | if (pluginConfig.getBlockingSettings().blockInventoryOpen()) { 100 | api.handleInteraction(player, e); 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/listeners/TabCompleteListener.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.listeners; 2 | 3 | import com.destroystokyo.paper.event.server.AsyncTabCompleteEvent; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.EventHandler; 6 | import org.bukkit.event.Listener; 7 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 8 | import ru.overwrite.protect.bukkit.api.ServerProtectorAPI; 9 | import ru.overwrite.protect.bukkit.configuration.Config; 10 | 11 | public class TabCompleteListener implements Listener { 12 | 13 | private final ServerProtectorAPI api; 14 | private final Config pluginConfig; 15 | 16 | public TabCompleteListener(ServerProtectorManager plugin) { 17 | this.api = plugin.getApi(); 18 | this.pluginConfig = plugin.getPluginConfig(); 19 | } 20 | 21 | @EventHandler(ignoreCancelled = true) 22 | public void onTabComplete(AsyncTabCompleteEvent e) { 23 | if (!(e.getSender() instanceof Player player)) 24 | return; 25 | if (pluginConfig.getBlockingSettings().blockTabComplete()) { 26 | api.handleInteraction(player, e); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/task/BukkitRunner.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.task; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.scheduler.BukkitScheduler; 5 | import org.jetbrains.annotations.NotNull; 6 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 7 | 8 | @SuppressWarnings("deprecation") 9 | public final class BukkitRunner implements Runner { 10 | 11 | private final ServerProtectorManager plugin; 12 | private final BukkitScheduler scheduler; 13 | 14 | public BukkitRunner(ServerProtectorManager plugin) { 15 | this.plugin = plugin; 16 | this.scheduler = plugin.getServer().getScheduler(); 17 | } 18 | 19 | @Override 20 | public void runPlayer(@NotNull Runnable task, @NotNull Player player) { 21 | run(task); 22 | } 23 | 24 | @Override 25 | public void run(@NotNull Runnable task) { 26 | scheduler.runTask(plugin, task); 27 | } 28 | 29 | @Override 30 | public void runAsync(@NotNull Runnable task) { 31 | scheduler.runTaskAsynchronously(plugin, task); 32 | } 33 | 34 | @Override 35 | public void runDelayed(@NotNull Runnable task, long delayTicks) { 36 | scheduler.runTaskLater(plugin, task, delayTicks); 37 | } 38 | 39 | @Override 40 | public void runDelayedAsync(@NotNull Runnable task, long delayTicks) { 41 | scheduler.runTaskLaterAsynchronously(plugin, task, delayTicks); 42 | } 43 | 44 | @Override 45 | public void runPeriodical(@NotNull Runnable task, long delayTicks, long periodTicks) { 46 | scheduler.runTaskTimer(plugin, task, delayTicks, periodTicks); 47 | } 48 | 49 | @Override 50 | public void runPeriodicalAsync(@NotNull Runnable task, long delayTicks, long periodTicks) { 51 | scheduler.runTaskTimerAsynchronously(plugin, task, delayTicks, periodTicks); 52 | } 53 | 54 | @Override 55 | public void cancelTasks() { 56 | if (!plugin.isCalledFromAllowedApplication()) { 57 | return; 58 | } 59 | scheduler.cancelTasks(plugin); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/task/PaperRunner.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.task; 2 | 3 | import io.papermc.paper.threadedregions.scheduler.AsyncScheduler; 4 | import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler; 5 | import io.papermc.paper.threadedregions.scheduler.ScheduledTask; 6 | import org.bukkit.entity.Player; 7 | import org.jetbrains.annotations.NotNull; 8 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 9 | 10 | import java.util.concurrent.TimeUnit; 11 | import java.util.function.Consumer; 12 | 13 | public final class PaperRunner implements Runner { 14 | 15 | private final ServerProtectorManager plugin; 16 | private final AsyncScheduler asyncScheduler; 17 | private final GlobalRegionScheduler globalScheduler; 18 | 19 | public PaperRunner(ServerProtectorManager plugin) { 20 | this.plugin = plugin; 21 | this.asyncScheduler = plugin.getServer().getAsyncScheduler(); 22 | this.globalScheduler = plugin.getServer().getGlobalRegionScheduler(); 23 | } 24 | 25 | @Override 26 | public void runPlayer(@NotNull Runnable task, Player player) { 27 | player.getScheduler().run(plugin, toConsumer(task), null); 28 | } 29 | 30 | @Override 31 | public void run(@NotNull Runnable task) { 32 | globalScheduler.run(plugin, toConsumer(task)); 33 | } 34 | 35 | @Override 36 | public void runAsync(@NotNull Runnable task) { 37 | asyncScheduler.runNow(plugin, toConsumer(task)); 38 | } 39 | 40 | @Override 41 | public void runDelayed(@NotNull Runnable task, long delayTicks) { 42 | globalScheduler.runDelayed(plugin, toConsumer(task), delayTicks); 43 | } 44 | 45 | @Override 46 | public void runDelayedAsync(@NotNull Runnable task, long delayTicks) { 47 | asyncScheduler.runDelayed(plugin, toConsumer(task), toMilli(delayTicks), TimeUnit.MILLISECONDS); 48 | } 49 | 50 | @Override 51 | public void runPeriodical(@NotNull Runnable task, long delayTicks, long periodTicks) { 52 | globalScheduler.runAtFixedRate(plugin, toConsumer(task), delayTicks, periodTicks); 53 | } 54 | 55 | @Override 56 | public void runPeriodicalAsync(@NotNull Runnable task, long delayTicks, long periodTicks) { 57 | asyncScheduler.runAtFixedRate(plugin, toConsumer(task), toMilli(delayTicks), toMilli(periodTicks), TimeUnit.MILLISECONDS); 58 | } 59 | 60 | @Override 61 | public void cancelTasks() { 62 | if (!plugin.isCalledFromAllowedApplication()) { 63 | return; 64 | } 65 | globalScheduler.cancelTasks(plugin); 66 | asyncScheduler.cancelTasks(plugin); 67 | } 68 | 69 | private static Consumer toConsumer(Runnable task) { 70 | return st -> task.run(); 71 | } 72 | 73 | private static long toMilli(long ticks) { 74 | return ticks * 50L; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/task/Runner.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.task; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public interface Runner { 7 | 8 | void runPlayer(@NotNull Runnable task, @NotNull Player player); 9 | 10 | void run(@NotNull Runnable task); 11 | 12 | void runAsync(@NotNull Runnable task); 13 | 14 | void runDelayed(@NotNull Runnable task, long delayTicks); 15 | 16 | void runDelayedAsync(@NotNull Runnable task, long delayTicks); 17 | 18 | void runPeriodical(@NotNull Runnable task, long delayTicks, long periodTicks); 19 | 20 | void runPeriodicalAsync(@NotNull Runnable task, long delayTicks, long periodTicks); 21 | 22 | void cancelTasks(); 23 | } 24 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/task/TaskManager.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.task; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.boss.BossBar; 5 | import org.bukkit.configuration.file.FileConfiguration; 6 | import org.bukkit.entity.Player; 7 | import ru.overwrite.protect.bukkit.PasswordHandler; 8 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 9 | import ru.overwrite.protect.bukkit.api.CaptureReason; 10 | import ru.overwrite.protect.bukkit.api.ServerProtectorAPI; 11 | import ru.overwrite.protect.bukkit.api.events.ServerProtectorCaptureEvent; 12 | import ru.overwrite.protect.bukkit.configuration.Config; 13 | import ru.overwrite.protect.bukkit.configuration.data.BossbarSettings; 14 | import ru.overwrite.protect.bukkit.utils.Utils; 15 | 16 | import java.time.LocalDateTime; 17 | import java.util.Map; 18 | 19 | public final class TaskManager { 20 | 21 | private final ServerProtectorManager plugin; 22 | private final ServerProtectorAPI api; 23 | private final PasswordHandler passwordHandler; 24 | private final Config pluginConfig; 25 | private final Runner runner; 26 | 27 | public TaskManager(ServerProtectorManager plugin) { 28 | this.plugin = plugin; 29 | this.api = plugin.getApi(); 30 | this.passwordHandler = plugin.getPasswordHandler(); 31 | this.pluginConfig = plugin.getPluginConfig(); 32 | this.runner = plugin.getRunner(); 33 | } 34 | 35 | public void startMainCheck(long interval) { 36 | runner.runPeriodicalAsync(() -> { 37 | if (Bukkit.getOnlinePlayers().isEmpty()) { 38 | return; 39 | } 40 | for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { 41 | if (plugin.isExcluded(onlinePlayer, pluginConfig.getExcludedPlayers().adminPass())) { 42 | continue; 43 | } 44 | if (api.isCaptured(onlinePlayer)) { 45 | continue; 46 | } 47 | CaptureReason captureReason = plugin.checkPermissions(onlinePlayer); 48 | if (captureReason == null) { 49 | continue; 50 | } 51 | if (!api.isAuthorised(onlinePlayer)) { 52 | ServerProtectorCaptureEvent captureEvent = new ServerProtectorCaptureEvent(onlinePlayer, Utils.getIp(onlinePlayer), captureReason); 53 | captureEvent.callEvent(); 54 | if (pluginConfig.getApiSettings().allowCancelCaptureEvent() && captureEvent.isCancelled()) { 55 | continue; 56 | } 57 | api.capturePlayer(onlinePlayer); 58 | if (pluginConfig.getSoundSettings().enableSounds()) { 59 | Utils.sendSound(pluginConfig.getSoundSettings().onCapture(), onlinePlayer); 60 | } 61 | if (pluginConfig.getEffectSettings().enableEffects()) { 62 | plugin.giveEffects(onlinePlayer); 63 | } 64 | plugin.applyHide(onlinePlayer); 65 | if (pluginConfig.getLoggingSettings().loggingPas()) { 66 | plugin.logAction(pluginConfig.getLogMessages().captured(), onlinePlayer, LocalDateTime.now()); 67 | } 68 | if (pluginConfig.getBroadcasts() != null) { 69 | plugin.sendAlert(onlinePlayer, pluginConfig.getBroadcasts().captured()); 70 | } 71 | } 72 | } 73 | }, 20L, interval >= 0 ? interval : 40L); 74 | } 75 | 76 | public void startAdminCheck() { 77 | runner.runPeriodicalAsync(() -> { 78 | if (!api.isAnybodyCaptured()) { 79 | return; 80 | } 81 | for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { 82 | if (api.isCaptured(onlinePlayer) && !plugin.isAdmin(onlinePlayer.getName())) { 83 | plugin.checkFail(onlinePlayer.getName(), pluginConfig.getCommands().notInConfig()); 84 | } 85 | } 86 | }, 5L, 20L); 87 | } 88 | 89 | public void startCapturesMessages(FileConfiguration config) { 90 | runner.runPeriodicalAsync(() -> { 91 | if (!api.isAnybodyCaptured()) { 92 | return; 93 | } 94 | for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { 95 | if (api.isCaptured(onlinePlayer)) { 96 | onlinePlayer.sendMessage(pluginConfig.getMessages().message()); 97 | if (pluginConfig.getMessageSettings().sendTitle()) { 98 | Utils.sendTitleMessage(pluginConfig.getTitles().message(), onlinePlayer); 99 | } 100 | } 101 | } 102 | }, 5L, config.getInt("message-settings.delay") * 20L); 103 | } 104 | 105 | public void startOpCheck() { 106 | runner.runPeriodicalAsync(() -> { 107 | if (Bukkit.getOnlinePlayers().isEmpty()) { 108 | return; 109 | } 110 | for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { 111 | if (onlinePlayer.isOp() 112 | && !pluginConfig.getAccessData().opWhitelist().contains(onlinePlayer.getName()) 113 | && !plugin.isExcluded(onlinePlayer, pluginConfig.getExcludedPlayers().opWhitelist())) { 114 | plugin.checkFail(onlinePlayer.getName(), pluginConfig.getCommands().notInOpWhitelist()); 115 | } 116 | } 117 | }, 5L, 20L); 118 | } 119 | 120 | public void startPermsCheck() { 121 | runner.runPeriodicalAsync(() -> { 122 | if (Bukkit.getOnlinePlayers().isEmpty()) { 123 | return; 124 | } 125 | for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { 126 | for (String blacklistedPerm : pluginConfig.getAccessData().blacklistedPerms()) { 127 | if (onlinePlayer.hasPermission(blacklistedPerm) && 128 | !plugin.isExcluded(onlinePlayer, pluginConfig.getExcludedPlayers().blacklistedPerms())) { 129 | plugin.checkFail(onlinePlayer.getName(), pluginConfig.getCommands().haveBlacklistedPerm()); 130 | } 131 | } 132 | } 133 | }, 5L, 20L); 134 | } 135 | 136 | public void startCapturesTimer() { 137 | runner.runPeriodicalAsync(() -> { 138 | if (!api.isAnybodyCaptured()) { 139 | return; 140 | } 141 | BossbarSettings bossbarSettings = pluginConfig.getBossbarSettings(); 142 | int time = pluginConfig.getPunishSettings().time(); 143 | for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { 144 | if (onlinePlayer.isDead() || !api.isCaptured(onlinePlayer)) { 145 | return; 146 | } 147 | String playerName = onlinePlayer.getName(); 148 | Map perPlayerTime = plugin.getPerPlayerTime(); 149 | if (!perPlayerTime.containsKey(playerName)) { 150 | perPlayerTime.put(playerName, 0); 151 | if (bossbarSettings.enableBossbar()) { 152 | BossBar bossbar = Bukkit.createBossBar( 153 | bossbarSettings.bossbarMessage().replace("%time%", Integer.toString(time)), 154 | bossbarSettings.barColor(), 155 | bossbarSettings.barStyle()); 156 | bossbar.addPlayer(onlinePlayer); 157 | passwordHandler.getBossbars().put(playerName, bossbar); 158 | } 159 | } else { 160 | int newTime = perPlayerTime.compute(playerName, (k, currentTime) -> currentTime + 1); 161 | BossBar bossBar = passwordHandler.getBossbars().get(playerName); 162 | if (bossbarSettings.enableBossbar() && bossBar != null) { 163 | bossBar.setTitle(bossbarSettings.bossbarMessage().replace("%time%", Integer.toString(time - newTime))); 164 | double percents = (time - newTime) 165 | / (double) time; 166 | if (percents > 0) { 167 | bossBar.setProgress(percents); 168 | bossBar.addPlayer(onlinePlayer); 169 | } 170 | } 171 | if (time - newTime <= 0) { 172 | plugin.checkFail(playerName, pluginConfig.getCommands().failedTime()); 173 | passwordHandler.getBossbars().get(playerName).removePlayer(onlinePlayer); 174 | } 175 | } 176 | } 177 | }, 5L, 20L); 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/utils/PAPIUtils.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.utils; 2 | 3 | import lombok.experimental.UtilityClass; 4 | import me.clip.placeholderapi.PlaceholderAPI; 5 | import org.bukkit.entity.Player; 6 | 7 | @UtilityClass 8 | public class PAPIUtils { 9 | 10 | public String parsePlaceholders(Player player, String message) { 11 | return Utils.COLORIZER.colorize(PlaceholderAPI.setPlaceholders(player, message)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/utils/PluginMessage.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.utils; 2 | 3 | import com.google.common.io.ByteArrayDataInput; 4 | import com.google.common.io.ByteArrayDataOutput; 5 | import com.google.common.io.ByteStreams; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.plugin.messaging.PluginMessageListener; 9 | import org.jetbrains.annotations.NotNull; 10 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 11 | 12 | public final class PluginMessage implements PluginMessageListener { 13 | 14 | private final ServerProtectorManager plugin; 15 | 16 | public PluginMessage(ServerProtectorManager plugin) { 17 | this.plugin = plugin; 18 | } 19 | 20 | @Override 21 | public void onPluginMessageReceived(String channel, @NotNull Player player, byte[] message) { 22 | if (!channel.equals("BungeeCord")) 23 | return; 24 | ByteArrayDataInput input = ByteStreams.newDataInput(message); 25 | String subchannel = input.readUTF(); 26 | if (subchannel.equalsIgnoreCase("serverprotector")) { 27 | String msg = input.readUTF(); 28 | for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { 29 | if (onlinePlayer.hasPermission("serverprotector.admin")) { 30 | onlinePlayer.sendMessage(msg); 31 | } 32 | } 33 | } 34 | } 35 | 36 | public void sendCrossProxy(Player player, String message) { 37 | ByteArrayDataOutput out = ByteStreams.newDataOutput(); 38 | out.writeUTF("Forward"); 39 | out.writeUTF("ALL"); 40 | out.writeUTF("serverprotector"); 41 | out.writeUTF(message); 42 | player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray()); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.utils; 2 | 3 | import lombok.experimental.UtilityClass; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.Sound; 6 | import org.bukkit.configuration.ConfigurationSection; 7 | import org.bukkit.entity.Player; 8 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 9 | import ru.overwrite.protect.bukkit.utils.color.*; 10 | 11 | import java.io.BufferedReader; 12 | import java.io.IOException; 13 | import java.io.InputStreamReader; 14 | import java.net.URL; 15 | import java.nio.charset.StandardCharsets; 16 | import java.security.MessageDigest; 17 | import java.security.NoSuchAlgorithmException; 18 | import java.security.SecureRandom; 19 | import java.util.Arrays; 20 | import java.util.Base64; 21 | import java.util.List; 22 | import java.util.Set; 23 | import java.util.function.Consumer; 24 | 25 | @UtilityClass 26 | public class Utils { 27 | 28 | public final int SUB_VERSION = Integer.parseInt(Bukkit.getBukkitVersion().split("-")[0].split("\\.")[1]); 29 | 30 | public final boolean FOLIA; 31 | 32 | static { 33 | boolean folia; 34 | try { 35 | Class.forName("io.papermc.paper.threadedregions.scheduler.AsyncScheduler"); 36 | folia = true; 37 | } catch (ClassNotFoundException e) { 38 | folia = false; 39 | } 40 | FOLIA = folia; 41 | } 42 | 43 | public Colorizer COLORIZER; 44 | 45 | public void setupColorizer(ConfigurationSection mainSettings) { 46 | COLORIZER = switch (mainSettings.getString("serializer", "LEGACY").toUpperCase()) { 47 | case "MINIMESSAGE" -> new MiniMessageColorizer(); 48 | case "LEGACY" -> SUB_VERSION >= 16 ? new LegacyColorizer() : new VanillaColorizer(); 49 | case "LEGACY_ADVANCED" -> new LegacyAdvancedColorizer(); 50 | default -> new VanillaColorizer(); 51 | }; 52 | } 53 | 54 | public String getIp(Player player) { 55 | return player.getAddress().getAddress().getHostAddress(); 56 | } 57 | 58 | public void sendTitleMessage(String[] titleMessages, Player player) { 59 | if (titleMessages[0].isEmpty()) { 60 | return; 61 | } 62 | if (titleMessages.length > 5) { 63 | Bukkit.getConsoleSender().sendMessage("Unable to send title. " + Arrays.toString(titleMessages)); 64 | return; 65 | } 66 | String title = titleMessages[0]; 67 | String subtitle = titleMessages.length >= 2 ? titleMessages[1] : ""; 68 | int fadeIn = titleMessages.length >= 3 ? Integer.parseInt(titleMessages[2]) : 10; 69 | int stay = titleMessages.length >= 4 ? Integer.parseInt(titleMessages[3]) : 70; 70 | int fadeOut = titleMessages.length == 5 ? Integer.parseInt(titleMessages[4]) : 20; 71 | player.sendTitle(title, subtitle, fadeIn, stay, fadeOut); 72 | } 73 | 74 | public void sendSound(String[] soundArgs, Player player) { 75 | if (soundArgs[0].isEmpty()) { 76 | return; 77 | } 78 | if (soundArgs.length > 3) { 79 | Bukkit.getConsoleSender().sendMessage("Unable to send sound. " + Arrays.toString(soundArgs)); 80 | return; 81 | } 82 | Sound sound = Sound.valueOf(soundArgs[0]); 83 | float volume = soundArgs.length >= 2 ? Float.parseFloat(soundArgs[1]) : 1.0f; 84 | float pitch = soundArgs.length == 3 ? Float.parseFloat(soundArgs[2]) : 1.0f; 85 | player.playSound(player.getLocation(), sound, volume, pitch); 86 | } 87 | 88 | public final char COLOR_CHAR = '§'; 89 | 90 | public String translateAlternateColorCodes(char altColorChar, String textToTranslate) { 91 | final char[] b = textToTranslate.toCharArray(); 92 | 93 | for (int i = 0, length = b.length - 1; i < length; ++i) { 94 | if (b[i] == altColorChar && isValidColorCharacter(b[i + 1])) { 95 | b[i++] = COLOR_CHAR; 96 | b[i] |= 0x20; 97 | } 98 | } 99 | 100 | return new String(b); 101 | } 102 | 103 | private boolean isValidColorCharacter(char c) { 104 | return switch (c) { 105 | case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 106 | 'E', 'F', 'r', 'R', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N', 'o', 'O', 'x', 'X' -> true; 107 | default -> false; 108 | }; 109 | } 110 | 111 | public void checkUpdates(ServerProtectorManager plugin, Consumer consumer) { 112 | plugin.getRunner().runDelayedAsync(() -> { 113 | try (BufferedReader reader = new BufferedReader(new InputStreamReader( 114 | new URL("https://raw.githubusercontent.com/Overwrite987/UltimateServerProtector/master/VERSION") 115 | .openStream()))) { 116 | consumer.accept(reader.readLine().trim()); 117 | } catch (IOException ex) { 118 | plugin.getPluginLogger().warn("Unable to check for updates: " + ex.getMessage()); 119 | } 120 | }, 10); 121 | } 122 | 123 | private final Set SUPPORTED_HASH_TYPES = 124 | Set.of("SHA224", "SHA256", "SHA384", "SHA512", "SHA-224", "SHA-256", "SHA-384", "SHA-512", "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512"); 125 | 126 | public String encryptPassword(String password, String salt, List hashTypes) { 127 | if (hashTypes.isEmpty()) { 128 | return password; 129 | } 130 | String encryptedPassword = password; 131 | boolean salted = false; 132 | for (String hashType : hashTypes) { 133 | switch (hashType.toUpperCase()) { 134 | case "BASE64": { 135 | encryptedPassword = encodeToBase64(encryptedPassword); 136 | break; 137 | } 138 | case "SALT": { 139 | if (salted) { 140 | break; 141 | } 142 | encryptedPassword = salt + encryptedPassword; 143 | salted = true; 144 | break; 145 | } 146 | default: { 147 | if (SUPPORTED_HASH_TYPES.contains(hashType.toUpperCase())) { 148 | encryptedPassword = encryptToHash(encryptedPassword, hashType); 149 | } else { 150 | throw new IllegalArgumentException("Unsupported hash type: " + hashType); 151 | } 152 | } 153 | } 154 | } 155 | return salted ? salt + ":" + encryptedPassword : encryptedPassword; 156 | } 157 | 158 | private final SecureRandom random = new SecureRandom(); 159 | 160 | public String generateSalt(int length) { 161 | byte[] saltBytes = new byte[(int) Math.ceil((double) length * 3 / 4)]; 162 | random.nextBytes(saltBytes); 163 | return Base64.getEncoder().encodeToString(saltBytes); 164 | } 165 | 166 | private String encodeToBase64(String str) { 167 | return Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8)); 168 | } 169 | 170 | private String encryptToHash(String str, String algorithm) { 171 | try { 172 | MessageDigest digest = MessageDigest.getInstance(algorithm); 173 | byte[] hash = digest.digest(str.getBytes(StandardCharsets.UTF_8)); 174 | return bytesToHexString(hash); 175 | } catch (NoSuchAlgorithmException ex) { 176 | ex.printStackTrace(); 177 | return str; 178 | } 179 | } 180 | 181 | private String bytesToHexString(byte[] bytes) { 182 | StringBuilder hexString = new StringBuilder(); 183 | for (byte b : bytes) { 184 | String hex = Integer.toHexString(0xff & b); 185 | if (hex.length() == 1) hexString.append('0'); 186 | hexString.append(hex); 187 | } 188 | return hexString.toString(); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/utils/color/Colorizer.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.utils.color; 2 | 3 | public interface Colorizer { 4 | 5 | String colorize(String message); 6 | } 7 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/utils/color/LegacyAdvancedColorizer.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.utils.color; 2 | 3 | import ru.overwrite.protect.bukkit.utils.Utils; 4 | 5 | public class LegacyAdvancedColorizer implements Colorizer { 6 | 7 | @Override 8 | public String colorize(String message) { 9 | if (message == null || message.isEmpty()) { 10 | return message; 11 | } 12 | final StringBuilder builder = new StringBuilder(); 13 | final char[] messageChars = message.toCharArray(); 14 | boolean isColor = false, isHashtag = false, isDoubleTag = false; 15 | 16 | for (int index = 0; index < messageChars.length; ) { 17 | final char currentChar = messageChars[index]; 18 | 19 | if (isDoubleTag) { 20 | isDoubleTag = false; 21 | if (processDoubleTag(builder, messageChars, index)) { 22 | index += 3; 23 | continue; 24 | } 25 | builder.append("&##"); 26 | } else if (isHashtag) { 27 | isHashtag = false; 28 | if (currentChar == '#') { 29 | isDoubleTag = true; 30 | index++; 31 | continue; 32 | } 33 | if (processSingleTag(builder, messageChars, index)) { 34 | index += 6; 35 | continue; 36 | } 37 | builder.append("&#"); 38 | } else if (isColor) { 39 | isColor = false; 40 | if (currentChar == '#') { 41 | isHashtag = true; 42 | index++; 43 | continue; 44 | } 45 | if (isValidColorCharacter(currentChar)) { 46 | builder.append(Utils.COLOR_CHAR).append(currentChar); 47 | index++; 48 | continue; 49 | } 50 | builder.append('&'); 51 | } else if (currentChar == '&') { 52 | isColor = true; 53 | index++; 54 | } else { 55 | builder.append(currentChar); 56 | index++; 57 | } 58 | } 59 | 60 | appendRemainingColorTags(builder, isColor, isHashtag, isDoubleTag); 61 | return builder.toString(); 62 | } 63 | 64 | private boolean processDoubleTag(StringBuilder builder, char[] messageChars, int index) { 65 | if (index + 3 <= messageChars.length && isValidHexCode(messageChars, index, 3)) { 66 | builder.append(Utils.COLOR_CHAR).append('x'); 67 | for (int i = index; i < index + 3; i++) { 68 | builder.append(Utils.COLOR_CHAR).append(messageChars[i]).append(Utils.COLOR_CHAR).append(messageChars[i]); 69 | } 70 | return true; 71 | } 72 | return false; 73 | } 74 | 75 | private boolean processSingleTag(StringBuilder builder, char[] messageChars, int index) { 76 | if (index + 6 <= messageChars.length && isValidHexCode(messageChars, index, 6)) { 77 | builder.append(Utils.COLOR_CHAR).append('x'); 78 | for (int i = index; i < index + 6; i++) { 79 | builder.append(Utils.COLOR_CHAR).append(messageChars[i]); 80 | } 81 | return true; 82 | } 83 | return false; 84 | } 85 | 86 | private static final boolean[] HEX_CHARS = new boolean[128]; 87 | 88 | static { 89 | for (char c = '0'; c <= '9'; c++) { 90 | HEX_CHARS[c] = true; 91 | } 92 | for (char c = 'a'; c <= 'f'; c++) { 93 | HEX_CHARS[c] = true; 94 | } 95 | for (char c = 'A'; c <= 'F'; c++) { 96 | HEX_CHARS[c] = true; 97 | } 98 | } 99 | 100 | public boolean isValidHexCode(char[] chars, int start, int length) { 101 | int end = start + length; 102 | for (int i = start; i < end; i++) { 103 | char c = chars[i]; 104 | if (!HEX_CHARS[c]) { 105 | return false; 106 | } 107 | } 108 | return true; 109 | } 110 | 111 | private static final boolean[] COLOR_CHARS_FLAGS = new boolean[128]; 112 | 113 | static { 114 | for (char c = '0'; c <= '9'; c++) { 115 | COLOR_CHARS_FLAGS[c] = true; 116 | } 117 | 118 | for (char c = 'a'; c <= 'f'; c++) { 119 | COLOR_CHARS_FLAGS[c] = true; 120 | } 121 | 122 | for (char c = 'A'; c <= 'F'; c++) { 123 | COLOR_CHARS_FLAGS[c] = true; 124 | } 125 | 126 | int[] specialSymbols = { 127 | 'r', 'R', 128 | 'k', 'l', 'm', 'n', 'o', 129 | 'K', 'L', 'M', 'N', 'O' 130 | }; 131 | 132 | for (int sym : specialSymbols) { 133 | COLOR_CHARS_FLAGS[sym] = true; 134 | } 135 | } 136 | 137 | public static boolean isValidColorCharacter(char c) { 138 | return COLOR_CHARS_FLAGS[c]; 139 | } 140 | 141 | private void appendRemainingColorTags(StringBuilder builder, boolean isColor, boolean isHashtag, boolean isDoubleTag) { 142 | if (isColor) { 143 | builder.append('&'); 144 | } else if (isHashtag) { 145 | builder.append("&#"); 146 | } else if (isDoubleTag) { 147 | builder.append("&##"); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/utils/color/LegacyColorizer.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.utils.color; 2 | 3 | import ru.overwrite.protect.bukkit.utils.Utils; 4 | 5 | import java.util.regex.Matcher; 6 | import java.util.regex.Pattern; 7 | 8 | public class LegacyColorizer implements Colorizer { 9 | 10 | private static final Pattern HEX_PATTERN = Pattern.compile("&#([a-fA-F\\d]{6})"); 11 | 12 | @Override 13 | public String colorize(String message) { 14 | if (message == null || message.isEmpty()) { 15 | return message; 16 | } 17 | final Matcher matcher = HEX_PATTERN.matcher(message); 18 | final StringBuilder builder = new StringBuilder(message.length() + 32); 19 | while (matcher.find()) { 20 | String group = matcher.group(1); 21 | matcher.appendReplacement(builder, 22 | Utils.COLOR_CHAR + "x" + 23 | Utils.COLOR_CHAR + group.charAt(0) + 24 | Utils.COLOR_CHAR + group.charAt(1) + 25 | Utils.COLOR_CHAR + group.charAt(2) + 26 | Utils.COLOR_CHAR + group.charAt(3) + 27 | Utils.COLOR_CHAR + group.charAt(4) + 28 | Utils.COLOR_CHAR + group.charAt(5)); 29 | } 30 | message = matcher.appendTail(builder).toString(); 31 | return Utils.translateAlternateColorCodes('&', message); 32 | } 33 | } -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/utils/color/MiniMessageColorizer.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.utils.color; 2 | 3 | import net.kyori.adventure.text.Component; 4 | import net.kyori.adventure.text.minimessage.MiniMessage; 5 | import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; 6 | 7 | public class MiniMessageColorizer implements Colorizer { 8 | 9 | @Override 10 | public String colorize(String message) { 11 | if (message == null || message.isEmpty()) { 12 | return message; 13 | } 14 | Component component = MiniMessage.miniMessage().deserialize(message); 15 | return LegacyComponentSerializer.legacySection().serialize(component); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/utils/color/VanillaColorizer.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.utils.color; 2 | 3 | import ru.overwrite.protect.bukkit.utils.Utils; 4 | 5 | public class VanillaColorizer implements Colorizer { 6 | 7 | @Override 8 | public String colorize(String message) { 9 | if (message == null || message.isEmpty()) { 10 | return message; 11 | } 12 | return Utils.translateAlternateColorCodes('&', message); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/utils/logging/BukkitLogger.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.utils.logging; 2 | 3 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 4 | 5 | public class BukkitLogger implements Logger { 6 | 7 | private final ServerProtectorManager plugin; 8 | 9 | public BukkitLogger(ServerProtectorManager plugin) { 10 | this.plugin = plugin; 11 | } 12 | 13 | @Override 14 | public void info(String msg) { 15 | plugin.getLogger().info(msg); 16 | } 17 | 18 | @Override 19 | public void warn(String msg) { 20 | plugin.getLogger().warning(msg); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/utils/logging/Logger.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.utils.logging; 2 | 3 | public interface Logger { 4 | 5 | void info(String msg); 6 | 7 | void warn(String msg); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ru/overwrite/protect/bukkit/utils/logging/PaperLogger.java: -------------------------------------------------------------------------------- 1 | package ru.overwrite.protect.bukkit.utils.logging; 2 | 3 | import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; 4 | import ru.overwrite.protect.bukkit.ServerProtectorManager; 5 | 6 | public class PaperLogger implements Logger { 7 | 8 | private final ServerProtectorManager plugin; 9 | 10 | private final LegacyComponentSerializer legacySection = LegacyComponentSerializer.legacySection(); 11 | 12 | public PaperLogger(ServerProtectorManager plugin) { 13 | this.plugin = plugin; 14 | } 15 | 16 | @Override 17 | public void info(String msg) { 18 | plugin.getComponentLogger().info(legacySection.deserialize(msg)); 19 | } 20 | 21 | @Override 22 | public void warn(String msg) { 23 | plugin.getComponentLogger().warn(legacySection.deserialize(msg)); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /bukkit/src/main/resources-common/plugin.yml: -------------------------------------------------------------------------------- 1 | name: '${project.name}' 2 | version: '${project.version}' 3 | author: OverwriteMC 4 | main: ru.overwrite.protect.bukkit.ServerProtector 5 | api-version: 1.13 6 | folia-supported: true 7 | load-priority: STARTUP 8 | loadafter: [LuckPerms, BungeeGuard] 9 | softdepend: [PlaceholderAPI] 10 | commands: 11 | ultimateserverprotector: 12 | aliases: [usp, serverprotector] 13 | permissions: 14 | serverprotector.admin: 15 | children: 16 | serverprotector.reload: true 17 | serverprotector.reboot: true 18 | serverprotector.encrypt: true 19 | serverprotector.setpass: true 20 | serverprotector.addop: true 21 | serverprotector.addip: true 22 | serverprotector.rempass: true 23 | serverprotector.remop: true 24 | serverprotector.remip: true -------------------------------------------------------------------------------- /bukkit/src/main/resources-en/config.yml: -------------------------------------------------------------------------------- 1 | # Main settings 2 | main-settings: 3 | # Text formatting. 4 | # LEGACY - color using & and hex &# 5 | # LEGACY_ADVANCED - an improved version of LEGACY with support for &## hex format 6 | # MINIMESSAGE - color using (introduced in newer versions (1.17+)) 7 | serializer: LEGACY 8 | # If set to true - messages will be broadcasted to all servers on the proxy network. 9 | proxy: false 10 | # Plugin prefix 11 | prefix: '&f&l[&c&lProtection&f&l]' 12 | # If set to false, players need to type the password in the chat 13 | use-command: true 14 | # Password input command. (specified without / at the beginning) (default - pas) (command is not going to be registered on Spigot) 15 | pas-command: 'pas' 16 | # Enable commands for adding new players to the config 17 | enable-admin-commands: false 18 | # Send anonymous statistics (advised not to disable) 19 | enable-metrics: true 20 | # Check for updates (advised not to disable) 21 | update-checker: true 22 | # Main check interval in ticks (do not touch if you don't know how it works) 23 | check-interval: 40 24 | # Should PlaceholderAPI be supported in plugin messages? 25 | # Applies only to messages involving a player 26 | papi-support: false 27 | # Should we suppress API warnings? 28 | # This will disable all warnings from API if something went wrong 29 | # Only change this if you know what you're doing! 30 | suppress-api-warnings: false 31 | 32 | # Encryption settings 33 | encryption-settings: 34 | # Whether to enable encryption 35 | # When encryption is enabled, the password in data.yml must be specified in an already encrypted format and in a separate field encrypted-pass: 36 | # To see what the password will look like in encrypted form, you can use the command /usp encrypt 37 | # However, if the auto-encrypt-passwords option is enabled, you can specify a regular password in the old pass: format in data.yml, and the plugin will automatically convert it. 38 | enable-encryption: false 39 | # Password encryption method (Supported types: BASE64, SHA224, SHA256, SHA384, SHA512, SHA3-224, SHA3-256, SHA3-384, SHA3-512) 40 | # BASE64 - This "encryption" does not provide data protection; it is simply a method of converting data to another format for network transmission or storage. 41 | # Use BASE64 only if you're afraid of "accidentally showing the file with passwords on the demo" and you don't need to specifically hide the data or to make encryption more complicated 42 | # SHA256 and other SHA - variations of the SHA algorithm. 43 | # Use SHA256 if you want to securely hide passwords without the possibility of decryption, and SHA512 for even more effective encryption 44 | # SHA3-256 and other SHA3 - an analogue of the usual SHA with a modified encryption algorithm. 45 | # Use SHA3 if you want to make non-standard and at the same time strong encryption 46 | # You can use 2 or more encryption methods simultaneously for greater security of your passwords, so they cannot be easily brute-forced 47 | # Encryption will be performed in order 1;2;3 and so on. It's important - deep encryption can take a lot of time, so don't use too many of them 48 | # SALT is used to apply salt (random string to an existing password). You can only apply it once. 49 | encrypt-method: 'BASE64;SALT;SHA256' 50 | # If you used any encryption method and for some reason decide to change it - you can specify it here so that you don't lose data 51 | old-encrypt-methods: [] 52 | # The length of the dynamically generated salt. The longer it is, the more effectively passwords are protected. 53 | salt-length: 24 54 | # Enable automatic encryption of all existing passwords from the data.yml file when the plugin starts and restarts 55 | # This function will automatically convert all passwords from the pass: format to the encrypted-pass: format, encrypting the existing passwords 56 | # If there is a lot of data in the file, automatic encryption can take a long time! Disable it in case of problems. 57 | auto-encrypt-passwords: true 58 | 59 | # File settings 60 | file-settings: 61 | # Players data file name. (default - data.yml) 62 | data-file: 'data.yml' 63 | # Log file name. (default - log.yml) 64 | log-file: 'log.yml' 65 | # If this setting is enabled, you need to specify the full path to the file 66 | # Example: root/server/plugins/UltimateServerProtector/data.yml 67 | use-full-path: false 68 | # Path to the data.yml file 69 | data-file-path: '/root/server/plugins/UltimateServerProtector/' 70 | # Path to the log.yml file 71 | log-file-path: '/root/server/plugins/UltimateServerProtector/' 72 | 73 | # Customization for floodgate + geyser users (with special characters) 74 | geyser-settings: 75 | # The symbol that all players from the hip (put '' if there is no symbol, then the check will be disabled) 76 | geyser-prefix: '.' 77 | # Nicknames of players who are players from Bedrock (if this nickname is recorded in data.yml, a symbol will be automatically added to it during password verification) 78 | geyser-nicknames: 79 | - 'test99999' 80 | 81 | # Additional blocking settings 82 | blocking-settings: 83 | # Block item dropping 84 | block-item-drop: true 85 | # Block item pickup 86 | block-item-pickup: true 87 | # Block tab-complete (works against /ver + tab) 88 | block-tab-complete: true 89 | # Make the player invulnerable during password input 90 | block-damage: true 91 | # Block the ability to cause damage to mobs and players during password input 92 | block-damaging-entity: true 93 | # Block the ability to open inventories during password input (menus, etc.) 94 | block-inventory-open: false 95 | # Whether to hide the player from the tab list when entering a password 96 | hide-on-entering: true 97 | # Whether to hide other players from the person entering the password 98 | hide-other-on-entering: true 99 | # Whether to allow you to move camera while entering a password 100 | allow-orientation-change: false 101 | 102 | # Session settings 103 | session-settings: 104 | # Save player data so they don't have to enter the admin password again 105 | session: true 106 | # Delete player data after some time 107 | session-time-enabled: false 108 | # Time after which data about a registered player will be deleted in seconds (countdown starts from the password input moment) 109 | session-time: 21600 #(6 hours) 110 | 111 | # Punishment settings 112 | punish-settings: 113 | # Enable punishments for incorrectly entered admin password 114 | enable-attempts: true 115 | # Maximum number of admin password entry attempts 116 | max-attempts: 3 117 | # Enable time for entering admin password 118 | enable-time: true 119 | # Time in seconds within which the player must enter the admin password 120 | time: 60 121 | # Enable punishments for rejoin to the server if a player exits without entering the admin password 122 | enable-rejoin: true 123 | # Maximum number of rejoins to the server if a player exits without entering correct admin password 124 | max-rejoins: 3 125 | 126 | # Enhanced security settings 127 | secure-settings: 128 | # Apply punishments to operators not listed in the whitelist 129 | enable-op-whitelist: false 130 | # Apply punishments to those who have admin rights but are not in the config 131 | enable-notadmin-punish: false 132 | # Apply punishments to people with forbidden permissions 133 | enable-permission-blacklist: false 134 | # Enable IPWhitelist for administrators 135 | enable-ip-whitelist: false 136 | # Allow using the /usp command only from the console 137 | only-console-usp: false 138 | # Shutdown the server if the plugin is disabled 139 | shutdown-on-disable: true 140 | # Allow certain players to enter the game without an admin password (disabled by default and unsafe) 141 | enable-excluded-players: false 142 | 143 | # Api settings 144 | api-settings: 145 | # Whether to allow canceling ServerProtectorCaptureEvent? (Disabled by default for security reasons) 146 | allow-cancel-capture-event: false 147 | # Should ServerProtectorPasswordEnterEvent be triggered when the player enters a password? (Disabled by default for security reasons) 148 | call-event-on-password-enter: false 149 | # From which packages is the invocation of authorization methods allowed from the API? 150 | # Calls to API methods from other packages will be blocked. (By default, only calls from our plugin are allowed) 151 | allowed-auth-api-calls-packages: [] 152 | 153 | # Message display settings 154 | message-settings: 155 | # Delay between auto-messages and titles in seconds 156 | delay: 2 157 | # Enable full-screen messages 158 | send-titles: true 159 | # Enable notifications for administrators 160 | enable-broadcasts: true 161 | # Enable notifications for the console 162 | enable-console-broadcasts: true 163 | 164 | # Bossbar settings (only works if login time is enabled) 165 | bossbar-settings: 166 | # Enable bossbar 167 | enable-bossbar: true 168 | # Bossbar color (PINK, BLUE, RED, GREEN, YELLOW, PURPLE, WHITE) 169 | bar-color: RED 170 | # Bossbar type (SOLID, SEGMENTED_6, SEGMENTED_10, SEGMENTED_12, SEGMENTED_20) 171 | bar-style: SEGMENTED_12 172 | 173 | # Sound settings for commands/actions 174 | sound-settings: 175 | # Enable sounds for commands 176 | enable-sounds: true 177 | # Sound when capturing an admin with permissions (SOUND:VOLUME:PITCH) 178 | on-capture: ENTITY_ITEM_BREAK;1.0;1.0 179 | # Sound when incorrect password is entered 180 | on-pas-fail: ENTITY_VILLAGER_NO;1.0;1.0 181 | # Sound when correct password is entered 182 | on-pas-correct: ENTITY_PLAYER_LEVELUP;1.0;1.0 183 | 184 | # Effects settings applied before entering the password 185 | effect-settings: 186 | # Enable the effect that will be applied to the admin before entering the password 187 | enable-effects: true 188 | # Effects to apply to the player (EFFECT;LEVEL) 189 | effects: 190 | - 'BLINDNESS;3' 191 | 192 | # Logging settings 193 | logging-settings: 194 | # Log successful/unsuccessful password entry attempts to file 195 | logging-pas: true 196 | # Log player joins with admin rights to file 197 | logging-join: true 198 | # Log plugin enabling and disabling to file 199 | logging-enable-disable: true 200 | 201 | # Commands applied to offenders 202 | commands: 203 | 204 | # Commands applied to those with admin rights but not in the config 205 | not-in-config: 206 | - 'kick %player% You are not in the list of administrators!' 207 | - 'deop %player%' 208 | 209 | # Commands applied to those with admin rights but not listed in op-whitelist 210 | not-in-opwhitelist: 211 | - 'deop %player%' 212 | #- 'ban %player% You are not allowed to have operator rights!' 213 | 214 | # Commands applied to those with forbidden permissions (disabled by default) 215 | have-blacklisted-perm: 216 | - 'lp user %player% permission clear' 217 | #- 'ban %player% You are not allowed to have such permissions!' 218 | 219 | # Commands applied to those who entered with admin rights but have a non-admin IP (disabled by default) 220 | not-admin-ip: 221 | - 'kick %player% Your IP is not on the whitelist' 222 | #- 'deop %player%' 223 | 224 | # Commands applied to those who entered the wrong password within the allotted attempts 225 | failed-pass: 226 | - 'ban %player% You entered the admin password incorrectly, your account is frozen' 227 | - 'deop %player%' 228 | 229 | # Commands applied to those who failed to enter the password within the allotted time 230 | failed-time: 231 | - 'kick %player% You did not manage to enter the admin password within the given time' 232 | - 'deop %player%' 233 | 234 | # Commands that will be applied to those who have rejoined the server without entering the correct password too many times 235 | failed-rejoin: 236 | - 'ban %player% You have been rejoining the server too many times without entering the password' 237 | - 'deop %player%' 238 | 239 | # Permissions for which the player will need to enter the admin password (feel free to add your own!) 240 | permissions: 241 | - '*' 242 | - 'bukkit.*' 243 | - 'minecraft.*' 244 | - 'essentials.*' 245 | - 'cmi.*' 246 | - 'worldguard.*' 247 | - 'worldedit.*' 248 | - 'fawe.*' 249 | - 'permissions.*' 250 | - 'luckperms.*' 251 | - 'luckperms.editor' 252 | - 'luckperms.applyedits' 253 | - 'citizens.*' 254 | - 'citizenscmd.*' 255 | - 'znpcs.*' 256 | - 'holograms.*' 257 | - 'multiverse.*' 258 | - 'coreprotect.*' 259 | - 'mycommand.*' 260 | - 'towny.*' 261 | - 'matrix.*' 262 | - 'vulcan.*' 263 | - 'grim.*' 264 | - 'dh.admin' 265 | - 'ls.admin' 266 | - 'fawe.admin' 267 | - 'authme.admin' 268 | - 'nlogin.admin' 269 | - 'protocol.admin' 270 | - 'placeholderapi.admin' 271 | - 'playerpoints.*' 272 | - 'plugman.*' 273 | - 'plugman.admin' 274 | - 'plugman.download' 275 | - 'serverprotector.admin' 276 | 277 | # Permissions that no one except players from the excluded-players section can have (disabled by default.) 278 | blacklisted-perms: 279 | - '*' 280 | 281 | # Commands that can be entered before entering the admin password (specify with /) 282 | allowed-commands: 283 | - '/l' 284 | - '/login' 285 | - '/reg' 286 | - '/register' 287 | - '/captcha' 288 | 289 | # Which players are allowed to have OP rights 290 | op-whitelist: 291 | - Overwrite 292 | - test99999 293 | 294 | # From which IPs and which players are allowed to enter with admin rights 295 | # You can specify only part of the IP address to allow entry to people with dynamic IPs. For example, 1.2.3.4 -> 1.2.3.* 296 | ip-whitelist: 297 | # Player 1 298 | test99999: 299 | - 127.0.0.1 300 | - 0.0.0.0 301 | # Player 2 302 | test123123: 303 | - 228.13.37.* 304 | 305 | # Which players will be excluded from checks (each check has its own type) 306 | excluded-players: 307 | # Players who do not need to enter the admin password 308 | admin-pass: 309 | - test99999 310 | - test123123 311 | # Players who will not be checked for inclusion in op-whitelist 312 | op-whitelist: 313 | - test99999 314 | - test123123 315 | # Players who will not be checked for inclusion in ip-whitelist 316 | ip-whitelist: 317 | - test99999 318 | - test123123 319 | # Players who will be allowed to have blocked permissions 320 | blacklisted-perms: 321 | - test99999 322 | - test123123 -------------------------------------------------------------------------------- /bukkit/src/main/resources-en/data.yml: -------------------------------------------------------------------------------- 1 | # Unique passwords for admins 2 | data: 3 | Overwrite: # player 1 4 | pass: '123123' # player's 1 password 5 | test99999: # player 2 6 | pass: '321321' # player's 2 password -------------------------------------------------------------------------------- /bukkit/src/main/resources-en/message.yml: -------------------------------------------------------------------------------- 1 | # Messages that will be displayed to people when entering a command 2 | msg: 3 | message: "%prefix% &fAdmin permissiond detected! You should enter admin-password!" 4 | incorrect: "%prefix% &cWrong password!" 5 | correct: "%prefix% &aCorrect password. Have a nice day ;)" 6 | noneed: "%prefix% &fYou do not need to enter the admin password or it has already been entered." 7 | cantbenull: "%prefix% &fPassword cannot be empty." 8 | playeronly: "%prefix% &fOnly for players" 9 | 10 | # Admin broadcasts (%player% = player"s nick / %ip% = player"s IP) 11 | broadcasts: 12 | failed: "%prefix% &fAdmin &3%player% &fentered the password &cwrongly! &fIP: &c%ip%" 13 | passed: "%prefix% &fAdmin &3%player% &fentered the password &acorrectly! &fIP: &c%ip%" 14 | joined: "%prefix% &fAdmin &3%player% &fjoined the game! &fIP: &c%ip%" 15 | captured: "%prefix% &fPlayer &3%player% &fwas detected with admin-permissions! &fIP: &c%ip%" 16 | disabled: "%prefix% &6&lWARNING! &fPlugin has been disabled!" 17 | 18 | # Titles (format - title;subtitle;fadein;stay;fadeout) 19 | titles: 20 | message: '&e&l⚠ &c&lProtection &e&l⚠;&fAdmin permissiond detected! Enter admin-password!;10;60;15' 21 | incorrect: '&e&l⚠ &c&lProtection &e&l⚠;&cWrong password!;10;60;15' 22 | correct: '&e&l⚠ &c&lProtection &e&l⚠;&aCorrect password. Have a nice day;10;60;15' 23 | 24 | # Message in boss bar 25 | bossbar: 26 | message: "&fRemained: &c%time% seconds" 27 | 28 | # Message when using the /usp command (admin commands) 29 | uspmsg: 30 | consoleonly: '&cThis command can only be executed from the console!' 31 | playeronly: '&cThis command can only be executed by a player!' 32 | logout: '&aYour session has been reset.' 33 | reloaded: '&aPlugin reloaded.' 34 | rebooted: '&aPlugin rebooted.' 35 | playernotfound: '&cAccount %nick% not found in the system!' 36 | alreadyinconfig: '&aThis account is already in the config.' 37 | notinconfig: '&cThis account is not in the config.' 38 | playeradded: '&aPlayer %nick% successfully added.' 39 | playerremoved: '&aPlayer successfully removed.' 40 | ipadded: '&aIPs %ip% successfully added.' 41 | setpassusage: '&f/%cmd% setpass (nick) (password)' 42 | addopusage: '&f/%cmd% addop (nick)' 43 | addipusage: '&f/%cmd% addip (IPs)' 44 | rempassusage: '&f/%cmd% rempass (nick)' 45 | remopusage: '&f/%cmd% remop (nick)' 46 | remipusage: '&f/%cmd% rempip (IPs)' 47 | usage: '&7&l> &7Usage:' 48 | usage-logout: '&6/%cmd% logout&7 - end your session' 49 | usage-reload: '&6/%cmd% reload&7 - reload the config' 50 | usage-reboot: '&6/%cmd% reboot&7 - reboot the plugin' 51 | usage-encrypt: '&6/%cmd% encrypt (password)&7 - show encrypted version of the password' 52 | usage-setpass: '&6/%cmd% setpass (nick) (password) &7- set player password' 53 | usage-rempass: '&6/%cmd% rempass (nick) &7- remove player password' 54 | usage-addop: '&6/%cmd% addop (nick) &7- add player to op whitelist' 55 | usage-remop: '&6/%cmd% remop (nick) &7- remove player from op whitelist' 56 | usage-addip: '&6/%cmd% addip (nick) (IPs) &7- add player and their ip to ip whitelist' 57 | usage-remip: '&6/%cmd% remip (nick) (IPs) &7- remove player and their ip from ip whitelist' 58 | otherdisabled: |- 59 | &7Other commands are disabled. 60 | &7To enable them, set &6enable-admin-commands: &atrue 61 | 62 | # Log format 63 | log-format: 64 | enabled: "%date% [UltimateServerProtector - plugin enabled]" 65 | disabled: "%date% [UltimateServerProtector - plugin disabled]" 66 | failed: "%date% Admin %player% entered admin password incorrectly! IP: %ip%" 67 | passed: "%date% Admin %player% sucsessfully logged in! IP: %ip%" 68 | joined: "%date% Admin %player% joined the game. IP: %ip%" 69 | captured: "%date% Player %player% was detected with admin-permissions! IP: %ip%" 70 | command: "%date% Plugin executed command: %cmd%" 71 | 72 | # System messages 73 | system: 74 | baseline-warn: "§6============= §c! WARNING ! §6=============" 75 | baseline-default: "§6========================================" 76 | paper-1: "§eYou are using an unstable core for your MC server! It's recommended to use §aPaper" 77 | paper-2: "§eDownload Paper: §ahttps://papermc.io/downloads/all" 78 | bungeecord-1: "§eYou have the §6bungeecord setting §aenabled§e, but the §6BungeeGuard §eplugin is not installed!" 79 | bungeecord-2: "§eWithout this plugin, you are exposed to §csecurity risks! §eInstall it for further safe operation." 80 | bungeecord-3: "§eDownload BungeeGuard: §ahttps://www.spigotmc.org/resources/bungeeguard.79601/" 81 | update-latest: "§aYou are using latest version of the plugin!" 82 | update-success-1: "§aUpdate was downloaded successfully!" 83 | update-success-2: "§aRestart the server to apply the update." 84 | update-outdated-1: "§aYou are using outdated version of the plugin!" 85 | update-outdated-2: "§aYou can download new version here:" 86 | update-outdated-3: "§bgithub.com/Overwrite987/UltimateServerProtector/releases/" 87 | -------------------------------------------------------------------------------- /bukkit/src/main/resources-ru/config.yml: -------------------------------------------------------------------------------- 1 | # 2 | #▀██▀ ▀█▀ ▀██ ▄ ██ ▄ ▄█▀▀▀▄█ ▀██▀▀█▄ ▄ ▄ 3 | # ██ █ ██ ▄██▄ ▄▄▄ ▄▄ ▄▄ ▄▄ ▄▄▄▄ ▄██▄ ▄▄▄▄ ██▄▄ ▀ ▄▄▄▄ ▄▄▄ ▄▄ ▄▄▄▄ ▄▄▄ ▄▄▄▄ ▄▄▄ ▄▄ ██ ██ ▄▄▄ ▄▄ ▄▄▄ ▄██▄ ▄▄▄▄ ▄▄▄▄ ▄██▄ ▄▄▄ ▄▄▄ ▄▄ 4 | # ██ █ ██ ██ ██ ██ ██ ██ ▀▀ ▄██ ██ ▄█▄▄▄██ ▀▀███▄ ▄█▄▄▄██ ██▀ ▀▀ ▀█▄ █ ▄█▄▄▄██ ██▀ ▀▀ ██▄▄▄█▀ ██▀ ▀▀ ▄█ ▀█▄ ██ ▄█▄▄▄██ ▄█ ▀▀ ██ ▄█ ▀█▄ ██▀ ▀▀ 5 | # ██ █ ██ ██ ██ ██ ██ ██ ▄█▀ ██ ██ ██ ▄ ▀██ ██ ██ ▀█▄█ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ 6 | # ▀█▄▄▀ ▄██▄ ▀█▄▀ ▄██▄ ▄██ ██ ██▄ ▀█▄▄▀█▀ ▀█▄▀ ▀█▄▄▄▀ █▀▄▄▄▄█▀ ▀█▄▄▄▀ ▄██▄ ▀█ ▀█▄▄▄▀ ▄██▄ ▄██▄ ▄██▄ ▀█▄▄█▀ ▀█▄▀ ▀█▄▄▄▀ ▀█▄▄▄▀ ▀█▄▀ ▀█▄▄█▀ ▄██▄ 7 | # 8 | 9 | # Основные настройки 10 | main-settings: 11 | # Форматирование текста. 12 | # LEGACY - цвет через & и hex &# 13 | # LEGACY_ADVANCED - улучшенный аналог legacy с поддержкой &## формата hex 14 | # MINIMESSAGE - цвет через <цвет> (был добавлен в новых версиях (1.17+)) 15 | serializer: LEGACY 16 | # Если стоит true - сообщения будут отправляться по всей сети серверов которые стоят на прокси. 17 | proxy: false 18 | # Префикс плагина 19 | prefix: '&f&l[&c&lЗащита&f&l]' 20 | # Если указано false, то для ввода пароля нужно будет написать пароль в чат 21 | use-command: true 22 | # Команда ввода пароля. (указывается без / в начале) (по умолчанию - pas) (на spigot команда не регистрируется!) 23 | pas-command: 'pas' 24 | # Включить ли команды добавления новых игроков в конфиг 25 | enable-admin-commands: false 26 | # Отправлять ли анонимную статистику (советую не отключать) 27 | enable-metrics: true 28 | # Проверять ли на наличие обновлений (советую не отключать) 29 | update-checker: true 30 | # Интервал основной проверки в тиках (не трогайте, если не знаете, как это работает) 31 | check-interval: 40 32 | # Включить ли поддержку PlaceholderAPI для сообщений? 33 | # Применяется только к сообщениям, где фигурирует игрок 34 | papi-support: false 35 | # Отключить ли оповещения от API? 36 | # Это отключит все варниги от апи, которые могут возникнуть если что-то пошло не так. 37 | # Изменяйте только если вы знаете что делаете! 38 | suppress-api-warnings: false 39 | 40 | # Настройки шифрования паролей 41 | encryption-settings: 42 | # Включить ли шифрование 43 | # При использовании шифрования пароль в data.yml необходимо будет указывать в уже зашифрованном формате и в отдельной графе encrypted-pass: 44 | # Чтобы узнать, как будет выглядеть пароль в зашифрованном виде можно использовать команду /usp encrypt <пароль> 45 | # Однако, если включена опция auto-encrypt-passwords - в data.yml можно будет указать обычный пароль в старом формате pass: и плагин автоматически конвертирует его 46 | enable-encryption: false 47 | # Метод шифрования паролей (Поддерживаемые типы: BASE64, SHA224, SHA256, SHA384, SHA512, SHA3-224, SHA3-256, SHA3-384, SHA3-512) 48 | # BASE64 - Это "шифрование" не обеспечивает защиту данных; это просто метод преобразования данных в другой формат для передачи по сети или хранения. 49 | # Используйте BASE64 только в случае, если боитесь "случайно показать файл с паролями на демке" и вам не нужно конкретно скрывать данные или же для усложнения шифрования 50 | # SHA256 и прочие SHA - разновидности алгоритма SHA. 51 | # Используйте SHA256 если хотите надежно скрыть пароли без возможности расшифровки и SHA512 для еще более эффективного шифрования 52 | # SHA3-256 и прочие SHA3 - аналог обычного SHA с измененным алгоритмом шифрования. 53 | # Используйте SHA3 в случае если желаете сделать нестандартное и одновременно сильное шифрование 54 | # Вы можете использовать 2 и более шифрования одновременно для большей сохранности ваших паролей, чтобы их нельзя было так просто сбрутить 55 | # Шифрование будет выполняться по порядку 1;2;3 и так далее. Важно - глубокое шифрование может занять много времени, по этому не используйте их много 56 | # Для наложения соли (рандомной строки к уже существующему паролю) используется SALT. Накладывать можно лишь 1 раз. 57 | encrypt-method: 'BASE64;SALT;SHA256' 58 | # Если вы использовали какой-либо метод шифрования и по какой-либо причине решили его заменить - вы можете указать его здесь, чтобы не потерять данные 59 | old-encrypt-methods: [] 60 | # Длинна динамически-генерируемой соли. Чем она больше, тем более эффективно защищены пароли. 61 | salt-length: 24 62 | # Включить ли автоматическое шифрование всех имеющихся паролей из файла data.yml при запуске и рестарте плагина 63 | # Данная функция автоматически переведет все пароли из формата pass: в формат encrypted-pass:, зашифровав имеющиеся на данный момент пароли 64 | # Если данных файле много - автоматическое шифрование может занять много времени! Отключите в случае возникновения проблем. 65 | auto-encrypt-passwords: true 66 | 67 | # Настройки файлов 68 | file-settings: 69 | # Имя файла с данными игроков. (по умолчанию - data.yml) 70 | data-file: 'data.yml' 71 | # Имя файла с логами. (по умолчанию - log.yml) 72 | log-file: 'log.yml' 73 | # Если эта настройка включена, то вам нужно будет указать полный путь до файла 74 | # Пример: root/server/plugins/UltimateServerProtector/data.yml 75 | use-full-path: false 76 | # Путь к файлу data.yml 77 | data-file-path: '/root/server/plugins/UltimateServerProtector/' 78 | # Путь к файлу log.yml 79 | log-file-path: '/root/server/plugins/UltimateServerProtector/' 80 | 81 | # Настройка для пользователей floodgate + geyser (со спец.символами) 82 | geyser-settings: 83 | # Символ, который есть у всех игроков с бедрока (поставьте '' если символа никакого нет, тогда проверка будет отключена) 84 | geyser-prefix: '.' 85 | # Ники игроков, которые являются игроками с бедрока (если данный ник будет записан в data.yml, то к нему в ходе проверки пароля автоматически добавится символ) 86 | geyser-nicknames: 87 | - 'test99999' 88 | 89 | # Настройки дополнительных блокировок 90 | blocking-settings: 91 | # Блокировать ли выбрасывание предметов 92 | block-item-drop: true 93 | # Блокировать ли подбор предметов 94 | block-item-pickup: true 95 | # Блокировать ли таб-комплит (работает против /ver + tab) 96 | block-tab-complete: true 97 | # Делать ли игрока бессмертным во время ввода пароля 98 | block-damage: true 99 | # Блокировать ли возможность наносить вред мобам и игрокам во время ввода пароля 100 | block-damaging-entity: true 101 | # Блокировать ли возможность открывать инвентари во время ввода пароля (меню и т.п.) 102 | block-inventory-open: false 103 | # Скрывать ли игрока из таб листа при вводе пароля 104 | hide-on-entering: true 105 | # Скрывать ли других игроков от человека вводящего пароль 106 | hide-other-on-entering: true 107 | # Разрешить ли двигать головой во время ввода пароля 108 | allow-orientation-change: false 109 | 110 | # Настройки сессии 111 | session-settings: 112 | # Сохранять ли данные об игроке чтобы ему не нужно было вводить админ пас при перезаходе 113 | session: true 114 | # Удалять ли данные об игроке через некоторое время 115 | session-time-enabled: false 116 | # Время через которое данные о зарегистрированном игроке удалятся в секундах (отсчет идет от момента ввода пароля) 117 | session-time: 21600 #(6 часов) 118 | 119 | # Настройки наказаний 120 | punish-settings: 121 | # Включить ли наказания за неверно введенный админ-пароль 122 | enable-attempts: true 123 | # Максимальное число попыток ввода админ-пароля 124 | max-attempts: 3 125 | # Включить ли время на ввод админ-пароля 126 | enable-time: true 127 | # Время за которое игрок будет должен ввести админ-пароль в секундах 128 | time: 60 129 | # Включить ли наказания за перезаход на сервер если игрок выходит без ввода админ-пароля 130 | enable-rejoin: true 131 | # Максимальное число перезаходов на сервер если игрок выходит без ввода верного админ-пароля 132 | max-rejoins: 3 133 | 134 | # Настройки повышенной безопасности 135 | secure-settings: 136 | # Применять ли наказания к операторам которых нет в списке 137 | enable-op-whitelist: false 138 | # Применять ли наказания к тем, кто не находится в конфиге, но имеет админ-права 139 | enable-notadmin-punish: false 140 | # Применять ли наказания к людям, которые имеют запрещенные права 141 | enable-permission-blacklist: false 142 | # Включить ли IPWhitelist для администраторов 143 | enable-ip-whitelist: false 144 | # Включить ли возможность использовать команду /usp только из консоли 145 | only-console-usp: false 146 | # Выключать ли сервер, если отключается плагин 147 | shutdown-on-disable: true 148 | # Разрешить ли ряду игроков входить в игру без админ пароля (отключено по умолчанию и небезопасно) 149 | enable-excluded-players: false 150 | 151 | # Настройки работы апи 152 | api-settings: 153 | # Разрешить ли отменить ServerProtectorCaptureEvent (Отключено по умолчанию в целях безопасности) 154 | allow-cancel-capture-event: false 155 | # Вызывать ли ServerProtectorPasswordEnterEvent при вводе пароля игроком? (Отключено по умолчанию в целях безопасности) 156 | call-event-on-password-enter: false 157 | # Из каких пакетов разрешен вызов методов авторизации из апи? 158 | # Вызов методов апи из прочих пакетов будет блокирован. (По умолчанию разрешен только вызов из плагина) 159 | allowed-auth-api-calls-packages: [] 160 | 161 | # Настройки показа сообщений 162 | message-settings: 163 | # Задержка между авто-сообщениями и тайтлами в секундах 164 | delay: 2 165 | # Включить ли сообщения на весь экран 166 | send-titles: true 167 | # Включить ли оповещения для администраторов 168 | enable-broadcasts: true 169 | # Включить ли оповещения для консоли 170 | enable-console-broadcasts: true 171 | 172 | # Настройка боссбара (работает только, если включено время для входа) 173 | bossbar-settings: 174 | # Включить ли боссбар 175 | enable-bossbar: true 176 | # Цвет боссбара (PINK, BLUE, RED, GREEN, YELLOW, PURPLE, WHITE) 177 | bar-color: RED 178 | # Тип боссбара (SOLID, SEGMENTED_6, SEGMENTED_10, SEGMENTED_12, SEGMENTED_20) 179 | bar-style: SEGMENTED_12 180 | 181 | # Настройки звуков, которые будут проигрываться при вводе команд/действиях 182 | sound-settings: 183 | # Включить ли звуки при командах 184 | enable-sounds: true 185 | # Звук при поимке админа с правами (формат - ЗВУК;ГРОМКОСТЬ;ТОНАЛЬНОСТЬ) 186 | on-capture: ENTITY_ITEM_BREAK;1.0;1.0 187 | # Звук при неверном пароле 188 | on-pas-fail: ENTITY_VILLAGER_NO;1.0;1.0 189 | # Звук при верном пароле 190 | on-pas-correct: ENTITY_PLAYER_LEVELUP;1.0;1.0 191 | 192 | # Настройка эффектов, которые даются до ввода пароля 193 | effect-settings: 194 | # Включить ли эффект, который будет выдаваться админу, до ввода пароля 195 | enable-effects: true 196 | # Какие эффекты накладывать на игрока (ЭФФЕКТ;УРОВЕНЬ) 197 | effects: 198 | - 'BLINDNESS;3' 199 | 200 | # Настройки логгирования 201 | logging-settings: 202 | # Записывать ли в файл удачные/неудачные попытки ввода пароля 203 | logging-pas: true 204 | # Записывать ли в файл присоединения игроков с админ-правами 205 | logging-join: true 206 | # Записывать ли в файл включение и отключение плагина 207 | logging-enable-disable: true 208 | # Записывать ли в файл исполнение команд плагином из раздела ниже? 209 | logging-command-execution: true 210 | 211 | # Команды, которые будут применяться к нарушителям 212 | commands: 213 | 214 | # Команды, которые будут применяться к тем, у кого есть админ-права, но кого нет в конфиге 215 | not-in-config: 216 | - 'kick %player% Вас нет в списке администраторов!' 217 | - 'deop %player%' 218 | 219 | # Команды, которые будут применяться к тем, у кого есть админ-права, но он не прописан в вайтлисте 220 | not-in-opwhitelist: 221 | - 'deop %player%' 222 | #- 'ban %player% Вам нельзя иметь права оператора!' 223 | 224 | # Команды, которые будут применяться к тем, кто имеет запрещенные права (отключено по умолчанию) 225 | have-blacklisted-perm: 226 | - 'lp user %player% permission clear' 227 | #- 'ban %player% Вам нельзя иметь такие права!' 228 | 229 | # Команды, которые будут применяться к тем, кто вошел с админ-правами, указан в конфиге, но имеет не админский IP (отключено по умолчанию) 230 | not-admin-ip: 231 | - 'kick %player% Ваш IP не находится в вайтлисте' 232 | #- 'deop %player' 233 | 234 | # Команды, которые будут применяться к тем, кто ввел пас неверно за отведенные ему попытки 235 | failed-pass: 236 | - 'ban %player% Вы ввели админ-пароль неверно, ваш аккаунт заморожен' 237 | - 'deop %player%' 238 | 239 | # Команды, которые будут применяться к тем, кто не ввел пас за отведенное время 240 | failed-time: 241 | - 'kick %player% Вы не успели ввести админ-пароль за отведенный срок' 242 | - 'deop %player%' 243 | 244 | # Команды, которые будут применяться к тем, кто перезашел на сервер без ввода верного пароля слишком много раз 245 | failed-rejoin: 246 | - 'ban %player% Вы слишком часто перезаходили на сервер не вводя пас' 247 | - 'deop %player%' 248 | 249 | # Права, за которые игроку будет необходимо ввести админ-пароль (не стесняйтесь добавлять свои!) 250 | permissions: 251 | - '*' 252 | - 'bukkit.*' 253 | - 'minecraft.*' 254 | - 'essentials.*' 255 | - 'cmi.*' 256 | - 'worldguard.*' 257 | - 'worldedit.*' 258 | - 'fawe.*' 259 | - 'permissions.*' 260 | - 'luckperms.*' 261 | - 'luckperms.editor' 262 | - 'luckperms.applyedits' 263 | - 'citizens.*' 264 | - 'citizenscmd.*' 265 | - 'znpcs.*' 266 | - 'holograms.*' 267 | - 'multiverse.*' 268 | - 'coreprotect.*' 269 | - 'mycommand.*' 270 | - 'towny.*' 271 | - 'matrix.*' 272 | - 'vulcan.*' 273 | - 'grim.*' 274 | - 'dh.admin' 275 | - 'ls.admin' 276 | - 'fawe.admin' 277 | - 'authme.admin' 278 | - 'nlogin.admin' 279 | - 'protocol.admin' 280 | - 'placeholderapi.admin' 281 | - 'playerpoints.*' 282 | - 'plugman.*' 283 | - 'plugman.admin' 284 | - 'plugman.download' 285 | - 'serverprotector.admin' 286 | 287 | # Права, которые никто, кроме игроков из раздела excluded-players, не сможет иметь (отключено по умолчанию.) 288 | blacklisted-perms: 289 | - '*' 290 | 291 | # Команды, которые можно вводить до ввода админ-пароля (указывать вместе с /) 292 | allowed-commands: 293 | - '/l' 294 | - '/login' 295 | - '/reg' 296 | - '/register' 297 | - '/captcha' 298 | 299 | # Каким игрокам разрешено иметь ОП права 300 | op-whitelist: 301 | - Overwrite 302 | - test99999 303 | 304 | # С каких IP и каким игрокам разрешено входить с админ-правами 305 | # Вы можете указать только часть IP адреса, чтобы разрешить вход людям с динамическим IP. К примеру 1.2.3.4 -> 1.2.3.* 306 | ip-whitelist: 307 | # Игрок 1 308 | test99999: 309 | - 127.0.0.1 310 | - 0.0.0.0 311 | # Игрок 2 312 | test123123: 313 | - 228.13.37.* 314 | 315 | # Какие игроки будут исключены из проверок (каждой проверке - свой тип) 316 | excluded-players: 317 | # Игроки, которым не нужно будет вводить админ-пароль 318 | admin-pass: 319 | - test99999 320 | - test123123 321 | # Игроки, которые не будут проверяться на наличие в op-whitelist 322 | op-whitelist: 323 | - test99999 324 | - test123123 325 | # Игроки, которые не будут проверяться на наличие в ip-whitelist 326 | ip-whitelist: 327 | - test99999 328 | - test123123 329 | # Игроки, которым можно будет иметь заблокированные права 330 | blacklisted-perms: 331 | - test99999 332 | - test123123 333 | -------------------------------------------------------------------------------- /bukkit/src/main/resources-ru/data.yml: -------------------------------------------------------------------------------- 1 | # Уникальные пароли для игроков 2 | data: 3 | OverwriteMC: # игрок 1 4 | pass: '123123' # админ-пасс игрока 1 5 | test99999: # игрок 2 6 | pass: '321321' # админ-пасс игрока 2 -------------------------------------------------------------------------------- /bukkit/src/main/resources-ru/message.yml: -------------------------------------------------------------------------------- 1 | # Сообщения которые будет выводиться людям при вводе команды и при наличии админ-прав 2 | msg: 3 | message: '%prefix% &fУ вас обнаружены админ-права. Вы должны ввести админ-пароль!' 4 | incorrect: '%prefix% &cВведенный тобой пароль неверен!' 5 | correct: '%prefix% &aПароль верный. Добро пожаловать на сервер.' 6 | noneed: '%prefix% &fВам не нужно вводить админ-пароль или он уже был введен.' 7 | cantbenull: '%prefix% &fПас не может быть пустым.' 8 | playeronly: '%prefix% &fТолько для игроков' 9 | 10 | # Оповещения для консоли и администраторов сервера 11 | broadcasts: 12 | failed: '%prefix% &fАдминистратор &3%player% &fввел админ-пас &cнеудачно! &fIP адрес: &c%ip%' 13 | passed: '%prefix% &fАдминистратор &3%player% &fввел админ-пас &aуспешно! &fIP адрес: &c%ip%' 14 | joined: '%prefix% &fАдминистратор &3%player% &fвошел в игру. &fIP адрес: &c%ip%' 15 | captured: '%prefix% &fИгрок &3%player% &fбыл пойман с админ-правами! &fIP адрес: &c%ip%' 16 | disabled: '%prefix% &6&lВнимание! &fПлагин был отключен!' 17 | 18 | # Сообщения которые будут высвечиваться на экране 19 | titles: 20 | message: '&e&l⚠ &c&lЗащита &e&l⚠;&fОбнаружены админ-права! Вводи админ-пароль!;10;60;15' 21 | incorrect: '&e&l⚠ &c&lЗащита &e&l⚠;&cПароль неверен!;10;60;15' 22 | correct: '&e&l⚠ &c&lЗащита &e&l⚠;&aПароль верный. Добро пожаловать.;10;60;15' 23 | 24 | # Сообщение в босс-баре 25 | bossbar: 26 | message: '&fОсталось: &c%time% секунд' 27 | 28 | # Сообщение при вводе команды /usp (админ-команд) 29 | uspmsg: 30 | consoleonly: '&cДанная команда может быть исполнена только из консоли!' 31 | playeronly: '&cДанная команда может быть исполнена только игроком!' 32 | logout: '&aВаша сессия была сброшена' 33 | reloaded: '&aПлагин перезагружен' 34 | rebooted: '&aПлагин перезапущен' 35 | playernotfound: '&cАккаунт %nick% не найден в системе!' 36 | alreadyinconfig: '&aДанный аккаунт уже находится в конфиге' 37 | notinconfig: '&cДанный аккаунт не находится в конфиге' 38 | playeradded: '&aИгрок %nick% успешно добавлен' 39 | playerremoved: '&aИгрок успешно удалён' 40 | ipadded: '&aIP %ip% успешно добавлены' 41 | setpassusage: '&f/%cmd% setpass (ник) (пароль)' 42 | addopusage: '&f/%cmd% addop (ник)' 43 | addipusage: '&f/%cmd% addip (ip)' 44 | rempassusage: '&f/%cmd% rempass (ник)' 45 | remopusage: '&f/%cmd% remop (ник)' 46 | remipusage: '&f/%cmd% rempip (ip)' 47 | usage: '&7&l> &7Использование:' 48 | usage-logout: '&6/%cmd% logout&7 - завешить сессию' 49 | usage-reload: '&6/%cmd% reload&7 - перезагрузить конфиг' 50 | usage-reboot: '&6/%cmd% reboot&7 - перезапустить плагин' 51 | usage-encrypt: '&6/%cmd% encrypt (password)&7 - показать зашифрованную версию указанного пароля' 52 | usage-setpass: '&6/%cmd% setpass (ник) (пароль) &7- установить пароль игроку' 53 | usage-rempass: '&6/%cmd% rempass (ник) &7- удалить пароль игроку' 54 | usage-addop: '&6/%cmd% addop (ник) &7- добавить игрока в op-whitelist' 55 | usage-remop: '&6/%cmd% remop (ник) &7- удалить игрока из op-whitelist' 56 | usage-addip: '&6/%cmd% addip (ник) (ip-адреса) &7- добавить игрока и его ip в ip-whitelist' 57 | usage-remip: '&6/%cmd% remip (ник) (ip-адреса) &7- удалить игрока и его ip из ip-whitelist' 58 | otherdisabled: |- 59 | &7Прочие команды отключены. 60 | &7Для их включения выставьте &6enable-admin-commands: &atrue 61 | 62 | # Как сообщения будут отображаться в логах 63 | log-format: 64 | enabled: '%date% [UltimateServerProtector - плагин включён]' 65 | disabled: '%date% [UltimateServerProtector - плагин выключён]' 66 | failed: '%date% Администратор %player% ввел админ-пас неудачно! IP адрес: %ip%' 67 | passed: '%date% Администратор %player% ввел админ-пас успешно! IP адрес: %ip%' 68 | joined: '%date% Администратор %player% вошел в игру. IP адрес: %ip%' 69 | captured: '%date% Игрок %player% был пойман с админ-правами! IP адрес: %ip%' 70 | command: '%date% Плагин исполнил команду: %cmd%' 71 | 72 | # Системные сообщения 73 | system: 74 | baseline-warn: "§6============= §c! ВНИМАНИЕ ! §6=============" 75 | baseline-default: "§6========================================" 76 | paper-1: "§eВы используете нестабильное ядро для вашего сервера Minecraft! Рекомендуется использовать §aPaper" 77 | paper-2: "§eСкачать Paper: §ahttps://papermc.io/downloads/all" 78 | bungeecord-1: "§eУ вас включена настройка §6bungeecord§a, но плагин §6BungeeGuard §eне установлен!" 79 | bungeecord-2: "§eБез этого плагина вы подвергаете себя §cопасности! §eУстановите его для дальнейшей безопасной работы." 80 | bungeecord-3: "§eСкачать BungeeGuard: §ahttps://www.spigotmc.org/resources/bungeeguard.79601/" 81 | update-latest: "§aВы используете последнюю версию плагина!" 82 | update-success-1: "§aОбновление было загружено успешно!" 83 | update-success-2: "§aПерезапустите сервер, чтобы применить обновление." 84 | update-outdated-1: "§aВы используете устаревшую версию плагина!" 85 | update-outdated-2: "§aВы можете скачать новую версию здесь:" 86 | update-outdated-3: "§bgithub.com/Overwrite987/UltimateServerProtector/releases/" 87 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | ru.overwrite.protect 8 | ultimateserverprotector-project 9 | 34.0 10 | pom 11 | 12 | UltimateServerProtector Project 13 | 14 | 15 | bukkit 16 | 17 | 18 | UltimateServerProtector Project 19 | 20 | 21 21 | UTF-8 22 | en 23 | 24 | 25 | 26 | 27 | ru 28 | 29 | ru 30 | 31 | 32 | 33 | 34 | 35 | clean package 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-compiler-plugin 40 | 3.13.0 41 | 42 | ${java.version} 43 | ${java.version} 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | papermc 52 | https://repo.papermc.io/repository/maven-public/ 53 | 54 | 55 | placeholderapi 56 | https://repo.extendedclip.com/content/repositories/placeholderapi/ 57 | 58 | 59 | 60 | --------------------------------------------------------------------------------