diff options
author | mdxd44 <ogurec332@mail.ru> | 2021-12-27 18:27:05 +0900 |
---|---|---|
committer | mdxd44 <ogurec332@mail.ru> | 2021-12-27 18:28:55 +0900 |
commit | fce457435c848b5262818383a98e6dbb8538e021 (patch) | |
tree | f15543d88cbc5cb1a4797d503272a54886ef51d9 | |
parent | cc2ccfbe22044e98a66257488cf5bd26e21ca340 (diff) | |
download | LimboAuth-fce457435c848b5262818383a98e6dbb8538e021.tar.gz LimboAuth-fce457435c848b5262818383a98e6dbb8538e021.tar.bz2 LimboAuth-fce457435c848b5262818383a98e6dbb8538e021.zip |
Add bStats and force changepassword command.
7 files changed, 186 insertions, 44 deletions
diff --git a/build.gradle b/build.gradle index ac00097..2fd5eec 100644 --- a/build.gradle +++ b/build.gradle @@ -44,10 +44,12 @@ dependencies { implementation("com.j256.ormlite:ormlite-jdbc:5.7") - implementation("com.h2database:h2:2.0.202") + implementation("com.h2database:h2:1.4.200") implementation("mysql:mysql-connector-java:8.0.27") implementation("org.postgresql:postgresql:42.3.1") + implementation("org.bstats:bstats-velocity:2.2.1") + compileOnly("com.github.spotbugs:spotbugs-annotations:4.5.2") } @@ -67,6 +69,10 @@ shadowJar { minimize() + // Why are we increasing the size of the plugin if we can do that? :thinking: + relocate("org.bstats", "net.elytrium.limboapi.bstats") + exclude("org/bstats/**") + relocate("at.favre.lib", "net.elytrium.limboauth.thirdparty.at.favre.lib") relocate("com.j256.ormlite", "net.elytrium.limboauth.thirdparty.com.j256.ormlite") relocate("com.mysql", "net.elytrium.limboauth.thirdparty.com.mysql") @@ -106,8 +112,8 @@ sourceSets.main.getJava().srcDir(getTasks().register("generateTemplates", Copy) task.getInputs().properties("version": getVersion()) task.from(file("src/main/templates")) - .into(getLayout().getBuildDirectory().dir("generated/sources/templates")) - .expand("version": getVersion()) + .into(getLayout().getBuildDirectory().dir("generated/sources/templates")) + .expand("version": getVersion()) }.map { it.getOutputs() }) diff --git a/src/main/java/net/elytrium/limboauth/LimboAuth.java b/src/main/java/net/elytrium/limboauth/LimboAuth.java index f0fcda0..a86f3c5 100644 --- a/src/main/java/net/elytrium/limboauth/LimboAuth.java +++ b/src/main/java/net/elytrium/limboauth/LimboAuth.java @@ -67,6 +67,7 @@ import net.elytrium.limboapi.api.file.SchematicFile; import net.elytrium.limboapi.api.file.WorldFile; import net.elytrium.limboauth.command.ChangePasswordCommand; import net.elytrium.limboauth.command.DestroySessionCommand; +import net.elytrium.limboauth.command.ForceChangePasswordCommand; import net.elytrium.limboauth.command.ForceUnregisterCommand; import net.elytrium.limboauth.command.LimboAuthCommand; import net.elytrium.limboauth.command.PremiumCommand; @@ -78,6 +79,7 @@ import net.elytrium.limboauth.model.RegisteredPlayer; import net.elytrium.limboauth.utils.UpdatesChecker; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.bstats.velocity.Metrics; import org.slf4j.Logger; @Plugin( @@ -94,9 +96,10 @@ public class LimboAuth { private static LimboAuth instance; private final HttpClient client = HttpClient.newHttpClient(); - private final Path dataDirectory; - private final Logger logger; private final ProxyServer server; + private final Logger logger; + private final Metrics.Factory metricsFactory; + private final Path dataDirectory; private final LimboFactory factory; private final Set<String> unsafePasswords = new HashSet<>(); @@ -108,17 +111,20 @@ public class LimboAuth { @Inject @SuppressWarnings("OptionalGetWithoutIsPresent") - public LimboAuth(ProxyServer server, Logger logger, @Named("limboapi") PluginContainer factory, @DataDirectory Path dataDirectory) { + public LimboAuth(ProxyServer server, Logger logger, Metrics.Factory metricsFactory, + @Named("limboapi") PluginContainer factory, @DataDirectory Path dataDirectory) { setInstance(this); this.server = server; this.logger = logger; + this.metricsFactory = metricsFactory; this.dataDirectory = dataDirectory; this.factory = (LimboFactory) factory.getInstance().get(); } @Subscribe public void onProxyInitialization(ProxyInitializeEvent event) throws Exception { + this.metricsFactory.make(this, 13700); System.setProperty("com.j256.simplelogging.level", "ERROR"); this.reload(); @@ -182,8 +188,10 @@ public class LimboAuth { CommandManager manager = this.server.getCommandManager(); manager.unregister("unregister"); + manager.unregister("premium"); manager.unregister("forceunregister"); manager.unregister("changepassword"); + manager.unregister("forcechangepassword"); manager.unregister("destroysession"); manager.unregister("2fa"); manager.unregister("limboauth"); @@ -192,6 +200,7 @@ public class LimboAuth { manager.register("premium", new PremiumCommand(this, this.playerDao)); manager.register("forceunregister", new ForceUnregisterCommand(this, this.server, this.playerDao), "forceunreg"); manager.register("changepassword", new ChangePasswordCommand(this.playerDao), "changepass"); + manager.register("forcechangepassword", new ForceChangePasswordCommand(this.server, this.playerDao), "forcechangepass"); manager.register("destroysession", new DestroySessionCommand(this)); if (Settings.IMP.MAIN.ENABLE_TOTP) { manager.register("2fa", new TotpCommand(this.playerDao), "totp"); @@ -236,7 +245,7 @@ public class LimboAuth { this.server.getEventManager().register(this, new AuthListener(this.playerDao)); Executors.newScheduledThreadPool(1, task -> new Thread(task, "purge-cache")).scheduleAtFixedRate(() -> - this.checkCache(this.cachedAuthChecks, Settings.IMP.MAIN.PURGE_CACHE_MILLIS), + this.checkCache(this.cachedAuthChecks, Settings.IMP.MAIN.PURGE_CACHE_MILLIS), Settings.IMP.MAIN.PURGE_CACHE_MILLIS, Settings.IMP.MAIN.PURGE_CACHE_MILLIS, TimeUnit.MILLISECONDS @@ -320,7 +329,6 @@ public class LimboAuth { } RegisteredPlayer registeredPlayer = AuthSessionHandler.fetchInfo(this.playerDao, nickname); - if (player.isOnlineMode()) { if (registeredPlayer == null || registeredPlayer.getHash().isEmpty()) { registeredPlayer = AuthSessionHandler.fetchInfo(this.playerDao, player.getUniqueId()); @@ -330,6 +338,7 @@ public class LimboAuth { } } } + // Send player to auth virtual server. try { this.authServer.spawnPlayer(player, new AuthSessionHandler(this.playerDao, player, this, registeredPlayer)); @@ -340,12 +349,12 @@ public class LimboAuth { public boolean isPremiumExternal(String nickname) { try { - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(String.format(Settings.IMP.MAIN.ISPREMIUM_AUTH_URL, nickname))) - .build(); - - HttpResponse<String> response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); - return response.statusCode() == 200; + return this.client.send( + HttpRequest.newBuilder() + .uri(URI.create(String.format(Settings.IMP.MAIN.ISPREMIUM_AUTH_URL, nickname))) + .build(), + HttpResponse.BodyHandlers.ofString() + ).statusCode() == 200; } catch (IOException | InterruptedException e) { this.getLogger().error("Unable to authenticate with Mojang", e); return true; diff --git a/src/main/java/net/elytrium/limboauth/Settings.java b/src/main/java/net/elytrium/limboauth/Settings.java index 42cb470..f32279b 100644 --- a/src/main/java/net/elytrium/limboauth/Settings.java +++ b/src/main/java/net/elytrium/limboauth/Settings.java @@ -166,20 +166,25 @@ public class Settings extends Config { public String UNREGISTER_SUCCESSFUL = "{PRFX}{NL}&aSuccessfully unregistered!"; public String UNREGISTER_USAGE = "{PRFX} Usage: &6/unregister <current password> confirm"; - public String PREMIUM_SUCCESSFUL = "{PRFX}{NL}&aSuccessfully changed account state to PREMIUM!"; + public String PREMIUM_SUCCESSFUL = "{PRFX}{NL}&aSuccessfully changed account state to &6PREMIUM&a!"; + public String ALREADY_PREMIUM = "{PRFX} &cYour account is already &6PREMIUM&c!"; + public String NOT_PREMIUM = "{PRFX} &cYour account is not &6PREMIUM&c!"; public String PREMIUM_USAGE = "{PRFX} Usage: &6/premium <current password> confirm"; - public String NOT_PREMIUM = "{PRFX} Your account is not PREMIUM"; - public String ALREADY_PREMIUM = "{PRFX} Your account is already PREMIUM"; - public String FORCE_UNREGISTER_SUCCESSFUL = "{PRFX} &a{0} successfully unregistered!"; + public String FORCE_UNREGISTER_SUCCESSFUL = "{PRFX} &6{0} &asuccessfully unregistered!"; public String FORCE_UNREGISTER_KICK = "{PRFX}{NL}&aYou have been unregistered by administrator!"; - public String FORCE_UNREGISTER_NOT_SUCCESSFUL = "{PRFX} &cUnable to unregister {0}. Most likely this player has never been on this server."; + public String FORCE_UNREGISTER_NOT_SUCCESSFUL = "{PRFX} &cUnable to unregister &6{0}&c. Most likely this player has never been on this server."; public String FORCE_UNREGISTER_USAGE = "{PRFX} Usage: &6/forceunregister <nickname>"; public String CHANGE_PASSWORD_SUCCESSFUL = "{PRFX} &aSuccessfully changed password!"; @Comment("Or if change-password-need-old-pass set to false remove the \"<old password>\" part.") public String CHANGE_PASSWORD_USAGE = "{PRFX} Usage: &6/changepassword <old password> <new password>"; + public String FORCE_CHANGE_PASSWORD_SUCCESSFUL = "{PRFX} &aSuccessfully changed password for player &6{0}&a!"; + public String FORCE_CHANGE_PASSWORD_MESSAGE = "{PRFX} &aYour password has been changed to &6{0} &aby administator!"; + public String FORCE_CHANGE_PASSWORD_NOT_SUCCESSFUL = "{PRFX} &cUnable to change password for &6{0}&c. Most likely this player has never been on this server."; + public String FORCE_CHANGE_PASSWORD_USAGE = "{PRFX} Usage: &6/forcechangepassword <nickname> <new password>"; + public String TOTP = "{PRFX} Please, enter your 2FA key using &6/2fa <key>"; public String TOTP_TITLE = "{PRFX}"; public String TOTP_SUBTITLE = "&aEnter your 2FA key using &6/2fa <key>"; diff --git a/src/main/java/net/elytrium/limboauth/command/ForceChangePasswordCommand.java b/src/main/java/net/elytrium/limboauth/command/ForceChangePasswordCommand.java new file mode 100644 index 0000000..51ef3a2 --- /dev/null +++ b/src/main/java/net/elytrium/limboauth/command/ForceChangePasswordCommand.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2021 Elytrium + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package net.elytrium.limboauth.command; + +import com.j256.ormlite.dao.Dao; +import com.j256.ormlite.stmt.UpdateBuilder; +import com.velocitypowered.api.command.CommandSource; +import com.velocitypowered.api.command.SimpleCommand; +import com.velocitypowered.api.proxy.ProxyServer; +import java.sql.SQLException; +import java.text.MessageFormat; +import java.util.List; +import java.util.Locale; +import net.elytrium.limboauth.Settings; +import net.elytrium.limboauth.handler.AuthSessionHandler; +import net.elytrium.limboauth.model.RegisteredPlayer; +import net.elytrium.limboauth.utils.SuggestUtils; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; + +public class ForceChangePasswordCommand implements SimpleCommand { + + private final ProxyServer server; + private final Dao<RegisteredPlayer, String> playerDao; + + private final String message; + private final String successful; + private final String notSuccessful; + private final Component usage; + + public ForceChangePasswordCommand(ProxyServer server, Dao<RegisteredPlayer, String> playerDao) { + this.server = server; + this.playerDao = playerDao; + + this.message = Settings.IMP.MAIN.STRINGS.FORCE_CHANGE_PASSWORD_MESSAGE; + this.successful = Settings.IMP.MAIN.STRINGS.FORCE_CHANGE_PASSWORD_SUCCESSFUL; + this.notSuccessful = Settings.IMP.MAIN.STRINGS.FORCE_CHANGE_PASSWORD_NOT_SUCCESSFUL; + this.usage = LegacyComponentSerializer.legacyAmpersand().deserialize(Settings.IMP.MAIN.STRINGS.FORCE_CHANGE_PASSWORD_USAGE); + } + + @Override + public List<String> suggest(SimpleCommand.Invocation invocation) { + return SuggestUtils.suggestPlayers(invocation.arguments(), this.server); + } + + @Override + public void execute(SimpleCommand.Invocation invocation) { + CommandSource source = invocation.source(); + String[] args = invocation.arguments(); + + if (args.length == 2) { + String nickname = args[0]; + String newPassword = args[1]; + + try { + UpdateBuilder<RegisteredPlayer, String> updateBuilder = this.playerDao.updateBuilder(); + updateBuilder.where().eq("LOWERCASENICKNAME", nickname.toLowerCase(Locale.ROOT)); + updateBuilder.updateColumnValue("HASH", AuthSessionHandler.genHash(newPassword)); + updateBuilder.update(); + + this.server.getPlayer(nickname).ifPresent(player -> + player.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(MessageFormat.format(this.message, newPassword))) + ); + + source.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(MessageFormat.format(this.successful, nickname))); + } catch (SQLException e) { + source.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(MessageFormat.format(this.notSuccessful, nickname))); + e.printStackTrace(); + } + + return; + } + + source.sendMessage(this.usage); + } + + @Override + public boolean hasPermission(SimpleCommand.Invocation invocation) { + return invocation.source().hasPermission("limboauth.admin.forcechangepassword"); + } +} diff --git a/src/main/java/net/elytrium/limboauth/command/ForceUnregisterCommand.java b/src/main/java/net/elytrium/limboauth/command/ForceUnregisterCommand.java index 2b97143..bf30f92 100644 --- a/src/main/java/net/elytrium/limboauth/command/ForceUnregisterCommand.java +++ b/src/main/java/net/elytrium/limboauth/command/ForceUnregisterCommand.java @@ -17,19 +17,17 @@ package net.elytrium.limboauth.command; -import com.google.common.collect.ImmutableList; import com.j256.ormlite.dao.Dao; import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.command.SimpleCommand; -import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ProxyServer; import java.sql.SQLException; import java.text.MessageFormat; import java.util.List; import java.util.Locale; -import java.util.stream.Collectors; import net.elytrium.limboauth.LimboAuth; import net.elytrium.limboauth.Settings; +import net.elytrium.limboauth.utils.SuggestUtils; import net.elytrium.limboauth.model.RegisteredPlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; @@ -58,20 +56,7 @@ public class ForceUnregisterCommand implements SimpleCommand { @Override public List<String> suggest(SimpleCommand.Invocation invocation) { - String[] args = invocation.arguments(); - - if (args.length == 0) { - return this.server.getAllPlayers().stream() - .map(Player::getUsername) - .collect(Collectors.toList()); - } else if (args.length == 1) { - return this.server.getAllPlayers().stream() - .map(Player::getUsername) - .filter(str -> str.regionMatches(true, 0, args[0], 0, args[0].length())) - .collect(Collectors.toList()); - } - - return ImmutableList.of(); + return SuggestUtils.suggestPlayers(invocation.arguments(), this.server); } @Override @@ -81,12 +66,11 @@ public class ForceUnregisterCommand implements SimpleCommand { if (args.length == 1) { String playerNick = args[0]; + try { this.playerDao.deleteById(playerNick.toLowerCase(Locale.ROOT)); this.plugin.removePlayerFromCache(playerNick); - this.server.getPlayer(playerNick).ifPresent(player -> { - player.disconnect(this.kick); - }); + this.server.getPlayer(playerNick).ifPresent(player -> player.disconnect(this.kick)); source.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(MessageFormat.format(this.successful, playerNick))); } catch (SQLException e) { source.sendMessage(LegacyComponentSerializer.legacyAmpersand().deserialize(MessageFormat.format(this.notSuccessful, playerNick))); diff --git a/src/main/java/net/elytrium/limboauth/command/PremiumCommand.java b/src/main/java/net/elytrium/limboauth/command/PremiumCommand.java index 7b209c5..87bf64d 100644 --- a/src/main/java/net/elytrium/limboauth/command/PremiumCommand.java +++ b/src/main/java/net/elytrium/limboauth/command/PremiumCommand.java @@ -36,11 +36,11 @@ public class PremiumCommand implements SimpleCommand { private final Dao<RegisteredPlayer, String> playerDao; private final Component notPlayer; - private final Component notPremium; - private final Component alreadyPremium; private final Component notRegistered; + private final Component alreadyPremium; private final Component successful; private final Component errorOccurred; + private final Component notPremium; private final Component wrongPassword; private final Component usage; @@ -49,11 +49,11 @@ public class PremiumCommand implements SimpleCommand { this.playerDao = playerDao; this.notPlayer = LegacyComponentSerializer.legacyAmpersand().deserialize(Settings.IMP.MAIN.STRINGS.NOT_PLAYER); - this.notPremium = LegacyComponentSerializer.legacyAmpersand().deserialize(Settings.IMP.MAIN.STRINGS.NOT_PREMIUM); - this.alreadyPremium = LegacyComponentSerializer.legacyAmpersand().deserialize(Settings.IMP.MAIN.STRINGS.ALREADY_PREMIUM); this.notRegistered = LegacyComponentSerializer.legacyAmpersand().deserialize(Settings.IMP.MAIN.STRINGS.NOT_REGISTERED); + this.alreadyPremium = LegacyComponentSerializer.legacyAmpersand().deserialize(Settings.IMP.MAIN.STRINGS.ALREADY_PREMIUM); this.successful = LegacyComponentSerializer.legacyAmpersand().deserialize(Settings.IMP.MAIN.STRINGS.PREMIUM_SUCCESSFUL); this.errorOccurred = LegacyComponentSerializer.legacyAmpersand().deserialize(Settings.IMP.MAIN.STRINGS.ERROR_OCCURRED); + this.notPremium = LegacyComponentSerializer.legacyAmpersand().deserialize(Settings.IMP.MAIN.STRINGS.NOT_PREMIUM); this.wrongPassword = LegacyComponentSerializer.legacyAmpersand().deserialize(Settings.IMP.MAIN.STRINGS.WRONG_PASSWORD); this.usage = LegacyComponentSerializer.legacyAmpersand().deserialize(Settings.IMP.MAIN.STRINGS.PREMIUM_USAGE); } @@ -103,6 +103,6 @@ public class PremiumCommand implements SimpleCommand { @Override public boolean hasPermission(SimpleCommand.Invocation invocation) { - return invocation.source().getPermissionValue("limboauth.commands.unregister") != Tristate.FALSE; + return invocation.source().getPermissionValue("limboauth.commands.premium") != Tristate.FALSE; } } diff --git a/src/main/java/net/elytrium/limboauth/utils/SuggestUtils.java b/src/main/java/net/elytrium/limboauth/utils/SuggestUtils.java new file mode 100644 index 0000000..7740ea5 --- /dev/null +++ b/src/main/java/net/elytrium/limboauth/utils/SuggestUtils.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2021 Elytrium + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package net.elytrium.limboauth.utils; + +import com.google.common.collect.ImmutableList; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import java.util.List; +import java.util.stream.Collectors; + +public class SuggestUtils { + + public static List<String> suggestPlayers(String[] args, ProxyServer server) { + if (args.length == 0) { + return server.getAllPlayers().stream() + .map(Player::getUsername) + .collect(Collectors.toList()); + } else if (args.length == 1) { + return server.getAllPlayers().stream() + .map(Player::getUsername) + .filter(str -> str.regionMatches(true, 0, args[0], 0, args[0].length())) + .collect(Collectors.toList()); + } + + return ImmutableList.of(); + } +} |