pala M-faction-2: claims chunks + protection territoire

This commit is contained in:
Anaïs Saraiva
2026-10-19 04:31:30 +02:00
parent 4379f63e8a
commit 7da06c6581
6 changed files with 102 additions and 1 deletions
+4
View File
@@ -612,6 +612,10 @@ avant M4 (TODO:crafts-machines).
UNVERIFIED en jeu. UNVERIFIED en jeu.
- M-faction-1c LIVRE 2026-10-19 ~04:20 : /f desc (chef, 140 car., sans speciaux — wiki) + - M-faction-1c LIVRE 2026-10-19 ~04:20 : /f desc (chef, 140 car., sans speciaux — wiki) +
/f help. VERIFIE : build SUCCESSFUL, boot Done, 0 erreur. UNVERIFIED en jeu. /f help. VERIFIE : build SUCCESSFUL, boot Done, 0 erreur. UNVERIFIED en jeu.
- M-faction-2 LIVRE 2026-10-19 ~04:30 : claims de chunks (/f claim/unclaim/unclaimall,
quota factionMaxClaims=10 UNVERIFIED) + protection stricte (membres+OP, wilderness libre).
Lecon : ResourceKey.location() n'existe plus en 26.3 -> identifier(). Grades/regions/elo :
M-faction-3. VERIFIE : build SUCCESSFUL, boot Done, 0 erreur. UNVERIFIED en jeu.
- M-palaforge LIVRE 2026-10-19 ~03:55 : bloc + BE partagee (3e mode) + gate mineur 14 + - M-palaforge LIVRE 2026-10-19 ~03:55 : bloc + BE partagee (3e mode) + gate mineur 14 +
table fonte wiki §3.2 (31 items, ratio floor usure) + fuels bois (+buche/planches/baton, table fonte wiki §3.2 (31 items, ratio floor usure) + fuels bois (+buche/planches/baton,
lave exclue : seau non rendu) + craft (1 findium + 4 furnaces + 4 briques, positions lave exclue : seau non rendu) + craft (1 findium + 4 furnaces + 4 briques, positions
@@ -85,6 +85,9 @@ public final class PalaConfig {
// M-afk (wiki reglement/grades) : kick apres N minutes sans activite (defaut 10). // M-afk (wiki reglement/grades) : kick apres N minutes sans activite (defaut 10).
public int afkKickMinutes = 10; public int afkKickMinutes = 10;
// M-faction-2 : claims de chunks (quota par faction, defaut 10, UNVERIFIED).
public int factionMaxClaims = 10;
// M-rtp (wiki commandes) : cooldown minutes entre deux /rtp (wiki : 15). // M-rtp (wiki commandes) : cooldown minutes entre deux /rtp (wiki : 15).
public int rtpCooldownMinutes = 15; public int rtpCooldownMinutes = 15;
// Rayon max du /rtp autour du spawn (blocs). UNVERIFIED (wiki : "aleatoire", sans borne). // Rayon max du /rtp autour du spawn (blocs). UNVERIFIED (wiki : "aleatoire", sans borne).
@@ -234,7 +237,8 @@ public final class PalaConfig {
"crusherResults", "crusherFuels", "crusherInfiniteFuels", "crusherResults", "crusherFuels", "crusherInfiniteFuels",
"furnaceSmelts", "furnaceFuels", "furnaceSmelts", "furnaceFuels",
"serverName", "wikiUrl", "discordUrl", "shopUrl", "serverName", "wikiUrl", "discordUrl", "shopUrl",
"afkKickMinutes", "rtpCooldownMinutes", "rtpRadius"); "afkKickMinutes", "rtpCooldownMinutes", "rtpRadius",
"factionMaxClaims");
boolean complete = true; boolean complete = true;
try (Reader keysReader = Files.newBufferedReader(path)) { try (Reader keysReader = Files.newBufferedReader(path)) {
com.google.gson.JsonObject obj = com.google.gson.JsonObject obj =
@@ -30,6 +30,8 @@ public final class PalaFactions {
public List<String> members = new ArrayList<>(); public List<String> members = new ArrayList<>();
public String description = ""; public String description = "";
public List<String> invites = new ArrayList<>(); public List<String> invites = new ArrayList<>();
// M-faction-2 : chunks revendiques ("dimension:x:z").
public List<String> claims = new ArrayList<>();
} }
private final Map<String, Faction> factions = new HashMap<>(); private final Map<String, Faction> factions = new HashMap<>();
@@ -66,6 +68,16 @@ public final class PalaFactions {
dirty = true; dirty = true;
} }
/** Faction proprietaire du chunk (cle "dimension:x:z"), ou null. */
public Faction byClaim(String key) {
for (Faction faction : factions.values()) {
if (faction.claims != null && faction.claims.contains(key)) {
return faction;
}
}
return null;
}
public void remove(String name) { public void remove(String name) {
if (factions.remove(name.toLowerCase(java.util.Locale.ROOT)) != null) { if (factions.remove(name.toLowerCase(java.util.Locale.ROOT)) != null) {
dirty = true; dirty = true;
@@ -99,6 +111,9 @@ public final class PalaFactions {
if (faction.invites == null) { if (faction.invites == null) {
faction.invites = new ArrayList<>(); faction.invites = new ArrayList<>();
} }
if (faction.claims == null) {
faction.claims = new ArrayList<>();
}
factions.put(String.valueOf(entry.getKey()), faction); factions.put(String.valueOf(entry.getKey()), faction);
} }
} }
@@ -35,6 +35,7 @@ public final class PalaEvents {
public static void registerAll() { public static void registerAll() {
PalaAfk.register(); PalaAfk.register();
PalaFactionProtect.register();
PalaArmorEvents.register(); PalaArmorEvents.register();
PalaItemUseEvents.register(); PalaItemUseEvents.register();
PalaToolEvents.register(); PalaToolEvents.register();
@@ -0,0 +1,77 @@
package fr.surviepote.pala.events;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import fr.surviepote.pala.core.PalaFactions;
// M-faction-2 (wiki Gestion faction + grades) : protection des chunks revendiques.
// Sans systeme de grades/regions (GUI, M-faction-3) : regle stricte — seuls les membres
// et les OP peuvent casser/poser/utiliser dans un chunk claim. Wilderness = libre.
public final class PalaFactionProtect {
private PalaFactionProtect() {
}
/** Cle de chunk "dimension:x:z". */
public static String key(ServerLevel level, BlockPos pos) {
return level.dimension().identifier().toString() + ":"
+ (pos.getX() >> 4) + ":" + (pos.getZ() >> 4);
}
/** Vrai si le joueur peut agir ici (membre de la faction proprietaire, ou OP, ou libre). */
public static boolean canAct(ServerPlayer player, ServerLevel level, BlockPos pos) {
PalaFactions.Faction owner =
PalaFactions.get().byClaim(key(level, pos));
if (owner == null) {
return true;
}
if (owner.members.contains(player.getUUID().toString())) {
return true;
}
return net.minecraft.commands.Commands.LEVEL_ADMINS
.check(player.permissions());
}
public static void register() {
PlayerBlockBreakEvents.BEFORE.register(PalaFactionProtect::beforeBreak);
UseBlockCallback.EVENT.register(PalaFactionProtect::onUseBlock);
}
private static boolean beforeBreak(Level level, Player player, BlockPos pos, BlockState state,
BlockEntity blockEntity) {
if (level.isClientSide() || !(level instanceof ServerLevel sl)
|| !(player instanceof ServerPlayer sp)) {
return true;
}
if (canAct(sp, sl, pos)) {
return true;
}
sp.sendSystemMessage(Component.literal("§cTerritoire de faction protege."));
return false;
}
private static InteractionResult onUseBlock(Player player, Level level, InteractionHand hand,
BlockHitResult hit) {
if (level.isClientSide() || !(level instanceof ServerLevel sl)
|| !(player instanceof ServerPlayer sp)) {
return InteractionResult.PASS;
}
if (canAct(sp, sl, hit.getBlockPos())) {
return InteractionResult.PASS;
}
return InteractionResult.FAIL;
}
}
Binary file not shown.