Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.comphenix.protocol.ProtocolLibrary;
import com.github.games647.fastlogin.bukkit.command.CrackedCommand;
import com.github.games647.fastlogin.bukkit.command.PremiumCommand;
import com.github.games647.fastlogin.bukkit.command.DeleteCommand;
import com.github.games647.fastlogin.bukkit.listener.ConnectionListener;
import com.github.games647.fastlogin.bukkit.listener.PaperCacheListener;
import com.github.games647.fastlogin.bukkit.listener.protocollib.ProtocolLibListener;
Expand Down Expand Up @@ -155,6 +156,7 @@ private void registerCommands() {
//register commands using a unique name
Optional.ofNullable(getCommand("premium")).ifPresent(c -> c.setExecutor(new PremiumCommand(this)));
Optional.ofNullable(getCommand("cracked")).ifPresent(c -> c.setExecutor(new CrackedCommand(this)));
Optional.ofNullable(getCommand("fldelete")).ifPresent(c -> c.setExecutor(new DeleteCommand(this)));
}

private boolean initializeFloodgate() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* SPDX-License-Identifier: MIT
*
* The MIT License (MIT)
*
* Copyright (c) 2015-2024 games647 and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.games647.fastlogin.bukkit.command;

import java.util.ArrayList;
import java.util.List;

import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;

import com.github.games647.fastlogin.bukkit.FastLoginBukkit;

public class DeleteCommand implements TabExecutor {
private final FastLoginBukkit plugin;

public DeleteCommand(FastLoginBukkit plugin) {
this.plugin = plugin;
}

/**
* Handles the command to delete profiles.
*/
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {

if (!sender.hasPermission(command.getPermission())) {
plugin.getCore().sendLocaleMessage("no-permission", sender);
return true;
}

if (plugin.getBungeeManager().isEnabled()) {
sender.sendMessage("Error: Cannot delete profile entries when using BungeeCord!");
return false;
}

if (args.length < 1) {
sender.sendMessage("Error: Must supply username to delete!");
return false;
}

Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
int count = plugin.getCore().getStorage().deleteProfile(args[0]);
if (!(sender instanceof ConsoleCommandSender)) {
Bukkit.getScheduler().runTask(plugin, () -> {
if (count == 0) {
sender.sendMessage("Error: No profile entries found!");
} else {
sender.sendMessage("Deleted " + count + " matching profile entries");
}
});
}
});

return true;
}

@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
List<String> list = new ArrayList<>();
for (Player p : Bukkit.getOnlinePlayers()) {
if (p.getName().toLowerCase().startsWith(args[0])) {
list.add(p.getName());
}
}
return null;
}
}
9 changes: 9 additions & 0 deletions bukkit/src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ commands:
usage: /<command> [player]
permission: ${project.artifactId}.command.cracked

fldelete:
description: 'Delete player profile data'
usage: /<command> [player]
permission: ${project.artifactId}.command.delete

permissions:
${project.artifactId}.command.premium:
description: 'Label themselves as premium'
Expand All @@ -62,3 +67,7 @@ permissions:
description: 'Label others as cracked'
children:
${project.artifactId}.command.cracked: true

${project.artifactId}.command.delete:
description: 'Delete other players profile data'
default: op
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public interface AuthStorage {

StoredProfile loadProfile(UUID uuid);

int deleteProfile(String name);

void save(StoredProfile playerProfile);

void close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public abstract class SQLStorage implements AuthStorage {
+ "` WHERE `Name`=? LIMIT 1";
protected static final String LOAD_BY_UUID = "SELECT * FROM `" + PREMIUM_TABLE
+ "` WHERE `UUID`=? LIMIT 1";
protected static final String DELETE_BY_NAME = "DELETE FROM " + PREMIUM_TABLE
+ " WHERE `Name` = ?";
protected static final String INSERT_PROFILE = "INSERT INTO `" + PREMIUM_TABLE
+ "` (`UUID`, `Name`, `Premium`, `Floodgate`, `LastIp`) " + "VALUES (?, ?, ?, ?, ?) ";
// limit not necessary here, because it's unique
Expand Down Expand Up @@ -143,6 +145,25 @@ public StoredProfile loadProfile(UUID uuid) {
return null;
}

@Override
public int deleteProfile(String name) {
try (Connection con = dataSource.getConnection();
PreparedStatement deleteStmt = con.prepareStatement(DELETE_BY_NAME)) {
deleteStmt.setString(1, name);

int rowsDeleted = deleteStmt.executeUpdate();
if (rowsDeleted > 0) {
log.info("Deleted {}'s profile data", name);
} else {
log.info("No profile data found for {}", name);
}
return rowsDeleted;
} catch (SQLException sqlEx) {
log.error("Failed to query profile: {}", name, sqlEx);
return 0;
}
}

private Optional<StoredProfile> parseResult(ResultSet resultSet) throws SQLException {
if (resultSet.next()) {
long userId = resultSet.getInt("UserID");
Expand Down