Make packet charset configurable

Better support for different language clients such as Thai or Korean
This commit is contained in:
P0nk
2021-09-08 08:24:52 +02:00
parent abb0a55ac9
commit 41cb6749c8
8 changed files with 62 additions and 46 deletions

View File

@@ -307,6 +307,7 @@ server:
#Miscellaneous Configuration #Miscellaneous Configuration
TIMEZONE: GMT-3 TIMEZONE: GMT-3
PACKET_CHARSET: US_ASCII # Defaults to US_ASCII if not set
USE_DISPLAY_NUMBERS_WITH_COMMA: true #Enforce comma on displayed strings (use this when USE_UNITPRICE_WITH_COMMA is active and you still want to display comma-separated values). USE_DISPLAY_NUMBERS_WITH_COMMA: true #Enforce comma on displayed strings (use this when USE_UNITPRICE_WITH_COMMA is active and you still want to display comma-separated values).
USE_UNITPRICE_WITH_COMMA: true #Set this accordingly with the layout of the unitPrices on Item.wz XML's, whether it's using commas or dots to represent fractions. USE_UNITPRICE_WITH_COMMA: true #Set this accordingly with the layout of the unitPrices on Item.wz XML's, whether it's using commas or dots to represent fractions.
MAX_MONITORED_BUFFSTATS: 5 #Limits accounting for "dormant" buff effects, that should take place when stronger stat buffs expires. MAX_MONITORED_BUFFSTATS: 5 #Limits accounting for "dormant" buff effects, that should take place when stronger stat buffs expires.

View File

