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: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/cache@v2
- uses: actions/cache@v4
with:
path: |
~/.gradle/loom-cache
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ dependencies {

modImplementation 'xyz.nucleoid:plasmid:0.6.3-SNAPSHOT+1.21.4'
modImplementation include('xyz.nucleoid:more-codecs:0.3.5+1.21.2')
modImplementation include("me.lucko:fabric-permissions-api:${project.permission_api_version}")
}

processResources {
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ fabric_version=0.110.5+1.21.4
mod_version=1.0.3
maven_group=xyz.nucleoid
archives_base_name=game-parties
permission_api_version=0.3.3
47 changes: 32 additions & 15 deletions src/main/java/xyz/nucleoid/parties/PartyCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.minecraft.command.argument.EntityArgumentType;
import net.minecraft.command.argument.GameProfileArgumentType;
import net.minecraft.command.argument.UuidArgumentType;
Expand All @@ -25,18 +26,21 @@ public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
dispatcher.register(
literal("party")
.then(literal("list")
.requires(source -> source.hasPermissionLevel(2))
.requires(Permissions.require("party.command.list", 2))
.executes(PartyCommand::listParties)
)
.then(literal("invite")
.then(argument("player", EntityArgumentType.player())
.requires(Permissions.require("party.command.invite", 0))
.then(argument("players", EntityArgumentType.players())
.executes(PartyCommand::invitePlayer)
))
.then(literal("kick")
.requires(Permissions.require("party.command.kick", 0))
.then(argument("player", GameProfileArgumentType.gameProfile())
.executes(PartyCommand::kickPlayer)
))
.then(literal("transfer")
.requires(Permissions.require("party.command.transfer", 0))
.then(argument("player", EntityArgumentType.player())
.executes(PartyCommand::transferToPlayer)
))
Expand All @@ -51,7 +55,7 @@ public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
.then(literal("leave").executes(PartyCommand::leave))
.then(literal("disband").executes(PartyCommand::disband))
.then(literal("add")
.requires(source -> source.hasPermissionLevel(2))
.requires(Permissions.require("party.command.add", 2))
.then(argument("player", EntityArgumentType.player())
.then(argument("owner", EntityArgumentType.player())
.executes(PartyCommand::addPlayerByOwner)
Expand All @@ -62,7 +66,7 @@ public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
)
)
.then(literal("remove")
.requires(source -> source.hasPermissionLevel(2))
.requires(Permissions.require("party.command.remove", 2))
.then(argument("player", EntityArgumentType.player())
.executes(PartyCommand::removePlayer)
))
Expand Down Expand Up @@ -123,20 +127,33 @@ private static int invitePlayer(CommandContext<ServerCommandSource> ctx) throws
var source = ctx.getSource();
var owner = source.getPlayer();

var player = EntityArgumentType.getPlayer(ctx, "player");
var players = EntityArgumentType.getPlayers(ctx, "players");

int inviteCount = 0;
var partyManager = PartyManager.get(source.getServer());
var result = partyManager.invitePlayer(PlayerRef.of(owner), PlayerRef.of(player));
if (result.isOk()) {
source.sendFeedback(() -> PartyTexts.invitedSender(player).formatted(Formatting.GOLD), false);
for (var player : players) {
var result = partyManager.invitePlayer(PlayerRef.of(owner), PlayerRef.of(player));
if (result.isOk() | result.error() == PartyError.ALREADY_INVITED) {
if (players.size() == 1) {
source.sendFeedback(() -> PartyTexts.invitedSender(player, result.error() == PartyError.ALREADY_INVITED).formatted(Formatting.GOLD), false);
} else {
inviteCount++;
}

var notification = PartyTexts.invitedReceiver(owner, result.party().getUuid())
.formatted(Formatting.GOLD);
var notification = PartyTexts.invitedReceiver(owner, result.party().getUuid())
.formatted(Formatting.GOLD);

player.sendMessage(notification, false);
} else {
var error = result.error();
source.sendError(PartyTexts.displayError(error, player));
player.sendMessage(notification, false);
} else {
var error = result.error();
if (!(players.size() > 1 && (player == owner | error == PartyError.ALREADY_PARTY_MEMBER))) {
source.sendError(PartyTexts.displayError(error, player));
}
}
}
if (inviteCount > 0) {
int finalInviteCount = inviteCount;
source.sendFeedback(() -> PartyTexts.invitedSender(finalInviteCount).formatted(Formatting.GOLD), false);
}

return Command.SINGLE_SUCCESS;
Expand All @@ -155,7 +172,7 @@ private static int kickPlayer(CommandContext<ServerCommandSource> ctx) throws Co
if (result.isOk()) {
var party = result.party();

var message = PartyTexts.kickedSender(owner);
var message = PartyTexts.kickedSender(profile);
party.getMemberPlayers().sendMessage(message.formatted(Formatting.GOLD));

PlayerRef.of(profile).ifOnline(server, player -> {
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/xyz/nucleoid/parties/PartyError.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ public enum PartyError {
DOES_NOT_EXIST,
ALREADY_INVITED,
ALREADY_IN_PARTY,
ALREADY_PARTY_MEMBER,
CANNOT_REMOVE_SELF,
NOT_IN_PARTY,
NOT_INVITED
NOT_INVITED,
NOT_ALLOWED
}
15 changes: 13 additions & 2 deletions src/main/java/xyz/nucleoid/parties/PartyManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.collect.Lists;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
Expand Down Expand Up @@ -96,11 +97,16 @@ private void onPartyOwnerLogOut(ServerPlayerEntity player, Party party) {

public PartyResult invitePlayer(PlayerRef owner, PlayerRef player) {
var party = this.getOrCreateOwnParty(owner);

if (party != null) {
if (party.getMemberPlayers().contains(player)) {
return PartyResult.err(PartyError.ALREADY_PARTY_MEMBER);
}

if (party.invite(player)) {
return PartyResult.ok(party);
} else {
return PartyResult.err(PartyError.ALREADY_INVITED);
return PartyResult.err(party, PartyError.ALREADY_INVITED);
}
}

Expand Down Expand Up @@ -173,7 +179,12 @@ public PartyResult transferParty(PlayerRef from, PlayerRef to) {
return PartyResult.err(PartyError.NOT_IN_PARTY);
}

party.setOwner(to);
if (Permissions.check(to.id(), "party.command.transfer", true).join()) {
party.setOwner(to);
} else {
return PartyResult.err(PartyError.NOT_ALLOWED);
}

return PartyResult.ok(party);
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/xyz/nucleoid/parties/PartyResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public static PartyResult err(PartyError error) {
return new PartyResult(null, error);
}

public static PartyResult err(Party party, PartyError error) {
return new PartyResult(party, error);
}

public boolean isOk() {
return this.error == null;
}
Expand Down
16 changes: 13 additions & 3 deletions src/main/java/xyz/nucleoid/parties/PartyTexts.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.UUID;

import com.mojang.authlib.GameProfile;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.MutableText;
Expand All @@ -21,9 +22,11 @@ public static MutableText displayError(PartyError error, String player) {
case DOES_NOT_EXIST -> Text.translatable("text.game_parties.party.error.does_not_exist");
case ALREADY_INVITED -> Text.translatable("text.game_parties.party.error.already_invited", player);
case ALREADY_IN_PARTY -> Text.translatable("text.game_parties.party.error.already_in_party");
case ALREADY_PARTY_MEMBER-> Text.translatable("text.game_parties.party.error.already_party_member", player);
case CANNOT_REMOVE_SELF -> Text.translatable("text.game_parties.party.error.cannot_remove_self");
case NOT_IN_PARTY -> Text.translatable("text.game_parties.party.error.not_in_party", player);
case NOT_INVITED -> Text.translatable("text.game_parties.party.error.not_invited");
case NOT_ALLOWED -> Text.translatable("text.game_parties.party.error.not_allowed");
};
}

Expand Down Expand Up @@ -55,18 +58,25 @@ public static MutableText transferredReceiver(ServerPlayerEntity transferredFrom
return Text.translatable("text.game_parties.party.transferred.receiver", transferredFrom.getDisplayName());
}

public static MutableText kickedSender(ServerPlayerEntity player) {
return Text.translatable("text.game_parties.party.kicked.sender", player.getDisplayName());
public static MutableText kickedSender(GameProfile player) {
return Text.translatable("text.game_parties.party.kicked.sender", player.getName());
}

public static MutableText kickedReceiver() {
return Text.translatable("text.game_parties.party.kicked.receiver");
}

public static MutableText invitedSender(ServerPlayerEntity player) {
public static MutableText invitedSender(ServerPlayerEntity player, boolean again) {
if (again) {
return Text.translatable("text.game_parties.party.invited.sender.again", player.getDisplayName());
}
return Text.translatable("text.game_parties.party.invited.sender", player.getDisplayName());
}

public static MutableText invitedSender(int count) {
return Text.translatable("text.game_parties.party.invited.sender.multiple", count);
}

public static MutableText invitedReceiver(ServerPlayerEntity owner, UUID uuid) {
return Text.translatable("text.game_parties.party.invited.receiver", owner.getDisplayName())
.append(PartyTexts.inviteNotificationLink(owner, uuid));
Expand Down
4 changes: 4 additions & 0 deletions src/main/resources/data/game_parties/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
"text.game_parties.party.disband.success": "Your party has been disbanded!",
"text.game_parties.party.error.already_in_party": "You are already in this party!",
"text.game_parties.party.error.already_invited": "%s is already invited to this party!",
"text.game_parties.party.error.already_party_member": "%s is already a party member!",
"text.game_parties.party.error.cannot_remove_self": "Cannot remove yourself from the party!",
"text.game_parties.party.error.does_not_exist": "You do not control any party!",
"text.game_parties.party.error.not_in_party": "%s is not in this party!",
"text.game_parties.party.error.not_invited": "You are not invited to this party!",
"text.game_parties.party.error.not_allowed": "This player does not have permission to run a party!",
"text.game_parties.party.invited.receiver": "You have been invited to join %s's party! ",
"text.game_parties.party.invited.receiver.click": "Click here to join",
"text.game_parties.party.invited.receiver.hover": "Join %s's party!",
"text.game_parties.party.invited.sender": "Invited %s to the party",
"text.game_parties.party.invited.sender.again": "%s is already invited, sent notification again",
"text.game_parties.party.invited.sender.multiple": "Invited %s players to the party",
"text.game_parties.party.join.success": "%s has joined the party!",
"text.game_parties.party.kicked.receiver": "You have been kicked from the party",
"text.game_parties.party.kicked.sender": "%s has been kicked from the party",
Expand Down