add messages

This commit is contained in:
Sen 2025-06-10 12:43:56 +02:00
parent 4c2c0ab7fc
commit 6bead101d3
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
6 changed files with 114 additions and 11 deletions

View file

@ -127,6 +127,8 @@ public class Proxy {
@Config @Config
private boolean kickOnConnect = true; private boolean kickOnConnect = true;
@Config @Config
private boolean joinQuitMessages = true;
@Config
private String forwardHost = "127.0.0.1"; private String forwardHost = "127.0.0.1";
@Config @Config
private int forwardPort = 25563; private int forwardPort = 25563;
@ -178,10 +180,12 @@ public class Proxy {
} }
public static void main(String[] args) { public static void main(String[] args) {
long time = System.currentTimeMillis();
Locale.setDefault(Locale.ROOT);
Thread.currentThread().setName("Proxy thread"); Thread.currentThread().setName("Proxy thread");
Log.info("Starting login proxy ..."); Log.info("Starting " + NAME + " ...");
Proxy proxy = new Proxy(); Proxy proxy = new Proxy();
proxy.run(); proxy.run(time);
} }
public Proxy() { public Proxy() {
@ -291,7 +295,7 @@ public class Proxy {
saveFile(obj, new File("users.json")); saveFile(obj, new File("users.json"));
} }
public void run() { public void run(long time) {
this.loadConfig(); this.loadConfig();
this.loadUsers(); this.loadUsers();
Log.info("Hosting proxy on %s:%d", this.proxyHost.isEmpty() ? "0.0.0.0" : this.proxyHost, this.proxyPort); Log.info("Hosting proxy on %s:%d", this.proxyHost.isEmpty() ? "0.0.0.0" : this.proxyHost, this.proxyPort);
@ -332,6 +336,7 @@ public class Proxy {
}, "Proxy console handler"); }, "Proxy console handler");
con.setDaemon(true); con.setDaemon(true);
con.start(); con.start();
Log.info("Proxy started in %.1f seconds.", (float)(System.currentTimeMillis() - time) / 1000.0f);
while(this.running) { while(this.running) {
synchronized (this.futureTaskQueue) synchronized (this.futureTaskQueue)
{ {
@ -566,11 +571,15 @@ public class Proxy {
handler.sendToClient(new S38PacketPlayerListItem(this.players.values(), false)); handler.sendToClient(new S38PacketPlayerListItem(this.players.values(), false));
this.sendPacket(new S38PacketPlayerListItem(handler, Action.ADD_PLAYER), handler); this.sendPacket(new S38PacketPlayerListItem(handler, Action.ADD_PLAYER), handler);
this.status.setOnline(this.players.size()); this.status.setOnline(this.players.size());
if(this.joinQuitMessages)
this.sendPacket(new S02PacketChat(Formatter.YELLOW + handler.getUsername() + " joined the game", false));
} }
private void removePlayer(ProxyHandler handler) { private void removePlayer(ProxyHandler handler) {
this.sendPacket(new S38PacketPlayerListItem(handler, Action.REMOVE_PLAYER), handler); this.sendPacket(new S38PacketPlayerListItem(handler, Action.REMOVE_PLAYER), handler);
this.status.setOnline(this.players.size()); this.status.setOnline(this.players.size());
if(this.joinQuitMessages)
this.sendPacket(new S02PacketChat(Formatter.YELLOW + handler.getUsername() + " left the game", false));
} }
public void deleteUser(String user) { public void deleteUser(String user) {
@ -627,13 +636,16 @@ public class Proxy {
this.register(new CommandList()); this.register(new CommandList());
this.register(new CommandPing()); this.register(new CommandPing());
this.register(new CommandKick()); this.register(new CommandKick());
this.register(new CommandSave()); this.register(new CommandTell());
this.register(new CommandSeed()); this.register(new CommandTellraw());
for(String cmd : new String[] {"?", "about", "ban", "ban-ip", "banlist", "icanhasbukkit", "me", "pardon", "pardon-ip", "pl", "plugins", "restart", "rl", "say", "scoreboard", "stop", "tell", "tellraw", "timings", "title", "toggledownfall", "trigger", "ver", "version", "whitelist", "clone", "debug", "fill", "testfor", "testforblock", "testforblocks", "setidletimeout", "stats", "save-off", "save-on", "save-all", "spreadplayers"}) { for(String cmd : new String[] {"?", "about", "ban", "ban-ip", "banlist", "icanhasbukkit", "me", "pardon", "pardon-ip", "pl", "plugins", "restart", "rl", "say", "scoreboard", "stop", "timings", "title", "toggledownfall", "trigger", "ver", "version", "whitelist", "clone", "debug", "fill", "testfor", "testforblock", "testforblocks", "setidletimeout", "stats", "save-off", "save-on", "save-all", "spreadplayers"}) {
this.register(new CommandDummy(cmd)); this.register(new CommandDummy(cmd));
} }
this.register(new CommandSave());
this.register(new CommandSeed());
this.register(new CommandPass("achievement", "<give|take> <stat_name|*> [player]", "Gives takes achievements to players or takes them")); this.register(new CommandPass("achievement", "<give|take> <stat_name|*> [player]", "Gives takes achievements to players or takes them"));
this.register(new CommandPass("blockdata", "<x> <y> <z> <dataTag>", "Sets data of a tile entity")); this.register(new CommandPass("blockdata", "<x> <y> <z> <dataTag>", "Sets data of a tile entity"));
this.register(new CommandPass("clear", "[player] [item] [data] [maxCount] [dataTag]", "Clears items in the inventory of a player")); this.register(new CommandPass("clear", "[player] [item] [data] [maxCount] [dataTag]", "Clears items in the inventory of a player"));

View file

@ -0,0 +1,42 @@
package proxy.command;
import com.google.common.collect.Collections2;
import proxy.Proxy;
import proxy.handler.ProxyHandler;
import proxy.util.Formatter;
public class CommandTell extends Command {
public String getName() {
return "tell";
}
public String getHelp() {
return "Sends a message to a player";
}
public String getArgs() {
return "<player> <message ...>";
}
public int getRedactedLogArg(int args) {
return 1;
}
public void run(Proxy proxy, ProxyHandler player, String[] args) {
if(args.length < 2)
throw new RunException("Please provide a player name and a message");
ProxyHandler plr = proxy.getPlayer(args[0]);
if(plr == null)
throw new RunException("'%s' is not online", args[0]);
if(plr == player)
throw new RunException("You cannot message yourself");
String msg = Formatter.joinSpace(1, args);
plr.sendMessage(Formatter.AQUA + "%s" + Formatter.GREEN + " -> " + Formatter.GRAY + "%s", player == null ? "#CONSOLE#" : player.getUsername(), msg);
sendMessage(player, Formatter.AQUA + "%s" + Formatter.RED + " <- " + Formatter.GRAY + "%s", plr.getUsername(), msg);
}
public Iterable<String> complete(Proxy proxy, ProxyHandler player, String[] args, String[] serverMatches) {
return args.length == 1 ? (player == null ? proxy.getPlayerNames() : Collections2.filter(proxy.getPlayerNames(), name -> proxy.getPlayer(name) != player)) : null;
}
}

View file

@ -0,0 +1,34 @@
package proxy.command;
import proxy.Proxy;
import proxy.handler.ProxyHandler;
import proxy.util.Formatter;
public class CommandTellraw extends Command {
public String getName() {
return "tellraw";
}
public String getHelp() {
return "Sends a raw message to a player";
}
public String getArgs() {
return "<player> <message ...>";
}
public void run(Proxy proxy, ProxyHandler player, String[] args) {
if(args.length < 2)
throw new RunException("Please provide a player name and a message");
ProxyHandler plr = proxy.getPlayer(args[0]);
if(plr == null)
throw new RunException("'%s' is not online", args[0]);
plr.sendMessage(Formatter.joinSpace(1, args));
if(plr != player)
sendInfo(player, "Message sent to %s", plr.getUsername());
}
public Iterable<String> complete(Proxy proxy, ProxyHandler player, String[] args, String[] serverMatches) {
return args.length == 1 ? proxy.getPlayerNames() : null;
}
}

View file

@ -9,6 +9,7 @@ import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import proxy.Proxy; import proxy.Proxy;
import proxy.network.Connection; import proxy.network.Connection;
@ -57,6 +58,7 @@ public class ProxyHandler extends User implements Handler {
} }
private static final AtomicInteger CONN_COUNTER = new AtomicInteger(); private static final AtomicInteger CONN_COUNTER = new AtomicInteger();
private static final Pattern JOIN_LEAVE_REGEX = Pattern.compile("\\QJSON:{\"extra\":[{\"color\":\"yellow\",\"text\":\"\\E[0-9A-Za-z_]{3,16} (joined the game|left the game\\.)\\Q\"}],\"text\":\"\"}\\E");
private final Proxy proxy; private final Proxy proxy;
private final Connection client; private final Connection client;
@ -685,7 +687,8 @@ public class ProxyHandler extends User implements Handler {
} }
public void handleChat(S02PacketChat packetIn) { public void handleChat(S02PacketChat packetIn) {
this.sendToClient(packetIn); if(packetIn.getType() != 1 || !JOIN_LEAVE_REGEX.matcher(packetIn.getMessage()).matches())
this.sendToClient(packetIn);
} }
public void handleAnimation(S0BPacketAnimation packetIn) { public void handleAnimation(S0BPacketAnimation packetIn) {

View file

@ -47,4 +47,12 @@ public class S02PacketChat implements Packet<ProxyHandler>
{ {
handler.handleChat(this); handler.handleChat(this);
} }
public String getMessage() {
return Formatter.getStringOrJson(this.chatComponent);
}
public byte getType() {
return this.type;
}
} }

View file

@ -42,7 +42,7 @@ public enum Formatter {
return new JsonPrimitive(text).toString(); return new JsonPrimitive(text).toString();
} }
public static String fromJsonString(String json) { private static String fromJsonString(String json, boolean object) {
JsonParser parser = new JsonParser(); JsonParser parser = new JsonParser();
JsonElement elem; JsonElement elem;
try { try {
@ -51,13 +51,17 @@ public enum Formatter {
catch(Throwable t) { catch(Throwable t) {
return null; return null;
} }
if(elem.isJsonObject()) if(object && elem.isJsonObject())
return elem.getAsJsonObject().has("text") && elem.getAsJsonObject().get("text").isJsonPrimitive() ? elem.getAsJsonObject().get("text").getAsString() : null; return elem.getAsJsonObject().has("text") && elem.getAsJsonObject().get("text").isJsonPrimitive() ? elem.getAsJsonObject().get("text").getAsString() : null;
return elem.isJsonPrimitive() ? elem.getAsString() : null; return elem.isJsonPrimitive() ? elem.getAsString() : null;
} }
public static String fromJsonString(String json) {
return fromJsonString(json, true);
}
public static String getStringOrJson(String json) { public static String getStringOrJson(String json) {
String str = fromJsonString(json); String str = fromJsonString(json, false);
return str == null ? "JSON:" + json : str; return str == null ? "JSON:" + json : str;
} }