@@ -1,6 +1,7 @@
package config; package config;
import java.util.*; import java.util.HashMap;
import java.util.Map;
public class ServerConfig { public class ServerConfig {
//Thread Tracker Configuration //Thread Tracker Configuration
@@ -153,6 +154,7 @@ public class ServerConfig {
//Miscellaneous Configuration //Miscellaneous Configuration
public String TIMEZONE; public String TIMEZONE;
public String PACKET_CHARSET;
public boolean USE_DISPLAY_NUMBERS_WITH_COMMA; public boolean USE_DISPLAY_NUMBERS_WITH_COMMA;
public boolean USE_UNITPRICE_WITH_COMMA; public boolean USE_UNITPRICE_WITH_COMMA;
public byte MAX_MONITORED_BUFFSTATS; public byte MAX_MONITORED_BUFFSTATS;

View File

@@ -12,37 +12,56 @@ package constants.string;
* MapleStory Server * MapleStory Server
* CharsetConstants * CharsetConstants
*/ */
import config.YamlConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Optional;
public class CharsetConstants { public class CharsetConstants {
private static final Logger log = LoggerFactory.getLogger(CharsetConstants.class);
public static MapleLanguageType MAPLE_TYPE = MapleLanguageType.LANGUAGE_US; public static final Charset PACKET_CHARSET = loadCharset();
public enum MapleLanguageType { private enum Language {
LANGUAGE_PT_BR(1, "ISO-8859-1"), LANGUAGE_US("US-ASCII"),
LANGUAGE_US(2, "US-ASCII"); LANGUAGE_PT_BR("ISO-8859-1"),
final byte type; LANGUAGE_THAI("TIS620"),
final String ascii; LANGUAGE_KOREAN("MS949");
private MapleLanguageType(int type, String ascii) { private final String charset;
this.type = (byte) type;
this.ascii = ascii; Language(String charset) {
this.charset = charset;
} }
public String getAscii() { public String getCharset() {
return ascii; return charset;
} }
public byte getType() { public static Language fromCharset(String charset) {
return type; Optional<Language> language = Arrays.stream(values())
} .filter(l -> l.charset.equals(charset))
.findAny();
public static MapleLanguageType getByType(byte type) { if (language.isEmpty()) {
for (MapleLanguageType l : MapleLanguageType.values()) { log.warn("Charset {} was not found, defaulting to US-ASCII", charset);
if (l.getType() == type) { return LANGUAGE_US;
return l;
}
} }
return LANGUAGE_PT_BR;
return language.get();
} }
} }
private static Charset loadCharset() {
String configCharset = YamlConfig.config.server.PACKET_CHARSET;
if (configCharset != null) {
Language language = Language.fromCharset(configCharset);
return Charset.forName(language.getCharset());
}
return StandardCharsets.US_ASCII;
}
} }

View File

@@ -1,5 +1,6 @@
package net.packet; package net.packet;
import constants.string.CharsetConstants;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBufUtil;
@@ -49,7 +50,7 @@ public class ByteBufInPacket implements InPacket {
short length = readShort(); short length = readShort();
byte[] stringBytes = new byte[length]; byte[] stringBytes = new byte[length];
byteBuf.readBytes(stringBytes); byteBuf.readBytes(stringBytes);
return new String(stringBytes, STRING_CHARSET); return new String(stringBytes, CharsetConstants.PACKET_CHARSET);
} }
@Override @Override

View File

@@ -1,5 +1,6 @@
package net.packet; package net.packet;
import constants.string.CharsetConstants;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
@@ -77,12 +78,12 @@ public class ByteBufOutPacket implements OutPacket {
@Override @Override
public void writeString(String value) { public void writeString(String value) {
writeShort((short) value.length()); writeShort((short) value.length());
writeBytes(value.getBytes(STRING_CHARSET)); writeBytes(value.getBytes(CharsetConstants.PACKET_CHARSET));
} }
@Override @Override
public void writeFixedString(String value) { public void writeFixedString(String value) {
writeBytes(value.getBytes(STRING_CHARSET)); writeBytes(value.getBytes(CharsetConstants.PACKET_CHARSET));
} }
@Override @Override

View File

@@ -1,10 +1,5 @@
package net.packet; package net.packet;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public interface Packet { public interface Packet {
Charset STRING_CHARSET = StandardCharsets.US_ASCII;
byte[] getBytes(); byte[] getBytes();
} }

View File

@@ -43,7 +43,7 @@ public class HexTool {
} }
return hexed.substring(0, hexed.length() - 1); return hexed.substring(0, hexed.length() - 1);
} }
public static String toCompressedString(byte[] bytes) { public static String toCompressedString(byte[] bytes) {
StringBuilder hexed = new StringBuilder(); StringBuilder hexed = new StringBuilder();
for (byte aByte : bytes) { for (byte aByte : bytes) {
@@ -87,8 +87,8 @@ public class HexTool {
} }
return baos.toByteArray(); return baos.toByteArray();
} }
public static final String toStringFromAscii(final byte[] bytes) { public static String toStringFromAscii(final byte[] bytes) {
byte[] ret = new byte[bytes.length]; byte[] ret = new byte[bytes.length];
for (int x = 0; x < bytes.length; x++) { for (int x = 0; x < bytes.length; x++) {
if (bytes[x] < 32 && bytes[x] >= 0) { if (bytes[x] < 32 && bytes[x] >= 0) {
@@ -98,12 +98,8 @@ public class HexTool {
ret[x] = (byte) chr; ret[x] = (byte) chr;
} }
} }
String encode = CharsetConstants.MAPLE_TYPE.getAscii();
try { return new String(ret, CharsetConstants.PACKET_CHARSET);
String str = new String(ret, encode);
return str;
} catch (Exception e) {}
return "";
} }
/** /**

View File

@@ -1,5 +1,6 @@
package net.packet; package net.packet;
import constants.string.CharsetConstants;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import net.opcodes.SendOpcode; import net.opcodes.SendOpcode;
@@ -82,7 +83,7 @@ class ByteBufInPacketTest {
void readString() { void readString() {
final String writtenString = "You have gained experience (+3200)"; final String writtenString = "You have gained experience (+3200)";
byteBuf.writeShortLE(writtenString.length()); byteBuf.writeShortLE(writtenString.length());
byte[] writtenStringBytes = writtenString.getBytes(Packet.STRING_CHARSET); byte[] writtenStringBytes = writtenString.getBytes(CharsetConstants.PACKET_CHARSET);
byteBuf.writeBytes(writtenStringBytes); byteBuf.writeBytes(writtenStringBytes);
String readString = inPacket.readString(); String readString = inPacket.readString();