Added chat support for ä/ö/å characters

This commit is contained in:
dam
2026-05-30 17:38:42 +03:00
committed by Ryan
parent 130cc79a17
commit bc6fd94f46
4 changed files with 52 additions and 24 deletions
@@ -11,7 +11,6 @@ import core.tools.*
import core.api.* import core.api.*
import core.game.world.GameWorld import core.game.world.GameWorld
import java.nio.charset.StandardCharsets
import kotlin.reflect.* import kotlin.reflect.*
import kotlin.math.max import kotlin.math.max
@@ -28,12 +27,13 @@ sealed class PlayerFlags530 (p: Int, o: Int, f: EntityFlag) : EFlagProvider (530
else else
buffer.p1 (context.chatIcon) buffer.p1 (context.chatIcon)
val chatBuf = ByteArray(256) val chatBuf = ByteArray(256)
chatBuf[0] = context.text.length.toByte() val encodedText = CP1252.toBytes(context.text)
chatBuf[0] = encodedText.size.toByte()
val offset = 1 + StringUtils.encryptPlayerChat ( val offset = 1 + StringUtils.encryptPlayerChat (
chatBuf, chatBuf,
0, 1, 0, 1,
context.text.length, encodedText.size,
context.text.toByteArray(StandardCharsets.UTF_8) encodedText
) )
buffer.p1 (offset + 1) buffer.p1 (offset + 1)
buffer.putReverse (chatBuf, 0, offset) buffer.putReverse (chatBuf, 0, offset)
@@ -6,6 +6,7 @@ import core.net.packet.IoBuffer;
import core.net.packet.OutgoingPacket; import core.net.packet.OutgoingPacket;
import core.net.packet.PacketHeader; import core.net.packet.PacketHeader;
import core.net.packet.context.MessageContext; import core.net.packet.context.MessageContext;
import core.tools.CP1252;
import core.tools.StringUtils; import core.tools.StringUtils;
import core.game.bots.AIPlayer; import core.game.bots.AIPlayer;
@@ -21,20 +22,21 @@ public final class CommunicationMessage implements OutgoingPacket<MessageContext
public void send(MessageContext context) { public void send(MessageContext context) {
IoBuffer buffer = new IoBuffer(context.getOpcode(), PacketHeader.BYTE); IoBuffer buffer = new IoBuffer(context.getOpcode(), PacketHeader.BYTE);
String message = context.getMessage(); String message = context.getMessage();
byte[] encodedMessage = CP1252.toBytes(message);
Player player = context.getPlayer(); Player player = context.getPlayer();
String other = context.getOther(); String other = context.getOther();
switch (context.getOpcode()) { switch (context.getOpcode()) {
case MessageContext.SEND_MESSAGE: case MessageContext.SEND_MESSAGE:
byte[] bytes = new byte[256]; byte[] bytes = new byte[256];
int length = StringUtils.encryptPlayerChat(bytes, 0, 0, message.length(), message.getBytes()); int length = StringUtils.encryptPlayerChat(bytes, 0, 0, encodedMessage.length, encodedMessage);
buffer.putLong(StringUtils.stringToLong(other)); buffer.putLong(StringUtils.stringToLong(other));
buffer.put((byte) message.length()); buffer.put((byte) encodedMessage.length);
buffer.putBytes(bytes, 0, length); buffer.putBytes(bytes, 0, length);
break; break;
case MessageContext.RECIEVE_MESSAGE: case MessageContext.RECIEVE_MESSAGE:
bytes = new byte[256]; bytes = new byte[256];
bytes[0] = (byte) message.length(); bytes[0] = (byte) encodedMessage.length;
length = 1 + StringUtils.encryptPlayerChat(bytes, 0, 1, message.length(), message.getBytes()); length = 1 + StringUtils.encryptPlayerChat(bytes, 0, 1, encodedMessage.length, encodedMessage);
player.setAttribute("replyTo", other); player.setAttribute("replyTo", other);
buffer.putLong(StringUtils.stringToLong(other)).putShort(new Random().nextInt(0xFFFF)).putTri(getMessageIndex(player)).put((byte) context.getChatIcon()).putBytes(bytes, 0, length); buffer.putLong(StringUtils.stringToLong(other)).putShort(new Random().nextInt(0xFFFF)).putTri(getMessageIndex(player)).put((byte) context.getChatIcon()).putBytes(bytes, 0, length);
break; break;
@@ -44,8 +46,8 @@ public final class CommunicationMessage implements OutgoingPacket<MessageContext
return; return;
} }
bytes = new byte[256]; bytes = new byte[256];
bytes[0] = (byte) context.getMessage().length(); bytes[0] = (byte) encodedMessage.length;
length = 1 + StringUtils.encryptPlayerChat(bytes, 0, 1, message.length(), message.getBytes()); length = 1 + StringUtils.encryptPlayerChat(bytes, 0, 1, encodedMessage.length, encodedMessage);
buffer.putLong(StringUtils.stringToLong(other)); buffer.putLong(StringUtils.stringToLong(other));
buffer.put((byte) 0);// it's just read does nothing buffer.put((byte) 0);// it's just read does nothing
buffer.putLong(StringUtils.stringToLong(clan.getName())); buffer.putLong(StringUtils.stringToLong(clan.getName()));
+29 -3
View File
@@ -1,18 +1,22 @@
package core.tools; package core.tools;
public class CP1252 { public final class CP1252 {
private static char[] charMap = {'\u20ac', '\0', '\u201a', '\u0192', '\u201e', '\u2026', '\u2020', '\u2021', private static final char[] CHAR_MAP = {'\u20ac', '\0', '\u201a', '\u0192', '\u201e', '\u2026', '\u2020', '\u2021',
'\u02c6', '\u2030', '\u0160', '\u2039', '\u0152', '\0', '\u017d', '\0', '\0', '\u2018', '\u2019', '\u02c6', '\u2030', '\u0160', '\u2039', '\u0152', '\0', '\u017d', '\0', '\0', '\u2018', '\u2019',
'\u201c', '\u201d', '\u2022', '\u2013', '\u2014', '\u02dc', '\u2122', '\u0161', '\u203a', '\u0153', '\u201c', '\u201d', '\u2022', '\u2013', '\u2014', '\u02dc', '\u2122', '\u0161', '\u203a', '\u0153',
'\0', '\u017e', '\u0178'}; '\0', '\u017e', '\u0178'};
private CP1252() {
/* utility class */
}
public static char getFromByte(byte value) { public static char getFromByte(byte value) {
int out = value & 0xff; int out = value & 0xff;
if (out == 0) { if (out == 0) {
throw new IllegalArgumentException("Non cp1252 character 0x" + Integer.toString(out, 16) + " provided"); throw new IllegalArgumentException("Non cp1252 character 0x" + Integer.toString(out, 16) + " provided");
} }
if (out >= 128 && out < 160) { if (out >= 128 && out < 160) {
int cp1252 = charMap[out - 128]; int cp1252 = CHAR_MAP[out - 128];
if (cp1252 == 0) { if (cp1252 == 0) {
cp1252 = 63; cp1252 = 63;
} }
@@ -20,4 +24,26 @@ public class CP1252 {
} }
return (char) out; return (char) out;
} }
public static byte getByte(char value) {
if ((value > 0 && value < 128) || (value >= 160 && value <= 255)) {
return (byte) value;
}
for (int i = 0; i < CHAR_MAP.length; i++) {
if (CHAR_MAP[i] != 0 && CHAR_MAP[i] == value) {
return (byte) (i + 128);
}
}
return 63;
}
public static byte[] toBytes(CharSequence value) {
byte[] out = new byte[value.length()];
for (int i = 0; i < value.length(); i++) {
out[i] = getByte(value.charAt(i));
}
return out;
}
} }
+10 -10
View File
@@ -502,7 +502,7 @@ public final class StringUtils {
return ""; return "";
int charsDecoded = 0; int charsDecoded = 0;
int i_4_ = 0; int i_4_ = 0;
String s = ""; StringBuilder s = new StringBuilder(totalChars);
for (;;) { for (;;) {
byte i_7_ = (byte) buffer.get(); byte i_7_ = (byte) buffer.get();
if (i_7_ >= 0) if (i_7_ >= 0)
@@ -511,7 +511,7 @@ public final class StringUtils {
i_4_ = anIntArray241[i_4_]; i_4_ = anIntArray241[i_4_];
int i_8_; int i_8_;
if ((i_8_ = anIntArray241[i_4_]) < 0) { if ((i_8_ = anIntArray241[i_4_]) < 0) {
s += (char) (byte) (i_8_ ^ 0xffffffff); s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff)));
if (totalChars <= ++charsDecoded) if (totalChars <= ++charsDecoded)
break; break;
i_4_ = 0; i_4_ = 0;
@@ -521,7 +521,7 @@ public final class StringUtils {
else else
i_4_++; i_4_++;
if ((i_8_ = anIntArray241[i_4_]) < 0) { if ((i_8_ = anIntArray241[i_4_]) < 0) {
s += (char) (byte) (i_8_ ^ 0xffffffff); s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff)));
if (++charsDecoded >= totalChars) if (++charsDecoded >= totalChars)
break; break;
i_4_ = 0; i_4_ = 0;
@@ -531,7 +531,7 @@ public final class StringUtils {
else else
i_4_ = anIntArray241[i_4_]; i_4_ = anIntArray241[i_4_];
if ((i_8_ = anIntArray241[i_4_]) < 0) { if ((i_8_ = anIntArray241[i_4_]) < 0) {
s += (char) (byte) (i_8_ ^ 0xffffffff); s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff)));
if (totalChars <= ++charsDecoded) if (totalChars <= ++charsDecoded)
break; break;
i_4_ = 0; i_4_ = 0;
@@ -541,7 +541,7 @@ public final class StringUtils {
else else
i_4_ = anIntArray241[i_4_]; i_4_ = anIntArray241[i_4_];
if ((i_8_ = anIntArray241[i_4_]) < 0) { if ((i_8_ = anIntArray241[i_4_]) < 0) {
s += (char) (byte) (i_8_ ^ 0xffffffff); s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff)));
if (totalChars <= ++charsDecoded) if (totalChars <= ++charsDecoded)
break; break;
@@ -552,7 +552,7 @@ public final class StringUtils {
else else
i_4_++; i_4_++;
if ((i_8_ = anIntArray241[i_4_]) < 0) { if ((i_8_ = anIntArray241[i_4_]) < 0) {
s += (char) (byte) (i_8_ ^ 0xffffffff); s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff)));
if (++charsDecoded >= totalChars) if (++charsDecoded >= totalChars)
break; break;
i_4_ = 0; i_4_ = 0;
@@ -562,7 +562,7 @@ public final class StringUtils {
else else
i_4_ = anIntArray241[i_4_]; i_4_ = anIntArray241[i_4_];
if ((i_8_ = anIntArray241[i_4_]) < 0) { if ((i_8_ = anIntArray241[i_4_]) < 0) {
s += (char) (byte) (i_8_ ^ 0xffffffff); s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff)));
if (totalChars <= ++charsDecoded) if (totalChars <= ++charsDecoded)
break; break;
i_4_ = 0; i_4_ = 0;
@@ -572,7 +572,7 @@ public final class StringUtils {
else else
i_4_++; i_4_++;
if ((i_8_ = anIntArray241[i_4_]) < 0) { if ((i_8_ = anIntArray241[i_4_]) < 0) {
s += (char) (byte) (i_8_ ^ 0xffffffff); s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff)));
if (totalChars <= ++charsDecoded) if (totalChars <= ++charsDecoded)
break; break;
i_4_ = 0; i_4_ = 0;
@@ -582,13 +582,13 @@ public final class StringUtils {
else else
i_4_++; i_4_++;
if ((i_8_ = anIntArray241[i_4_]) < 0) { if ((i_8_ = anIntArray241[i_4_]) < 0) {
s += (char) (byte) (i_8_ ^ 0xffffffff); s.append(CP1252.getFromByte((byte) (i_8_ ^ 0xffffffff)));
if (++charsDecoded >= totalChars) if (++charsDecoded >= totalChars)
break; break;
i_4_ = 0; i_4_ = 0;
} }
} }
return s; return s.toString();
} catch (RuntimeException runtimeexception) { } catch (RuntimeException runtimeexception) {
runtimeexception.printStackTrace(); runtimeexception.printStackTrace();
} }