add: PingPlayerFeature (#1)
fix many bugs, rewrote some message decorators to be refactored
This commit is contained in:
6 files changed
+121
-18
No files matched your search
@@ -7,8 +7,10 @@ import net.minecraft.server.network.ServerPlayerEntity;
|
|||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class SFConsts {
|
public class SFConsts {
|
||||||
public static final String SPECIAL_SUDO = "sfcraft.special.state.sudo";
|
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> 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_ADDWL = ofSFCPermission("command.addwl", false);
|
||||||
public static final Permission<PlayerEntity> COMMAND_UNBLOCKSERVER = ofSFCPermission("command.unblockserver", false);
|
public static final Permission<PlayerEntity> COMMAND_UNBLOCKSERVER = ofSFCPermission("command.unblockserver", false);
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package io.ib67.sfcraft.message;
|
package io.ib67.sfcraft.message;
|
||||||
|
|
||||||
|
import io.ib67.sfcraft.message.feature.PingPlayerFeature;
|
||||||
import io.ib67.sfcraft.message.feature.SendLocationFeature;
|
import io.ib67.sfcraft.message.feature.SendLocationFeature;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
public class SFMessageDecorator extends SimpleMessageDecorator {
|
public class SFMessageDecorator extends SimpleMessageDecorator {
|
||||||
public SFMessageDecorator() {
|
public SFMessageDecorator() {
|
||||||
registerDecorator(new SendLocationFeature());
|
registerDecorator(new SendLocationFeature());
|
||||||
|
registerDecorator(new PingPlayerFeature());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -21,9 +21,21 @@ public class SimpleMessageDecorator implements MessageDecorator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Text decorate(@Nullable ServerPlayerEntity sender, Text message) {
|
public Text decorate(@Nullable ServerPlayerEntity sender, Text message) {
|
||||||
|
var targets = new ArrayList<Text>();
|
||||||
|
targets.add(message);
|
||||||
for (MessageDecorator decorator : decorators) {
|
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());
|
||||||
}
|
}
|
||||||
return message;
|
targets = newRd;
|
||||||
|
}
|
||||||
|
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;
|
package io.ib67.sfcraft.message.feature;
|
||||||
|
|
||||||
import io.ib67.sfcraft.Helper;
|
import io.ib67.sfcraft.Helper;
|
||||||
|
import io.ib67.sfcraft.SFConsts;
|
||||||
import net.minecraft.network.message.MessageDecorator;
|
import net.minecraft.network.message.MessageDecorator;
|
||||||
import net.minecraft.registry.RegistryKey;
|
import net.minecraft.registry.RegistryKey;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
@@ -12,24 +13,12 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
public class SendLocationFeature implements MessageDecorator {
|
public class SendLocationFeature implements MessageDecorator {
|
||||||
@Override
|
@Override
|
||||||
public Text decorate(@Nullable ServerPlayerEntity sender, Text message) {
|
public Text decorate(@Nullable ServerPlayerEntity sender, Text message) {
|
||||||
var text = message.getLiteralString().trim();
|
if (sender != null) {
|
||||||
if (text == null) {
|
if (!SFConsts.USE_BROADCAST_LOCATION.hasPermission(sender)) {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
if (text.trim().equals(".xyz")) {
|
|
||||||
return generateLocText(sender);
|
|
||||||
}
|
}
|
||||||
var result = Text.literal("");
|
return ReplaceHelper.replace(sender, message, ".xyz", SendLocationFeature::generateLocText);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Text generateLocText(ServerPlayerEntity sender) {
|
private static Text generateLocText(ServerPlayerEntity sender) {
|
||||||
|
|||||||
Reference in new issue
Block a user