Compare commits
13 Commits
78ca16dfe3
...
511017ab35
Author | SHA1 | Date | |
---|---|---|---|
|
511017ab35 | ||
|
c3e8cfac79 | ||
|
bf2b3c68f8 | ||
|
68e74a8c03 | ||
|
5b4a540440 | ||
|
88da5c05c7 | ||
|
2d369e8945 | ||
|
02548c4b9b | ||
|
71990e3ccc | ||
|
5e7dcc48b9 | ||
|
5cdba87b87 | ||
|
696315615d | ||
|
dd3f820040 |
5
.github/workflows/maven.yml
vendored
5
.github/workflows/maven.yml
vendored
@ -14,9 +14,10 @@ jobs:
|
||||
name: Java ${{ matrix.java }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v1
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: zulu
|
||||
java-version: ${{ matrix.java }}
|
||||
- run: java -version && mvn --version
|
||||
- run: mvn --activate-profiles dist --no-transfer-progress package
|
||||
|
@ -73,7 +73,7 @@
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.30</version>
|
||||
<version>1.33</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
@ -8,7 +8,7 @@ import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
|
||||
/**
|
||||
* Called when the proxy is pinged with packet 0xFE from the server list.
|
||||
* Called when the proxy is queried for status from the server list.
|
||||
*/
|
||||
@Data
|
||||
@ToString(callSuper = false)
|
||||
|
@ -29,7 +29,7 @@
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.30</version>
|
||||
<version>1.33</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
@ -24,6 +24,7 @@ public class BungeeLogger extends Logger
|
||||
{
|
||||
super( loggerName, null );
|
||||
setLevel( Level.ALL );
|
||||
setUseParentHandlers( false );
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -0,0 +1,29 @@
|
||||
package net.md_5.bungee.log;
|
||||
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class LoggingForwardHandler extends Handler
|
||||
{
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
@Override
|
||||
public void publish(LogRecord record)
|
||||
{
|
||||
logger.log( record );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SecurityException
|
||||
{
|
||||
}
|
||||
}
|
2
pom.xml
2
pom.xml
@ -73,7 +73,7 @@
|
||||
<properties>
|
||||
<build.number>unknown</build.number>
|
||||
<lombok.version>1.18.22</lombok.version>
|
||||
<netty.version>4.1.77.Final</netty.version>
|
||||
<netty.version>4.1.85.Final</netty.version>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
@ -30,6 +30,7 @@ import net.md_5.bungee.protocol.packet.Respawn;
|
||||
import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
|
||||
import net.md_5.bungee.protocol.packet.ScoreboardObjective;
|
||||
import net.md_5.bungee.protocol.packet.ScoreboardScore;
|
||||
import net.md_5.bungee.protocol.packet.ServerData;
|
||||
import net.md_5.bungee.protocol.packet.SetCompression;
|
||||
import net.md_5.bungee.protocol.packet.StatusRequest;
|
||||
import net.md_5.bungee.protocol.packet.StatusResponse;
|
||||
@ -208,4 +209,8 @@ public abstract class AbstractPacketHandler
|
||||
public void handle(GameState gameState) throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public void handle(ServerData serverData) throws Exception
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -21,12 +21,22 @@ public abstract class DefinedPacket
|
||||
|
||||
public static void writeString(String s, ByteBuf buf)
|
||||
{
|
||||
if ( s.length() > Short.MAX_VALUE )
|
||||
writeString( s, buf, Short.MAX_VALUE );
|
||||
}
|
||||
|
||||
public static void writeString(String s, ByteBuf buf, int maxLength)
|
||||
{
|
||||
throw new OverflowPacketException( "Cannot send string longer than Short.MAX_VALUE (got " + s.length() + " characters)" );
|
||||
if ( s.length() > maxLength )
|
||||
{
|
||||
throw new OverflowPacketException( "Cannot send string longer than " + maxLength + " (got " + s.length() + " characters)" );
|
||||
}
|
||||
|
||||
byte[] b = s.getBytes( Charsets.UTF_8 );
|
||||
if ( b.length > maxLength * 3 )
|
||||
{
|
||||
throw new OverflowPacketException( "Cannot send string longer than " + ( maxLength * 3 ) + " (got " + b.length + " bytes)" );
|
||||
}
|
||||
|
||||
writeVarInt( b.length, buf );
|
||||
buf.writeBytes( b );
|
||||
}
|
||||
@ -39,15 +49,14 @@ public abstract class DefinedPacket
|
||||
public static String readString(ByteBuf buf, int maxLen)
|
||||
{
|
||||
int len = readVarInt( buf );
|
||||
if ( len > maxLen * 4 )
|
||||
if ( len > maxLen * 3 )
|
||||
{
|
||||
throw new OverflowPacketException( "Cannot receive string longer than " + maxLen * 4 + " (got " + len + " bytes)" );
|
||||
throw new OverflowPacketException( "Cannot receive string longer than " + maxLen * 3 + " (got " + len + " bytes)" );
|
||||
}
|
||||
|
||||
byte[] b = new byte[ len ];
|
||||
buf.readBytes( b );
|
||||
String s = buf.toString( buf.readerIndex(), len, Charsets.UTF_8 );
|
||||
buf.readerIndex( buf.readerIndex() + len );
|
||||
|
||||
String s = new String( b, Charsets.UTF_8 );
|
||||
if ( s.length() > maxLen )
|
||||
{
|
||||
throw new OverflowPacketException( "Cannot receive string longer than " + maxLen + " (got " + s.length() + " characters)" );
|
||||
@ -275,7 +284,7 @@ public abstract class DefinedPacket
|
||||
{
|
||||
if ( buf.readBoolean() )
|
||||
{
|
||||
return new PlayerPublicKey( buf.readLong(), readArray( buf ), readArray( buf ) );
|
||||
return new PlayerPublicKey( buf.readLong(), readArray( buf, 512 ), readArray( buf, 4096 ) );
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -36,6 +36,7 @@ import net.md_5.bungee.protocol.packet.Respawn;
|
||||
import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
|
||||
import net.md_5.bungee.protocol.packet.ScoreboardObjective;
|
||||
import net.md_5.bungee.protocol.packet.ScoreboardScore;
|
||||
import net.md_5.bungee.protocol.packet.ServerData;
|
||||
import net.md_5.bungee.protocol.packet.SetCompression;
|
||||
import net.md_5.bungee.protocol.packet.StatusRequest;
|
||||
import net.md_5.bungee.protocol.packet.StatusResponse;
|
||||
@ -338,6 +339,12 @@ public enum Protocol
|
||||
map( ProtocolConstants.MINECRAFT_1_19, 0x49 ),
|
||||
map( ProtocolConstants.MINECRAFT_1_19_1, 0x4C )
|
||||
);
|
||||
TO_CLIENT.registerPacket(
|
||||
ServerData.class,
|
||||
ServerData::new,
|
||||
map( ProtocolConstants.MINECRAFT_1_19, 0x3F ),
|
||||
map( ProtocolConstants.MINECRAFT_1_19_1, 0x42 )
|
||||
);
|
||||
|
||||
TO_SERVER.registerPacket(
|
||||
KeepAlive.class,
|
||||
|
@ -54,7 +54,7 @@ public class Chat extends DefinedPacket
|
||||
@Override
|
||||
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||
{
|
||||
writeString( message, buf );
|
||||
writeString( message, buf, ( direction == ProtocolConstants.Direction.TO_CLIENT ) ? 262144 : ( protocolVersion >= ProtocolConstants.MINECRAFT_1_11 ? 256 : 100 ) );
|
||||
if ( direction == ProtocolConstants.Direction.TO_CLIENT )
|
||||
{
|
||||
buf.writeByte( position );
|
||||
|
@ -49,7 +49,7 @@ public class ClientChat extends DefinedPacket
|
||||
buf.writeBoolean( signedPreview );
|
||||
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
|
||||
{
|
||||
chain.write( buf );
|
||||
chain.write( buf, direction, protocolVersion );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ public class ClientCommand extends DefinedPacket
|
||||
buf.writeBoolean( signedPreview );
|
||||
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
|
||||
{
|
||||
chain.write( buf );
|
||||
chain.write( buf, direction, protocolVersion );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,78 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.md_5.bungee.protocol.AbstractPacketHandler;
|
||||
import net.md_5.bungee.protocol.DefinedPacket;
|
||||
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class ServerData extends DefinedPacket
|
||||
{
|
||||
|
||||
private String motd;
|
||||
private String icon;
|
||||
private boolean preview;
|
||||
private boolean enforceSecure;
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||
{
|
||||
if ( buf.readBoolean() )
|
||||
{
|
||||
motd = readString( buf, 262144 );
|
||||
}
|
||||
if ( buf.readBoolean() )
|
||||
{
|
||||
icon = readString( buf );
|
||||
}
|
||||
|
||||
preview = buf.readBoolean();
|
||||
|
||||
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
|
||||
{
|
||||
enforceSecure = buf.readBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||
{
|
||||
if ( motd != null )
|
||||
{
|
||||
buf.writeBoolean( true );
|
||||
writeString( motd, buf, 262144 );
|
||||
} else
|
||||
{
|
||||
buf.writeBoolean( false );
|
||||
}
|
||||
|
||||
if ( icon != null )
|
||||
{
|
||||
buf.writeBoolean( true );
|
||||
writeString( icon, buf );
|
||||
} else
|
||||
{
|
||||
buf.writeBoolean( false );
|
||||
}
|
||||
|
||||
buf.writeBoolean( preview );
|
||||
|
||||
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
|
||||
{
|
||||
buf.writeBoolean( enforceSecure );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ public class SystemChat extends DefinedPacket
|
||||
@Override
|
||||
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
|
||||
{
|
||||
writeString( message, buf );
|
||||
writeString( message, buf, 262144 );
|
||||
if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 )
|
||||
{
|
||||
buf.writeBoolean( position == ChatMessageType.ACTION_BAR.ordinal() );
|
||||
|
@ -24,10 +24,12 @@ import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.text.Format;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
@ -85,6 +87,7 @@ import net.md_5.bungee.conf.Configuration;
|
||||
import net.md_5.bungee.conf.YamlConfig;
|
||||
import net.md_5.bungee.forge.ForgeConstants;
|
||||
import net.md_5.bungee.log.BungeeLogger;
|
||||
import net.md_5.bungee.log.LoggingForwardHandler;
|
||||
import net.md_5.bungee.log.LoggingOutputStream;
|
||||
import net.md_5.bungee.module.ModuleManager;
|
||||
import net.md_5.bungee.netty.PipelineUtils;
|
||||
@ -113,10 +116,9 @@ public class BungeeCord extends ProxyServer
|
||||
@Getter
|
||||
public final Configuration config = new Configuration();
|
||||
/**
|
||||
* Localization bundle.
|
||||
* Localization formats.
|
||||
*/
|
||||
private ResourceBundle baseBundle;
|
||||
private ResourceBundle customBundle;
|
||||
private Map<String, Format> messageFormats;
|
||||
public EventLoopGroup eventLoops;
|
||||
/**
|
||||
* locations.yml save thread.
|
||||
@ -189,13 +191,6 @@ public class BungeeCord extends ProxyServer
|
||||
// Java uses ! to indicate a resource inside of a jar/zip/other container. Running Bungee from within a directory that has a ! will cause this to muck up.
|
||||
Preconditions.checkState( new File( "." ).getAbsolutePath().indexOf( '!' ) == -1, "Cannot use BungeeCord in directory with ! in path." );
|
||||
|
||||
try
|
||||
{
|
||||
baseBundle = ResourceBundle.getBundle( "messages" );
|
||||
} catch ( MissingResourceException ex )
|
||||
{
|
||||
baseBundle = ResourceBundle.getBundle( "messages", Locale.ENGLISH );
|
||||
}
|
||||
reloadMessages();
|
||||
|
||||
// This is a workaround for quite possibly the weirdest bug I have ever encountered in my life!
|
||||
@ -215,6 +210,21 @@ public class BungeeCord extends ProxyServer
|
||||
|
||||
logger = new BungeeLogger( "BungeeCord", "proxy.log", consoleReader );
|
||||
JDK14LoggerFactory.LOGGER = logger;
|
||||
|
||||
// Before we can set the Err and Out streams to our LoggingOutputStream we also have to remove
|
||||
// the default ConsoleHandler from the root logger, which writes to the err stream.
|
||||
// But we still want to log these records, so we add our own handler which forwards the LogRecord to the BungeeLogger.
|
||||
// This way we skip the err stream and the problem of only getting a string without context, and can handle the LogRecord itself.
|
||||
// Thus improving the default bahavior for projects that log on other Logger instances not created by BungeeCord.
|
||||
Logger rootLogger = Logger.getLogger( "" );
|
||||
for ( Handler handler : rootLogger.getHandlers() )
|
||||
{
|
||||
rootLogger.removeHandler( handler );
|
||||
}
|
||||
rootLogger.addHandler( new LoggingForwardHandler( logger ) );
|
||||
|
||||
// We want everything that reaches these output streams to be handled by our logger
|
||||
// since it applies a nice looking format and also writes to the logfile.
|
||||
System.setErr( new PrintStream( new LoggingOutputStream( logger, Level.SEVERE ), true ) );
|
||||
System.setOut( new PrintStream( new LoggingOutputStream( logger, Level.INFO ), true ) );
|
||||
|
||||
@ -537,32 +547,49 @@ public class BungeeCord extends ProxyServer
|
||||
return ( BungeeCord.class.getPackage().getImplementationVersion() == null ) ? "unknown" : BungeeCord.class.getPackage().getImplementationVersion();
|
||||
}
|
||||
|
||||
public void reloadMessages()
|
||||
public final void reloadMessages()
|
||||
{
|
||||
Map<String, Format> cachedFormats = new HashMap<>();
|
||||
|
||||
File file = new File( "messages.properties" );
|
||||
if ( file.isFile() )
|
||||
{
|
||||
try ( FileReader rd = new FileReader( file ) )
|
||||
{
|
||||
customBundle = new PropertyResourceBundle( rd );
|
||||
cacheResourceBundle( cachedFormats, new PropertyResourceBundle( rd ) );
|
||||
} catch ( IOException ex )
|
||||
{
|
||||
getLogger().log( Level.SEVERE, "Could not load custom messages.properties", ex );
|
||||
}
|
||||
}
|
||||
|
||||
ResourceBundle baseBundle;
|
||||
try
|
||||
{
|
||||
baseBundle = ResourceBundle.getBundle( "messages" );
|
||||
} catch ( MissingResourceException ex )
|
||||
{
|
||||
baseBundle = ResourceBundle.getBundle( "messages", Locale.ENGLISH );
|
||||
}
|
||||
cacheResourceBundle( cachedFormats, baseBundle );
|
||||
|
||||
messageFormats = Collections.unmodifiableMap( cachedFormats );
|
||||
}
|
||||
|
||||
private void cacheResourceBundle(Map<String, Format> map, ResourceBundle resourceBundle)
|
||||
{
|
||||
Enumeration<String> keys = resourceBundle.getKeys();
|
||||
while ( keys.hasMoreElements() )
|
||||
{
|
||||
map.computeIfAbsent( keys.nextElement(), (key) -> new MessageFormat( resourceBundle.getString( key ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslation(String name, Object... args)
|
||||
{
|
||||
String translation = "<translation '" + name + "' missing>";
|
||||
try
|
||||
{
|
||||
translation = MessageFormat.format( customBundle != null && customBundle.containsKey( name ) ? customBundle.getString( name ) : baseBundle.getString( name ), args );
|
||||
} catch ( MissingResourceException ex )
|
||||
{
|
||||
}
|
||||
return translation;
|
||||
Format format = messageFormats.get( name );
|
||||
return ( format != null ) ? format.format( args ) : "<translation '" + name + "' missing>";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -59,6 +59,7 @@ import net.md_5.bungee.protocol.packet.Respawn;
|
||||
import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
|
||||
import net.md_5.bungee.protocol.packet.ScoreboardObjective;
|
||||
import net.md_5.bungee.protocol.packet.ScoreboardScore;
|
||||
import net.md_5.bungee.protocol.packet.ServerData;
|
||||
import net.md_5.bungee.protocol.packet.SetCompression;
|
||||
import net.md_5.bungee.protocol.packet.TabCompleteResponse;
|
||||
import net.md_5.bungee.tab.TabList;
|
||||
@ -678,6 +679,15 @@ public class DownstreamBridge extends PacketHandler
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(ServerData serverData) throws Exception
|
||||
{
|
||||
serverData.setMotd( null );
|
||||
serverData.setIcon( null );
|
||||
con.unsafe().sendPacket( serverData );
|
||||
throw CancelSendSignal.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
@ -314,6 +314,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
||||
Preconditions.checkState( thisState == State.HANDSHAKE, "Not expecting HANDSHAKE" );
|
||||
this.handshake = handshake;
|
||||
ch.setVersion( handshake.getProtocolVersion() );
|
||||
ch.getHandle().pipeline().remove( PipelineUtils.LEGACY_KICKER );
|
||||
|
||||
// Starting with FML 1.8, a "\0FML\0" token is appended to the handshake. This interferes
|
||||
// with Bungee's IP forwarding, so we detect it, and remove it from the host string, for now.
|
||||
|
@ -7,29 +7,29 @@ connect_kick=\u00a7cKicked whilst connecting to {0}: {1}
|
||||
current_server=\u00a76You are currently connected to {0}.
|
||||
fallback_kick=\u00a7cCould not connect to a default or fallback server. Incorrectly configured address/port/firewall? {0}
|
||||
fallback_lobby=\u00a7cCould not connect to target server, you have been moved to a fallback server.
|
||||
lost_connection=[Proxy] Lost connection to server.
|
||||
mojang_fail=Error occurred while contacting login servers, are they down?
|
||||
lost_connection=\u00a7cProxy lost connection to server.
|
||||
mojang_fail=\u00a7cError occurred while contacting login servers, are they down?
|
||||
no_permission=\u00a7cYou do not have permission to execute this command!
|
||||
no_server=\u00a7cThe specified server does not exist.
|
||||
no_server_permission=\u00a7cYou don''t have permission to access this server.
|
||||
outdated_client=Outdated client! Please use {0}
|
||||
outdated_server=Outdated server! I''m still on {0}
|
||||
proxy_full=Server is full!
|
||||
restart=[Proxy] Proxy restarting.
|
||||
outdated_client=\u00a7cOutdated client! Please use {0}
|
||||
outdated_server=\u00a7cOutdated server! I''m still on {0}
|
||||
proxy_full=\u00a7cServer is full!
|
||||
restart=\u00a7cThe proxy server is restarting
|
||||
server_list=\u00a76You may connect to the following servers at this time:
|
||||
server_went_down=\u00a7cThe server you were previously on went down, you have been connected to a fallback server
|
||||
total_players=Total players online: {0}
|
||||
name_invalid=Username contains invalid characters.
|
||||
ping_cannot_connect=\u00a7c[Bungee] Can''t connect to server.
|
||||
offline_mode_player=Not authenticated with Minecraft.net
|
||||
secure_profile_required=A secure profile is required to join this server.
|
||||
secure_profile_expired=Secure profile expired.
|
||||
secure_profile_invalid=Secure profile invalid.
|
||||
name_invalid=\u00a7cUsername contains invalid characters.
|
||||
ping_cannot_connect=\u00a7cCould not request status from target server.
|
||||
offline_mode_player=\u00a7cNot authenticated with Minecraft.net
|
||||
secure_profile_required=\u00a7cA secure profile is required to join this server.
|
||||
secure_profile_expired=\u00a7cSecure profile expired.
|
||||
secure_profile_invalid=\u00a7cSecure profile invalid.
|
||||
message_needed=\u00a7cYou must supply a message.
|
||||
error_occurred_player=\u00a7cAn error occurred while parsing your message. (Hover for details)
|
||||
error_occurred_console=\u00a7cAn error occurred while parsing your message: {0}
|
||||
click_to_connect=Click to connect to the server
|
||||
username_needed=\u00a7cPlease follow this command by a user name.
|
||||
username_needed=\u00a7cPlease follow this command by a username.
|
||||
user_not_online=\u00a7cThat user is not online.
|
||||
user_online_at=\u00a7a{0} \u00a7ris online at {1}
|
||||
send_cmd_usage=\u00a7cNot enough arguments, usage: /send <server|player|all|current> <target>
|
||||
@ -38,5 +38,5 @@ you_got_summoned=\u00a76Summoned to {0} by {1}
|
||||
command_perms_groups=\u00a76You have the following groups: {0}
|
||||
command_perms_permission=\u00a79- {0}
|
||||
command_ip=\u00a79IP of {0} is {1}
|
||||
illegal_chat_characters=\u00a7cillegal characters in chat ({0})
|
||||
illegal_chat_characters=\u00a7cIllegal characters in chat ({0})
|
||||
kick_message=\u00a7cYou have been kicked off the proxy.
|
||||
|
Loading…
Reference in New Issue
Block a user