fix: make the lists actually thread-safe (maybe, but pretty likely)
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/Collections.html#synchronizedList(java.util.List) > It is imperative that the user manually synchronize on the returned list when traversing it via Iterator, Spliterator or Stream > Failure to follow this advice may result in non-deterministic behavior.
This commit is contained in:
@@ -1 +1 @@
|
||||
2892
|
||||
2900
|
||||
@@ -63,48 +63,52 @@ public class CommandBlockCommand extends Command {
|
||||
if (userFound) pattern = Pattern.compile(userMatcher.group(1));
|
||||
else pattern = Pattern.compile(uuidMatcher.group(1));
|
||||
|
||||
for (final PlayerEntry entry : bot.players.list) {
|
||||
final String username = entry.profile.getName();
|
||||
final String uuid = entry.profile.getIdAsString();
|
||||
synchronized (bot.players.list) {
|
||||
for (final PlayerEntry entry : bot.players.list) {
|
||||
final String username = entry.profile.getName();
|
||||
final String uuid = entry.profile.getIdAsString();
|
||||
|
||||
if (!pattern.matcher(userFound ? username : uuid).matches()) continue;
|
||||
if (!pattern.matcher(userFound ? username : uuid).matches()) continue;
|
||||
|
||||
String replacedCommand;
|
||||
String replacedCommand;
|
||||
|
||||
if (userFound)
|
||||
replacedCommand = new StringBuilder(command).replace(userMatcher.start(), userMatcher.end(), username).toString();
|
||||
else
|
||||
replacedCommand = new StringBuilder(command).replace(uuidMatcher.start(), uuidMatcher.end(), uuid).toString();
|
||||
if (userFound)
|
||||
replacedCommand = new StringBuilder(command).replace(userMatcher.start(), userMatcher.end(), username).toString();
|
||||
else
|
||||
replacedCommand = new StringBuilder(command).replace(uuidMatcher.start(), uuidMatcher.end(), uuid).toString();
|
||||
|
||||
replacedCommand = replacedCommand
|
||||
.replace("{username}", username)
|
||||
.replace("{uuid}", uuid);
|
||||
replacedCommand = replacedCommand
|
||||
.replace("{username}", username)
|
||||
.replace("{uuid}", uuid);
|
||||
|
||||
if (
|
||||
!replacedCommand.contains("{username}") &&
|
||||
!replacedCommand.contains("{uuid}") &&
|
||||
!USER_PATTERN.matcher(username).find() &&
|
||||
!UUID_PATTERN.matcher(username).find()
|
||||
) {
|
||||
runCommand(bot, context, replacedCommand, entry);
|
||||
if (
|
||||
!replacedCommand.contains("{username}") &&
|
||||
!replacedCommand.contains("{uuid}") &&
|
||||
!USER_PATTERN.matcher(username).find() &&
|
||||
!UUID_PATTERN.matcher(username).find()
|
||||
) {
|
||||
runCommand(bot, context, replacedCommand, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (command.contains("{username}") || command.contains("{uuid}")) {
|
||||
for (final PlayerEntry entry : bot.players.list) {
|
||||
final String username = entry.profile.getName();
|
||||
final String uuid = entry.profile.getIdAsString();
|
||||
synchronized (bot.players.list) {
|
||||
for (final PlayerEntry entry : bot.players.list) {
|
||||
final String username = entry.profile.getName();
|
||||
final String uuid = entry.profile.getIdAsString();
|
||||
|
||||
final String replacedCommand = command
|
||||
.replace("{username}", username)
|
||||
.replace("{uuid}", uuid);
|
||||
final String replacedCommand = command
|
||||
.replace("{username}", username)
|
||||
.replace("{uuid}", uuid);
|
||||
|
||||
if (
|
||||
!replacedCommand.contains("{username}") &&
|
||||
!replacedCommand.contains("{uuid}") &&
|
||||
!USER_PATTERN.matcher(username).find() &&
|
||||
!UUID_PATTERN.matcher(username).find()
|
||||
) {
|
||||
runCommand(bot, context, replacedCommand, entry);
|
||||
if (
|
||||
!replacedCommand.contains("{username}") &&
|
||||
!replacedCommand.contains("{uuid}") &&
|
||||
!USER_PATTERN.matcher(username).find() &&
|
||||
!UUID_PATTERN.matcher(username).find()
|
||||
) {
|
||||
runCommand(bot, context, replacedCommand, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -5,7 +5,6 @@ import me.chayapak1.chomens_bot.command.CommandContext;
|
||||
import me.chayapak1.chomens_bot.command.CommandException;
|
||||
import me.chayapak1.chomens_bot.command.TrustLevel;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
public class TestCommand extends Command {
|
||||
public TestCommand () {
|
||||
@@ -20,13 +19,17 @@ public class TestCommand extends Command {
|
||||
|
||||
@Override
|
||||
public Component execute (final CommandContext context) throws CommandException {
|
||||
return Component.translatable(
|
||||
"Hello, World! Username: %s, Sender UUID: %s, Prefix: %s, Flags: %s, Args: %s",
|
||||
Component.text(context.sender.profile.getName()),
|
||||
Component.text(context.sender.profile.getIdAsString()),
|
||||
Component.text(context.prefix),
|
||||
Component.text(String.join(" ", context.getFlags())),
|
||||
Component.text(context.getString(true, false))
|
||||
).color(NamedTextColor.GREEN);
|
||||
for (final Thread thread : Thread.getAllStackTraces().keySet()) {
|
||||
System.out.println(thread);
|
||||
}
|
||||
return null;
|
||||
// return Component.translatable(
|
||||
// "Hello, World! Username: %s, Sender UUID: %s, Prefix: %s, Flags: %s, Args: %s",
|
||||
// Component.text(context.sender.profile.getName()),
|
||||
// Component.text(context.sender.profile.getIdAsString()),
|
||||
// Component.text(context.prefix),
|
||||
// Component.text(String.join(" ", context.getFlags())),
|
||||
// Component.text(context.getString(true, false))
|
||||
// ).color(NamedTextColor.GREEN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,14 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.Clientbound
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
// yes this has been rewritten to be not spammy
|
||||
public class BossbarManagerPlugin implements Listener {
|
||||
private final Bot bot;
|
||||
|
||||
public final Map<UUID, BossBar> serverBossBars = new HashMap<>();
|
||||
private final Map<UUID, BotBossBar> bossBars = new HashMap<>();
|
||||
public final Map<UUID, BossBar> serverBossBars = new ConcurrentHashMap<>();
|
||||
private final Map<UUID, BotBossBar> bossBars = new ConcurrentHashMap<>();
|
||||
|
||||
public boolean enabled = true;
|
||||
public boolean actionBar = false;
|
||||
|
||||
@@ -109,7 +109,9 @@ public class IPFilterPlugin implements Listener {
|
||||
if (localList.isEmpty()) return;
|
||||
|
||||
bot.executorService.submit(() -> {
|
||||
for (final PlayerEntry entry : bot.players.list) check(entry);
|
||||
synchronized (bot.players.list) {
|
||||
for (final PlayerEntry entry : bot.players.list) check(entry);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,11 @@ public class PlayersPlugin implements Listener {
|
||||
for (final UUID uuid : uuids) removePlayer(uuid);
|
||||
}
|
||||
|
||||
private void queryPlayersIP () { for (final PlayerEntry target : list) queryPlayersIP(target); }
|
||||
private void queryPlayersIP () {
|
||||
synchronized (list) {
|
||||
for (final PlayerEntry target : list) queryPlayersIP(target);
|
||||
}
|
||||
}
|
||||
|
||||
private void queryPlayersIP (final PlayerEntry target) {
|
||||
if (target.ip != null) return;
|
||||
@@ -132,40 +136,46 @@ public class PlayersPlugin implements Listener {
|
||||
}
|
||||
|
||||
public final PlayerEntry getEntry (final UUID uuid) {
|
||||
for (final PlayerEntry candidate : list) {
|
||||
if (candidate != null && candidate.profile.getId().equals(uuid)) {
|
||||
return candidate;
|
||||
synchronized (list) {
|
||||
for (final PlayerEntry candidate : list) {
|
||||
if (candidate != null && candidate.profile.getId().equals(uuid)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public final PlayerEntry getEntry (final String username) {
|
||||
for (final PlayerEntry candidate : list) {
|
||||
if (
|
||||
candidate != null &&
|
||||
(
|
||||
candidate.profile.getIdAsString().equals(username) || // checks for a string UUID
|
||||
candidate.profile.getName().equals(username) ||
|
||||
candidate.usernames.contains(username)
|
||||
)
|
||||
) {
|
||||
return candidate;
|
||||
synchronized (list) {
|
||||
for (final PlayerEntry candidate : list) {
|
||||
if (
|
||||
candidate != null &&
|
||||
(
|
||||
candidate.profile.getIdAsString().equals(username) || // checks for a string UUID
|
||||
candidate.profile.getName().equals(username) ||
|
||||
candidate.usernames.contains(username)
|
||||
)
|
||||
) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public final PlayerEntry getEntry (final Component displayName) {
|
||||
for (final PlayerEntry candidate : list) {
|
||||
if (candidate != null && candidate.displayName != null && candidate.displayName.equals(displayName)) {
|
||||
return candidate;
|
||||
synchronized (list) {
|
||||
for (final PlayerEntry candidate : list) {
|
||||
if (candidate != null && candidate.displayName != null && candidate.displayName.equals(displayName)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerEntry getBotEntry () { return getEntry(bot.username); }
|
||||
|
||||
@@ -15,8 +15,8 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.entity.spaw
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundAcceptTeleportationPacket;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
// some part of the code used to be in a test plugin but i thought it would be useful in the future so i moved it here
|
||||
public class PositionPlugin implements Listener {
|
||||
@@ -28,9 +28,9 @@ public class PositionPlugin implements Listener {
|
||||
|
||||
private long tpCommandCooldownTime = 0;
|
||||
|
||||
private final Map<Integer, PlayerEntry> entityIdMap = new HashMap<>();
|
||||
private final Map<Integer, Vector3d> positionMap = new HashMap<>();
|
||||
private final Map<Integer, Rotation> rotationMap = new HashMap<>();
|
||||
private final Map<Integer, PlayerEntry> entityIdMap = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, Vector3d> positionMap = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, Rotation> rotationMap = new ConcurrentHashMap<>();
|
||||
|
||||
public PositionPlugin (final Bot bot) {
|
||||
this.bot = bot;
|
||||
|
||||
@@ -25,20 +25,24 @@ public class TeamPlugin implements Listener {
|
||||
teams.clear();
|
||||
}
|
||||
|
||||
public synchronized Team findTeamByName (final String name) {
|
||||
for (final Team team : new ArrayList<>(teams)) {
|
||||
if (team.teamName.equals(name)) return team;
|
||||
}
|
||||
public Team findTeamByName (final String name) {
|
||||
synchronized (teams) {
|
||||
for (final Team team : new ArrayList<>(teams)) {
|
||||
if (team.teamName.equals(name)) return team;
|
||||
}
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized Team findTeamByMember (final String member) {
|
||||
for (final Team team : new ArrayList<>(teams)) {
|
||||
if (team.players.contains(member)) return team;
|
||||
}
|
||||
public Team findTeamByMember (final String member) {
|
||||
synchronized (teams) {
|
||||
for (final Team team : new ArrayList<>(teams)) {
|
||||
if (team.players.contains(member)) return team;
|
||||
}
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -23,20 +23,24 @@ public class WhitelistPlugin implements Listener {
|
||||
public void enable () {
|
||||
enabled = true;
|
||||
|
||||
for (final PlayerEntry entry : bot.players.list) {
|
||||
if (list.contains(entry.profile.getName())) continue;
|
||||
synchronized (bot.players.list) {
|
||||
for (final PlayerEntry entry : bot.players.list) {
|
||||
if (list.contains(entry.profile.getName())) continue;
|
||||
|
||||
list.add(entry.profile.getName());
|
||||
list.add(entry.profile.getName());
|
||||
|
||||
bot.filterManager.remove(entry.profile.getName());
|
||||
bot.filterManager.remove(entry.profile.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void disable () {
|
||||
enabled = false;
|
||||
|
||||
for (final PlayerEntry entry : bot.players.list) {
|
||||
bot.filterManager.remove(entry.profile.getName());
|
||||
synchronized (bot.players.list) {
|
||||
for (final PlayerEntry entry : bot.players.list) {
|
||||
bot.filterManager.remove(entry.profile.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,10 +61,12 @@ public class WhitelistPlugin implements Listener {
|
||||
public void clear () {
|
||||
list.removeIf(eachPlayer -> !eachPlayer.equals(bot.profile.getName()));
|
||||
|
||||
for (final PlayerEntry entry : bot.players.list) {
|
||||
if (entry.profile.equals(bot.profile)) continue;
|
||||
synchronized (bot.players.list) {
|
||||
for (final PlayerEntry entry : bot.players.list) {
|
||||
if (entry.profile.equals(bot.profile)) continue;
|
||||
|
||||
bot.filterManager.add(entry, "");
|
||||
bot.filterManager.add(entry, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user