Skip to content
Open
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
2 changes: 2 additions & 0 deletions src/main/java/io/icker/factions/FactionsMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.icker.factions.command.CreateCommand;
import io.icker.factions.command.DeclareCommand;
import io.icker.factions.command.DisbandCommand;
import io.icker.factions.command.FriendlyFireCommand;
import io.icker.factions.command.HomeCommand;
import io.icker.factions.command.InfoCommand;
import io.icker.factions.command.InviteCommand;
Expand Down Expand Up @@ -98,6 +99,7 @@ private static void registerCommands(
new CreateCommand(),
new DeclareCommand(),
new DisbandCommand(),
new FriendlyFireCommand(),
new HomeCommand(),
new InfoCommand(),
new InviteCommand(),
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/io/icker/factions/api/persistents/Faction.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ public class Faction {
@Field("Open")
private boolean open;

/** Whether friendly fire is enabled for this faction (null = use global config) */
@Field("FriendlyFire")
private Boolean friendlyFire;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using a boxed boolean type, this should use an enum with either true, false, or use config. I don't think our serialization system can handle this correctly as is and it would be more readable.


@Field("Power")
private int power;

Expand Down Expand Up @@ -153,6 +157,10 @@ public boolean isOpen() {
return open;
}

public boolean isFriendlyFireEnabled() {
return friendlyFire != null ? friendlyFire : FactionsMod.CONFIG.FRIENDLY_FIRE;
}

public void setName(String name) {
this.name = name;
FactionEvents.MODIFY.invoker().onModify(this);
Expand All @@ -178,6 +186,11 @@ public void setOpen(boolean open) {
FactionEvents.MODIFY.invoker().onModify(this);
}

public void setFriendlyFire(boolean enabled) {
this.friendlyFire = enabled;
FactionEvents.MODIFY.invoker().onModify(this);
}

public int adjustPower(int adjustment) {
int maxPower = calculateMaxPower();
int newPower = Math.min(Math.max(0, power + adjustment), maxPower);
Expand Down
52 changes: 52 additions & 0 deletions src/main/java/io/icker/factions/command/FriendlyFireCommand.java
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having a new command for the friendly fire option, it should be added to the existing modify command

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.icker.factions.command;

import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.tree.LiteralCommandNode;

import io.icker.factions.api.persistents.Faction;
import io.icker.factions.util.Command;
import io.icker.factions.util.Message;

import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;

public class FriendlyFireCommand implements Command {
private int execute(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
boolean enabled = BoolArgumentType.getBool(context, "enabled");

ServerCommandSource source = context.getSource();
ServerPlayerEntity player = source.getPlayerOrThrow();

Faction faction = Command.getUser(player).getFaction();

faction.setFriendlyFire(enabled);

new Message(
Text.translatable(
enabled
? "factions.command.friendlyfire.success.enabled"
: "factions.command.friendlyfire.success.disabled"))
.format(enabled ? Formatting.GREEN : Formatting.RED)
.prependFaction(faction)
.send(player, false);

return 1;
}

public LiteralCommandNode<ServerCommandSource> getNode() {
return CommandManager.literal("friendlyfire")
.requires(
Requires.multiple(
Requires.hasPerms("factions.friendlyfire.toggle", 0),
Requires.isLeader()))
.then(
CommandManager.argument("enabled", BoolArgumentType.bool())
.executes(this::execute))
.build();
}
}
1 change: 1 addition & 0 deletions src/main/java/io/icker/factions/core/FactionsManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class FactionsManager {

public static void register() {
ServerLifecycleEvents.SERVER_STARTED.register(FactionsManager::serverStarted);
ServerLifecycleEvents.SERVER_STOPPING.register(FactionsManager::serverStopping);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh sorry, this was supposed to be for another pr

also includes: #148 (comment)

Copy link
Author

@choke-dev choke-dev Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so basically, whenever the server shuts down before the save interval is triggered, all data stored in memory is just gone which gives me an "Invalid player data" error when attempting to join my dev server

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The server saves itself as it stops, I’m not sure why this is needed

FactionEvents.MODIFY.register(FactionsManager::factionModified);
FactionEvents.MEMBER_JOIN.register(FactionsManager::memberChange);
FactionEvents.MEMBER_LEAVE.register(FactionsManager::memberChange);
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/io/icker/factions/core/InteractionManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ private static ActionResult onUseInventory(PlayerEntity player, BlockPos pos, Wo
}

private static ActionResult isInvulnerableTo(Entity source, Entity target) {
if (!source.isPlayer() || FactionsMod.CONFIG.FRIENDLY_FIRE) return ActionResult.PASS;
if (!source.isPlayer()) return ActionResult.PASS;

User sourceUser = User.get(source.getUuid());
User targetUser = User.get(target.getUuid());
Expand All @@ -274,6 +274,10 @@ private static ActionResult isInvulnerableTo(Entity source, Entity target) {
Faction sourceFaction = sourceUser.getFaction();
Faction targetFaction = targetUser.getFaction();

if (targetFaction.isFriendlyFireEnabled()) {
return ActionResult.PASS;
}

if (sourceFaction.equals(targetFaction)) {
return ActionResult.SUCCESS;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/icker/factions/core/ServerManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static void register() {
MiscEvents.ON_SAVE.register(ServerManager::save);
}

private static void save(MinecraftServer server) {
public static void save(MinecraftServer server) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this changed?

Claim.save();
Faction.save();
User.save();
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/io/icker/factions/ui/ModifyGui.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public ModifyGui(ServerPlayerEntity player, Faction faction, @Nullable Runnable
new ColorGui(player, faction, this::open);
}));
this.setSlot(5, buildOpenFactionButton(faction));
this.setSlot(6, buildFriendlyFireButton(faction));

this.setSlot(
8,
Expand Down Expand Up @@ -112,6 +113,26 @@ private GuiElementBuilder buildOpenFactionButton(Faction faction) {
});
}

private GuiElementBuilder buildFriendlyFireButton(Faction faction) {
boolean enabled = faction.isFriendlyFireEnabled();
return new GuiElementBuilder(Items.PLAYER_HEAD)
.setProfileSkinTexture(
enabled ? Icons.GUI_TESSERACT_RED : Icons.GUI_TESSERACT_BLUE)
.setName(
Text.translatable(
enabled
? "factions.gui.modify.friendly_fire.enabled"
: "factions.gui.modify.friendly_fire.disabled"))
.addLoreLine(
Text.translatable("factions.gui.modify.friendly_fire.lore")
.formatted(Formatting.GRAY))
.setCallback(
(index, clickType, actionType) -> {
faction.setFriendlyFire(!faction.isFriendlyFireEnabled());
this.setSlot(index, buildFriendlyFireButton(faction));
});
}

private void execName(Faction faction) {
InputGui inputGui = new InputGui(player);

Expand Down
41 changes: 6 additions & 35 deletions src/main/resources/data/factions/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@
"factions.gui.admin.options.reload_dynmap": "Reload DynMap markers",
"factions.gui.admin.options.reload_dynmap.lore": "Reloads DynMap markers.",
"factions.gui.admin.options.reload_dynmap.success": "Reloaded DynMap markers",

"factions.gui.spoof.title": "Specify a player...",
"factions.gui.spoof.default": "Player Name",
"factions.gui.spoof.fail.invalid_name": "Invalid name %s!",
"factions.gui.spoof.fail.no_player": "No such player %s!",
"factions.gui.spoof.success": "Set spoof to player %s",

"factions.gui.power.setfaction.title": "Specify a faction...",
"factions.gui.power.setfaction.default": "Faction Name",
"factions.gui.power.setfaction.fail.no_faction": "No such faction!",
Expand All @@ -34,7 +32,6 @@
"factions.gui.power.success.removed.admin": "Removed %d power",
"factions.gui.power.success.added.faction": "Admin %s added %d power",
"factions.gui.power.success.removed.faction": "Admin %s removed %d power",

"factions.gui.info.title": "Faction info",
"factions.gui.info.owner": "Owner: ",
"factions.gui.info.description": "Description: ",
Expand All @@ -51,11 +48,9 @@
"factions.gui.info.enemies.some": "Enemy factions (%s): ",
"factions.gui.info.settings": "Faction settings",
"factions.gui.info.settings.lore": "Click to change settings",

"factions.gui.list.title": "Factions list",
"factions.gui.list.entry.view_info": "Click to view faction info.",
"factions.gui.list.entry.teleport": "Right-click to teleport to faction home.",

"factions.gui.members.title": "%s members list (%s)",
"factions.gui.members.entry.unknown_player": "No info available",
"factions.gui.members.entry.info.rank": "Rank: %s",
Expand All @@ -74,7 +69,6 @@
"factions.gui.members.entry.manage.kick.confirm.no": "Go back",
"factions.gui.members.entry.manage.kick.result.actor": "Kicked %s",
"factions.gui.members.entry.manage.kick.result.subject": "You have been kicked from the faction by %s",

"factions.gui.modify.title": "Faction settings",
"factions.gui.modify.change_name": "Change name",
"factions.gui.modify.change_name.input.title": "Specify a name...",
Expand Down Expand Up @@ -126,14 +120,17 @@
"factions.gui.modify.faction_type": "Faction type: %s",
"factions.gui.modify.faction_type.public": "Public",
"factions.gui.modify.faction_type.invite": "Invite only",

"factions.gui.modify.friendly_fire.enabled": "Friendly Fire: Enabled",
"factions.gui.modify.friendly_fire.disabled": "Friendly Fire: Disabled",
"factions.gui.modify.friendly_fire.lore": "Click to toggle friendly fire for your faction",
"factions.command.friendlyfire.success.enabled": "Friendly fire has been enabled for your faction",
"factions.command.friendlyfire.success.disabled": "Friendly fire has been disabled for your faction",
"factions.gui.generic.unknown_player": "{Unknown Player}",
"factions.gui.generic.close": "Close",
"factions.gui.generic.confirm": "Confirm",
"factions.gui.generic.back": "Go back",
"factions.gui.generic.next_page": "Next page",
"factions.gui.generic.previous_page": "Previous page",

"factions.command.claim.list": "You have %s claim(s)",
"factions.command.claim.add.fail.already_owned.single": "%s faction already owns this chunk",
"factions.command.claim.add.fail.already_owned.single.your": "Your",
Expand All @@ -156,12 +153,10 @@
"factions.command.claim.set_access_level.fail.min_level": "Cannot decrease access level as it is already at its minimum.",
"factions.command.claim.set_access_level.fail.rank_too_low": "Cannot decrease access level from above your rank",
"factions.command.claim.set_access_level.success": "Claim (%d, %d) changed to level %s by %s",

"factions.command.create.fail.blacklisted_name": "Cannot create a faction with this name as it is on the blacklist",
"factions.command.create.fail.name_too_long": "Cannot create a faction with this name as it is too long",
"factions.command.create.fail.name_taken": "Cannot create a faction as a one with that name already exists",
"factions.command.create.success": "Successfully created faction",

"factions.command.declare.fail.nonexistent_faction": "Cannot change faction relationship with a faction that doesn't exist",
"factions.command.declare.fail.own_faction": "Cannot use the declare command on your own faction",
"factions.command.declare.fail.no_change": "That faction relationship has already been declared with this faction",
Expand All @@ -172,23 +167,19 @@
"factions.command.declare.success.status.ally": "allies",
"factions.command.declare.success.status.enemy": "enemies",
"factions.command.declare.success.status.neutral": "neutral",

"factions.command.disband.fail.safe_not_empty": "Your faction safe isn't empty.",
"factions.command.disband.fail.safe_not_empty.prompt": "\nContinue and move the items to your inventory",
"factions.command.disband.fail.safe_not_empty.prompt.hover": "Click to confirm",
"factions.command.disband.success": "%s disbanded the faction",

"factions.command.home.warp.fail.no_home": "No faction home set",
"factions.command.home.warp.fail.no_world": "Cannot find dimension",
"factions.command.home.warp.fail.no_claim": "Cannot warp home to an unclaimed chunk",
"factions.command.home.warp.fail.combat": "Cannot warp while in combat",
"factions.command.home.warp.success": "Warped to faction home",
"factions.command.home.fail.no_claim": "Cannot set home to an unclaimed chunk",
"factions.command.home.set.success": "Home set to %.2f, %.2f, %.2f by %s",

"factions.command.info.fail.no_faction": "Command can only be used whilst in a faction",
"factions.command.info.fail.nonexistent_faction": "Faction does not exist",

"factions.command.invite.list": "You have %s outgoing invite(s)",
"factions.command.invite.add.fail.already_invited": "%s was already invited to your faction",
"factions.command.invite.add.fail.already_member": "%s is already in your faction",
Expand All @@ -197,70 +188,57 @@
"factions.command.invite.add.success.subject.hover": "Click to join",
"factions.command.invite.remove.success": "%s is no longer invited to your faction",
"factions.command.invite.remove.fail": "Could not find invite for %s",

"factions.command.join.fail.nonexistent_faction": "Cannot join faction as none exist with that name",
"factions.command.join.fail.private_no_invite": "Cannot join faction as it is not open and you are not invited",
"factions.command.join.fail.faction_full": "Cannot join faction as it is currently full",
"factions.command.join.success": "%s joined",

"factions.command.kick.fail.self": "Cannot kick yourself",
"factions.command.kick.fail.other_faction": "Cannot kick someone that is not in your faction",
"factions.command.kick.fail.high_rank": "Cannot kick members with a higher of equivalent rank",
"factions.command.kick.success.actor": "Kicked %s",
"factions.command.kick.success.subject": "You have been kicked from the faction by %s",

"factions.command.leave.success.actor": "You have left this faction.",
"factions.command.leave.success.subject": "%s left",

"factions.command.map.title": "Faction Map",
"factions.command.map.you_wilderness": "<You> <Wilderness>",
"factions.command.map.you_owner": "<You> %s",

"factions.command.members.fail.no_faction": "Command can only be used whilst in a faction",
"factions.command.members.faction.nonexistent_faction": "Faction does not exist",
"factions.command.members.faction.title": "Total Members: %s",
"factions.command.members.faction.owner": "Owner: %s",
"factions.command.members.faction.leaders": "Leaders (%s): %s",
"factions.command.members.faction.commanders": "Commanders (%s): %s",
"factions.command.members.faction.members": "Members (%s): %s",

"factions.command.modify.name.fail.blacklisted_name": "Cannot rename a faction to that name as it is on the blacklist",
"factions.command.modify.name.fail.name_too_long": "Cannot rename a faction to this that as it is too long",
"factions.command.modify.name.fail.name_taken": "A faction with that name already exists",
"factions.command.modify.open.success": "Successfully updated faction to ",

"factions.command.permissions.change.fail.no_faction": "You must be in a faction and you must provide a valid faction",
"factions.command.permissions.change.fail.invalid_permission": "Not a valid permission",
"factions.command.permissions.change.fail.already_exists": "Could not change because the permission already exists",
"factions.command.permissions.change.fail.doesnt_exist": "Could not change because the permission doesn't exist",
"factions.command.permissions.change.success": "Successfully changed permissions",
"factions.command.permissions.guest.fail.no_faction": "You must be in a faction",

"factions.command.permissions.list.title": "%s has the permissions: %s",
"factions.command.permissions.list_guest.title": "Guests have the permissions: %s",

"factions.command.rank.guest": "guest",
"factions.command.rank.member": "member",
"factions.command.rank.commander": "commander",
"factions.command.rank.leader": "leader",

"factions.command.rank.promote.fail.self": "You cannot promote yourself",
"factions.command.rank.promote.fail.not_in_faction": "%s is not in your faction",
"factions.command.rank.promote.fail.leader": "You cannot promote a Leader to Owner",
"factions.command.rank.promote.fail.owner": "You cannot promote the Owner",
"factions.command.rank.promote.success": "Promoted %s to %s",

"factions.command.rank.demote.fail.self": "You cannot demote yourself",
"factions.command.rank.demote.fail.not_in_faction": "%s is not in your faction",
"factions.command.rank.demote.fail.guest": "You cannot demote a Guest",
"factions.command.rank.demote.fail.leader": "You cannot demote a Leader",
"factions.command.rank.demote.fail.owner": "You cannot demote the Owner",
"factions.command.rank.demote.success": "Demoted %s to %s",

"factions.command.rank.transfer.fail.self": "You cannot transfer ownership to yourself",
"factions.command.rank.transfer.fail.not_in_faction": "%s is not in your faction",
"factions.command.rank.transfer.success": "Transferred ownership to %s",

"factions.command.settings.chat": "Successfully set your chat preference",
"factions.command.settings.chat.faction": "Faction",
"factions.command.settings.chat.focus": "Focus",
Expand All @@ -271,17 +249,14 @@
"factions.command.settings.sound.none": "None",
"factions.command.settings.sound.warnings": "Warnings",
"factions.command.settings.radar": "Successfully toggled claim radar",

"factions.chat.in_faction_symbol": "F",
"factions.chat.faction_chat_when_not_in_faction": "You can't send a message to faction chat if you aren't in a faction.",
"factions.chat.faction_chat_when_not_in_faction.hover": "Click to switch to global chat",

"factions.gui.safe.title": "%s's Safe",
"factions.events.lose_power_by_death": "%s lost %d power from dying",
"factions.events.get_power_by_tick": "%s gained %d power from surviving",
"factions.events.no_enderchests_without_faction": "Cannot use enderchests when not in a faction",
"factions.events.member_returns": "Welcome back %s!",

"factions.interactions.cannot_do": "Cannot %s here",
"factions.interactions.name.break_blocks": "break blocks",
"factions.interactions.name.use_blocks": "use blocks",
Expand All @@ -290,20 +265,16 @@
"factions.interactions.name.attack_entities": "attack entities",
"factions.interactions.name.use_entities": "use entities",
"factions.interactions.name.use_inventory": "use inventory",

"factions.level.minecraft:overworld": "Overworld",
"factions.level.minecraft:the_nether": "The Nether",
"factions.level.minecraft:the_end": "The End",

"factions.events.autoclaim.fail": "Not enough faction power to claim chunk, autoclaim toggled off",
"factions.events.autoclaim.success": "Chunk (%d, %d) claimed by %s",
"factions.radar.wilderness": "Wilderness",

"factions.factionless": "[FACTIONLESS]",
"factions.default_description": "No description set",
"factions.default_motd": "No faction MOTD set",

"factions.papi.chat.global": "Global Chat",
"factions.papi.chat.faction": "Faction Chat",
"factions.papi.factionless": "FACTIONLESS"
}
}
Loading