add: PingPlayerFeature (#1)
fix many bugs, rewrote some message decorators to be refactored
This commit is contained in:
6 files changed
+123
-20
No files matched your search
@@ -7,8 +7,10 @@ import net.minecraft.server.network.ServerPlayerEntity;
|
||||
@UtilityClass
|
||||
public class SFConsts {
|
||||
public static final String SPECIAL_SUDO = "sfcraft.special.state.sudo";
|
||||
public static final Permission<PlayerEntity> USE_AT = ofSFCPermission("chat.at",true);
|
||||
public static final Permission<PlayerEntity> USE_BROADCAST_LOCATION = ofSFCPermission("chat.xyz",true);
|
||||
public static final Permission<PlayerEntity> COMMAND_BACK = ofSFCPermission("command.home", true);
|
||||
public static final Permission<PlayerEntity> UNLIMITED_COMMAND_BACK = ofSFCPermission("command.home.unlimited", true);
|
||||
public static final Permission<PlayerEntity> UNLIMITED_COMMAND_BACK = ofSFCPermission("command.home.unlimited", false);
|
||||
|
||||
public static final Permission<PlayerEntity> COMMAND_ADDWL = ofSFCPermission("command.addwl", false);
|
||||
public static final Permission<PlayerEntity> COMMAND_UNBLOCKSERVER = ofSFCPermission("command.unblockserver", false);
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package io.ib67.sfcraft.message;
|
||||
|
||||
import io.ib67.sfcraft.message.feature.PingPlayerFeature;
|
||||
import io.ib67.sfcraft.message.feature.SendLocationFeature;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class SFMessageDecorator extends SimpleMessageDecorator {
|
||||
public SFMessageDecorator() {
|
||||
registerDecorator(new SendLocationFeature());
|
||||
registerDecorator(new PingPlayerFeature());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,9 +21,21 @@ public class SimpleMessageDecorator implements MessageDecorator {
|
||||
|
||||
@Override
|
||||
public Text decorate(@Nullable ServerPlayerEntity sender, Text message) {
|
||||
var targets = new ArrayList<Text>();
|
||||
targets.add(message);
|
||||
for (MessageDecorator decorator : decorators) {
|
||||
message = decorator.decorate(sender, message);
|
||||
var newRd = new ArrayList<Text>();
|
||||
for (Text target : targets) {
|
||||
var r = decorator.decorate(sender, target);
|
||||
var copy = r.copy();
|
||||
copy.getSiblings().clear();
|
||||
newRd.add(copy);
|
||||
newRd.addAll(r.getSiblings());
|
||||
}
|
||||
targets = newRd;
|
||||
}
|
||||
return message;
|
||||
var result = Text.empty();
|
||||
targets.forEach(result::append);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package io.ib67.sfcraft.message.feature;
|
||||
|
||||
import io.ib67.sfcraft.SFConsts;
|
||||
import io.ib67.sfcraft.SFCraft;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.network.message.MessageDecorator;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Colors;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.MatchResult;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class PingPlayerFeature implements MessageDecorator {
|
||||
private static final Pattern PING = Pattern.compile("(@[\\w]+)?");
|
||||
|
||||
@Override
|
||||
public Text decorate(@Nullable ServerPlayerEntity sender, Text message) {
|
||||
if (sender != null) {
|
||||
if (!SFConsts.USE_AT.hasPermission(sender)) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
var text = message.getLiteralString();
|
||||
if (text == null) return message;
|
||||
var match = PING.matcher(text);
|
||||
if (!match.find()) return message;
|
||||
var foundPlayers = new HashSet<PlayerEntity>();
|
||||
var names = List.of(SFCraft.getInstance().getServer().getPlayerNames());
|
||||
var r = Text.literal(match.replaceAll(it -> this.matchPlayer(it, names, foundPlayers)));
|
||||
for (PlayerEntity foundPlayer : foundPlayers) {
|
||||
if (sender != null) {
|
||||
foundPlayer.sendMessage(Text.literal(sender.getName().getLiteralString() + " 正在叫你。").withColor(Colors.LIGHT_GRAY));
|
||||
}
|
||||
foundPlayer.playSoundToPlayer(
|
||||
SoundEvent.of(SoundEvents.ENTITY_ITEM_PICKUP.getId()),
|
||||
SoundCategory.PLAYERS,
|
||||
0.8f,
|
||||
0.5f
|
||||
);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private String matchPlayer(MatchResult match, List<String> playerNames, Set<PlayerEntity> foundPlayers) {
|
||||
for (int i = 0; i < match.groupCount(); i++) {
|
||||
var r = match.group();
|
||||
if (r.isEmpty()) continue;
|
||||
final var d = r.substring(1);
|
||||
return playerNames.stream()
|
||||
.filter(it -> it.toLowerCase().startsWith(d))
|
||||
.peek(it -> foundPlayers.add(SFCraft.getInstance().getServer().getPlayerManager().getPlayer(it)))
|
||||
.findFirst()
|
||||
.orElse(r);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.ib67.sfcraft.message.feature;
|
||||
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
|
||||
class ReplaceHelper {
|
||||
|
||||
public static Text replace(ServerPlayerEntity sender, Text message, String s, Function<ServerPlayerEntity, Text> generator) {
|
||||
var text = message.getLiteralString();
|
||||
if (text == null || text.isEmpty()) return message;
|
||||
text = text.trim();
|
||||
var result = Text.literal("");
|
||||
var head = 0;
|
||||
var lowercase = text.toLowerCase(Locale.ROOT);
|
||||
var i = lowercase.indexOf(s);
|
||||
while (i != -1) {
|
||||
result.append(text.substring(0, i).trim());
|
||||
result.append(generator.apply(sender));
|
||||
head = i + s.length();
|
||||
i = lowercase.indexOf(s, head + 1);
|
||||
}
|
||||
result.append(text.substring(head).trim());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.ib67.sfcraft.message.feature;
|
||||
|
||||
import io.ib67.sfcraft.Helper;
|
||||
import io.ib67.sfcraft.SFConsts;
|
||||
import net.minecraft.network.message.MessageDecorator;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
@@ -12,24 +13,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class SendLocationFeature implements MessageDecorator {
|
||||
@Override
|
||||
public Text decorate(@Nullable ServerPlayerEntity sender, Text message) {
|
||||
var text = message.getLiteralString().trim();
|
||||
if (text == null) {
|
||||
return message;
|
||||
if (sender != null) {
|
||||
if (!SFConsts.USE_BROADCAST_LOCATION.hasPermission(sender)) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
if (text.trim().equals(".xyz")) {
|
||||
return generateLocText(sender);
|
||||
}
|
||||
var result = Text.literal("");
|
||||
var head = 0;
|
||||
var i = text.indexOf(".xyz");
|
||||
while (i != -1) {
|
||||
result.append(text.substring(0, i).trim());
|
||||
result.append(generateLocText(sender));
|
||||
head = i + 4;
|
||||
i = text.indexOf(".xyz", head + 1);
|
||||
}
|
||||
result.append(text.substring(head).trim());
|
||||
return result;
|
||||
return ReplaceHelper.replace(sender, message, ".xyz", SendLocationFeature::generateLocText);
|
||||
}
|
||||
|
||||
private static Text generateLocText(ServerPlayerEntity sender) {
|
||||
|
||||
Reference in new issue
Block a user