WIP: basic strike handling

This commit is contained in:
2025-06-22 10:34:27 +02:00
parent 1aad8f07c4
commit 76297bb3af
4 changed files with 235 additions and 5 deletions

View File

@ -0,0 +1,75 @@
package eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.strike;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import eu.mhsl.craftattack.spawn.core.Main;
import eu.mhsl.craftattack.spawn.core.util.IteratorUtil;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class CordLeak {
private static final Path saveFile = Paths.get(Main.instance().getDataFolder().getAbsolutePath(), "cordleak.json");
private static final Map<UUID, Location> locations = new HashMap<>();
static {
load();
}
private record LocationDto(String world, double x, double y, double z, float yaw, float pitch) {
static LocationDto from(Location loc) {
return new LocationDto(loc.getWorld().getName(), loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
}
Location toLocation() {
return new Location(Bukkit.getWorld(this.world), this.x, this.y, this.z, this.yaw, this.pitch);
}
}
public static void update() {
IteratorUtil.onlinePlayers(player -> locations.put(player.getUniqueId(), player.getLocation()));
Bukkit.getScheduler().runTaskAsynchronously(Main.instance(), CordLeak::save);
}
private static void load() {
if (!Files.exists(saveFile)) return;
try (Reader reader = Files.newBufferedReader(saveFile)) {
Type type = new TypeToken<Map<String, LocationDto>>() {}.getType();
Map<String, LocationDto> raw = new Gson().fromJson(reader, type);
for (Map.Entry<String, LocationDto> entry : raw.entrySet()) {
locations.put(UUID.fromString(entry.getKey()), entry.getValue().toLocation());
}
} catch (IOException e) {
Main.logger().warning("Failed to load CordLeak data: " + e.getMessage());
}
}
private static void save() {
try {
Files.createDirectories(saveFile.getParent());
Map<String, LocationDto> raw = new HashMap<>();
for (Map.Entry<UUID, Location> entry : locations.entrySet()) {
raw.put(entry.getKey().toString(), LocationDto.from(entry.getValue()));
}
try (Writer writer = Files.newBufferedWriter(saveFile)) {
new Gson().toJson(raw, writer);
}
} catch (IOException e) {
Main.logger().warning("Failed to save CordLeak data: " + e.getMessage());
}
}
public static Location getLastKnownLocation(UUID uuid) {
return locations.get(uuid);
}
}

View File

@ -0,0 +1,63 @@
package eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.strike;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import eu.mhsl.craftattack.spawn.core.Main;
import org.bukkit.Bukkit;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
public class InvClear {
private static final Path saveFile = Paths.get(Main.instance().getDataFolder().getAbsolutePath(), "invClear.json");
private static final List<UUID> players = new ArrayList<>();
static {
load();
}
public static void add(UUID player) {
players.add(player);
Bukkit.getScheduler().runTaskAsynchronously(Main.instance(), InvClear::save);
}
public static boolean contains(UUID player) {
return players.contains(player);
}
public static void remove(UUID player) {
players.remove(player);
Bukkit.getScheduler().runTaskAsynchronously(Main.instance(), InvClear::save);
}
private static void load() {
if (!Files.exists(saveFile)) return;
try (Reader reader = Files.newBufferedReader(saveFile)) {
Type type = new TypeToken<List<UUID>>() {}.getType();
List<UUID> loaded = new Gson().fromJson(reader, type);
if (loaded != null) {
players.clear();
players.addAll(loaded);
}
} catch (IOException e) {
Main.logger().warning("Failed to load InvClear data: " + e.getMessage());
}
}
private static void save() {
try {
Files.createDirectories(saveFile.getParent());
try (Writer writer = Files.newBufferedWriter(saveFile)) {
new Gson().toJson(players, writer);
}
} catch (IOException e) {
Main.logger().warning("Failed to save InvClear data: " + e.getMessage());
}
}
}

View File

@ -0,0 +1,12 @@
package eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.strike;
import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
public class OnStrikeActionListener extends ApplianceListener<Strike> {
@EventHandler
public void onJoin(PlayerJoinEvent event) {
this.getAppliance().checkJoin(event.getPlayer());
}
}

View File

@ -3,15 +3,40 @@ package eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.strike;
import eu.mhsl.craftattack.spawn.core.Main; import eu.mhsl.craftattack.spawn.core.Main;
import eu.mhsl.craftattack.spawn.core.api.server.HttpServer; import eu.mhsl.craftattack.spawn.core.api.server.HttpServer;
import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
import eu.mhsl.craftattack.spawn.core.util.IteratorUtil;
import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.teams.Teams; import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.teams.Teams;
import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.teams.VaroTeam; import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.teams.VaroTeam;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentBuilder;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.util.Ticks;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class Strike extends Appliance { public class Strike extends Appliance {
public Strike() {
Bukkit.getScheduler().scheduleSyncRepeatingTask(
Main.instance(),
CordLeak::update,
Ticks.TICKS_PER_SECOND,
Ticks.TICKS_PER_SECOND * 3
);
}
public void leakCoordinates() {
}
@Override @Override
public void httpApi(HttpServer.ApiBuilder apiBuilder) { public void httpApi(HttpServer.ApiBuilder apiBuilder) {
record StrikeInfo(List<UUID> users, int totalWeight) { record StrikeInfo(List<UUID> users, int totalWeight) {
@ -22,16 +47,71 @@ public class Strike extends Appliance {
data.users.stream().map(UUID::toString).collect(Collectors.joining(", "))) data.users.stream().map(UUID::toString).collect(Collectors.joining(", ")))
); );
VaroTeam team = null; VaroTeam select = null;
for(UUID uuid : data.users) { for(UUID uuid : data.users) {
team = this.queryAppliance(Teams.class).getTeamFromPlayer(uuid); select = this.queryAppliance(Teams.class).getTeamFromPlayer(uuid);
if(team != null) break; if(select != null) break;
} }
Objects.requireNonNull(team); Objects.requireNonNull(select);
VaroTeam team = select;
System.out.println(team.name); switch(data.totalWeight) {
case 1 -> {
Main.logger().info(String.format("Cord leak for Team %s", team.name));
ComponentBuilder<TextComponent, TextComponent.Builder> text = Component.text()
.append(
Component.text(
String.format("Das Team %s hat einen Strike erhalten. Daher werden folgende Koordinaten des Teams veröffentlicht:", team.name),
NamedTextColor.RED
)
);
data.users.forEach(uuid -> {
OfflinePlayer player = Bukkit.getOfflinePlayer(uuid);
Location cords = CordLeak.getLastKnownLocation(uuid);
if(cords == null) return;
text.appendNewline();
text.append(Component.text(Objects.requireNonNull(player.getName()), NamedTextColor.DARK_AQUA));
text.append(Component.text(": ", NamedTextColor.GRAY));
text.append(Component.text(
String.format(
"(%s) %d, %d, %d",
cords.getWorld().getName(),
cords.getBlockX(),
cords.getBlockY(),
cords.getBlockZ()
),
NamedTextColor.AQUA)
);
});
IteratorUtil.onlinePlayers(player -> player.sendMessage(text));
}
case 2 -> team.members.forEach(member -> {
Optional<Player> player = Optional.ofNullable(Bukkit.getPlayer(member.player.getUniqueId()));
player.ifPresentOrElse(
p -> p.getInventory().clear(),
() -> InvClear.add(member.player.getUniqueId())
);
});
case 3 -> team.members.forEach(member -> member.player.banPlayer("projektausschluss"));
}
return HttpServer.nothing; return HttpServer.nothing;
}); });
} }
public void checkJoin(@NotNull Player player) {
if(InvClear.contains(player.getUniqueId())) {
player.getInventory().clear();
InvClear.remove(player.getUniqueId());
}
}
@Override
protected @NotNull List<Listener> listeners() {
return List.of(new OnStrikeActionListener());
}
} }