4
.github/workflows/pr-pipeline.yml
vendored
4
.github/workflows/pr-pipeline.yml
vendored
@@ -14,10 +14,10 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Set up JDK 16
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v2
|
||||||
with:
|
with:
|
||||||
java-version: '16'
|
java-version: '17'
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
- name: Build with Maven (compile -> test -> package)
|
- name: Build with Maven (compile -> test -> package)
|
||||||
run: mvn -B package --file pom.xml
|
run: mvn -B package --file pom.xml
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# Cosmic JAR creation stage
|
# Cosmic JAR creation stage
|
||||||
#
|
#
|
||||||
FROM maven:3.8.1-openjdk-16 AS jar
|
FROM maven:3.8.4-openjdk-17 AS jar
|
||||||
|
|
||||||
# Build in a separated location which won't have permissions issues.
|
# Build in a separated location which won't have permissions issues.
|
||||||
WORKDIR /opt/cosmic
|
WORKDIR /opt/cosmic
|
||||||
@@ -21,7 +21,7 @@ RUN mvn -f ./pom.xml clean package -Dmaven.test.skip -T 1C
|
|||||||
#
|
#
|
||||||
# Server creation stage
|
# Server creation stage
|
||||||
#
|
#
|
||||||
FROM openjdk:16
|
FROM openjdk:17.0.2
|
||||||
|
|
||||||
# Host the server in a location that won't have permissions issues.
|
# Host the server in a location that won't have permissions issues.
|
||||||
WORKDIR /opt/server
|
WORKDIR /opt/server
|
||||||
|
|||||||
42
pom.xml
42
pom.xml
@@ -11,45 +11,58 @@
|
|||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
<!-- Project -->
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<java.version>16</java.version>
|
<java.version>17</java.version>
|
||||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||||
<mainClass>net.server.Server</mainClass>
|
<mainClass>net.server.Server</mainClass>
|
||||||
|
|
||||||
<log4j.version>2.17.1</log4j.version>
|
<!-- Maven plugins -->
|
||||||
<graalvm.version>21.1.0</graalvm.version>
|
<maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version> <!-- For running unit tests -->
|
||||||
<netty.version>4.1.67.Final</netty.version>
|
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version> <!-- Disabled. (for building thin jar) -->
|
||||||
<junit.version>5.7.2</junit.version>
|
<maven-assembly-plugin.version>3.3.0</maven-assembly-plugin.version> <!-- For packaging the executable fat jar -->
|
||||||
|
|
||||||
|
<!-- Dependencies -->
|
||||||
|
<slf4j-api.version>1.7.36</slf4j-api.version> <!-- Logging facade -->
|
||||||
|
<log4j.version>2.17.1</log4j.version> <!-- Slf4j implementation -->
|
||||||
|
<graalvm.version>21.1.0</graalvm.version> <!-- ScriptEngine implementation -->
|
||||||
|
<netty.version>4.1.74.Final</netty.version> <!-- Networking -->
|
||||||
|
<junit.version>5.8.2</junit.version> <!-- Unit test -->
|
||||||
|
<yamlbeans.version>1.15</yamlbeans.version> <!-- Config file -->
|
||||||
|
<jcip-annotations.version>1.0</jcip-annotations.version> <!-- Annotations for concurrency documentation -->
|
||||||
|
<commons-io.version>2.11.0</commons-io.version> <!-- Util library used by some of our tools -->
|
||||||
|
<HikariCP.version>5.0.1</HikariCP.version> <!-- Database connection pool -->
|
||||||
|
<mysql-connector-java.version>8.0.28</mysql-connector-java.version> <!-- MySQL JDBC driver -->
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.esotericsoftware.yamlbeans</groupId>
|
<groupId>com.esotericsoftware.yamlbeans</groupId>
|
||||||
<artifactId>yamlbeans</artifactId>
|
<artifactId>yamlbeans</artifactId>
|
||||||
<version>1.15</version>
|
<version>${yamlbeans.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.jcip</groupId>
|
<groupId>net.jcip</groupId>
|
||||||
<artifactId>jcip-annotations</artifactId>
|
<artifactId>jcip-annotations</artifactId>
|
||||||
<version>1.0</version>
|
<version>${jcip-annotations.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency> <!-- only used for some tools -->
|
<dependency> <!-- only used for some tools -->
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>2.11.0</version>
|
<version>${commons-io.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Database -->
|
<!-- Database -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.zaxxer</groupId>
|
<groupId>com.zaxxer</groupId>
|
||||||
<artifactId>HikariCP</artifactId>
|
<artifactId>HikariCP</artifactId>
|
||||||
<version>5.0.0</version>
|
<version>${HikariCP.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>mysql</groupId>
|
<groupId>mysql</groupId>
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
<version>8.0.26</version>
|
<version>${mysql-connector-java.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Networking -->
|
<!-- Networking -->
|
||||||
@@ -78,7 +91,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<version>1.7.32</version>
|
<version>${slf4j-api.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
@@ -120,7 +133,6 @@
|
|||||||
<version>${junit.version}</version>
|
<version>${junit.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -129,7 +141,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>3.2.0</version>
|
<version>${maven-jar-plugin.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>default-jar</id>
|
<id>default-jar</id>
|
||||||
@@ -141,14 +153,14 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.0.0-M5</version>
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<!-- Enable assembling jar that includes all dependencies -->
|
<!-- Enable assembling jar that includes all dependencies -->
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
<version>3.3.0</version>
|
<version>${maven-assembly-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<descriptorRefs>
|
<descriptorRefs>
|
||||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
|||||||
@@ -1335,7 +1335,7 @@ public class Client extends ChannelInboundHandlerAdapter {
|
|||||||
try {
|
try {
|
||||||
MessageDigest digester = MessageDigest.getInstance(type);
|
MessageDigest digester = MessageDigest.getInstance(type);
|
||||||
digester.update(password.getBytes(StandardCharsets.UTF_8), 0, password.length());
|
digester.update(password.getBytes(StandardCharsets.UTF_8), 0, password.length());
|
||||||
return HexTool.toString(digester.digest()).replace(" ", "").toLowerCase().equals(hash);
|
return HexTool.toHexString(digester.digest()).replace(" ", "").toLowerCase().equals(hash);
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
throw new RuntimeException("Encoding the string failed", e);
|
throw new RuntimeException("Encoding the string failed", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class PeCommand extends Command {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] packetContent = HexTool.getByteArrayFromHexString(packet);
|
byte[] packetContent = HexTool.toBytes(packet);
|
||||||
InPacket inPacket = new ByteBufInPacket(Unpooled.wrappedBuffer(packetContent));
|
InPacket inPacket = new ByteBufInPacket(Unpooled.wrappedBuffer(packetContent));
|
||||||
short packetId = inPacket.readShort();
|
short packetId = inPacket.readShort();
|
||||||
final PacketHandler packetHandler = PacketProcessor.getProcessor(0, c.getChannel()).getHandler(packetId);
|
final PacketHandler packetHandler = PacketProcessor.getProcessor(0, c.getChannel()).getHandler(packetId);
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ public class MapleAESOFB {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "IV: " + HexTool.toString(this.iv);
|
return "IV: " + HexTool.toHexString(this.iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] funnyShit(byte inputByte, byte[] in) {
|
private static byte[] funnyShit(byte inputByte, byte[] in) {
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ public class InPacketLogger extends ChannelInboundHandlerAdapter implements Pack
|
|||||||
final String opcodeName = getRecvOpcodeName(opcode);
|
final String opcodeName = getRecvOpcodeName(opcode);
|
||||||
final String prefix = opcodeName == null ? "<UnknownPacket> " : "";
|
final String prefix = opcodeName == null ? "<UnknownPacket> " : "";
|
||||||
log.debug("{}ClientSend:{} [{}] ({}) <HEX> {} <TEXT> {}", prefix, opcodeName, opcodeHex, packetLength,
|
log.debug("{}ClientSend:{} [{}] ({}) <HEX> {} <TEXT> {}", prefix, opcodeName, opcodeHex, packetLength,
|
||||||
HexTool.toString(content), HexTool.toStringFromAscii(content));
|
HexTool.toHexString(content), HexTool.toStringFromAscii(content));
|
||||||
} else {
|
} else {
|
||||||
log.debug(HexTool.toString(new byte[]{content[0], content[1]}) + "...");
|
log.debug(HexTool.toHexString(new byte[]{content[0], content[1]}) + "...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public class MonitoredChrLogger {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String packet = packetContent.length > 0 ? HexTool.toString(packetContent) : "<empty>";
|
String packet = packetContent.length > 0 ? HexTool.toHexString(packetContent) : "<empty>";
|
||||||
log.info("{}-{} {}-{}", c.getAccountName(), chr.getName(), packetId, packet);
|
log.info("{}-{} {}-{}", c.getAccountName(), chr.getName(), packetId, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ public class OutPacketLogger extends ChannelOutboundHandlerAdapter implements Pa
|
|||||||
String opcodeName = getSendOpcodeName(opcode);
|
String opcodeName = getSendOpcodeName(opcode);
|
||||||
String prefix = opcodeName == null ? "<UnknownPacket> " : "";
|
String prefix = opcodeName == null ? "<UnknownPacket> " : "";
|
||||||
log.debug("{}ServerSend:{} [{}] ({}) <HEX> {} <TEXT> {}", prefix, opcodeName, opcodeHex, packetLength,
|
log.debug("{}ServerSend:{} [{}] ({}) <HEX> {} <TEXT> {}", prefix, opcodeName, opcodeHex, packetLength,
|
||||||
HexTool.toString(content), HexTool.toStringFromAscii(content));
|
HexTool.toHexString(content), HexTool.toStringFromAscii(content));
|
||||||
} else {
|
} else {
|
||||||
log.debug(HexTool.toString(new byte[]{content[0], content[1]}) + " ...");
|
log.debug(HexTool.toHexString(new byte[]{content[0], content[1]}) + " ...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public final class LoginPasswordHandler implements PacketHandler {
|
|||||||
private static String hashpwSHA512(String pwd) throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
private static String hashpwSHA512(String pwd) throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
||||||
MessageDigest digester = MessageDigest.getInstance("SHA-512");
|
MessageDigest digester = MessageDigest.getInstance("SHA-512");
|
||||||
digester.update(pwd.getBytes(StandardCharsets.UTF_8), 0, pwd.length());
|
digester.update(pwd.getBytes(StandardCharsets.UTF_8), 0, pwd.length());
|
||||||
return HexTool.toString(digester.digest()).replace(" ", "").toLowerCase();
|
return HexTool.toHexString(digester.digest()).replace(" ", "").toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -67,7 +67,7 @@ public final class LoginPasswordHandler implements PacketHandler {
|
|||||||
|
|
||||||
p.skip(6); // localhost masked the initial part with zeroes...
|
p.skip(6); // localhost masked the initial part with zeroes...
|
||||||
byte[] hwidNibbles = p.readBytes(4);
|
byte[] hwidNibbles = p.readBytes(4);
|
||||||
Hwid hwid = new Hwid(HexTool.bytesToHex(hwidNibbles));
|
Hwid hwid = new Hwid(HexTool.toCompactHexString(hwidNibbles));
|
||||||
int loginok = c.login(login, pwd, hwid);
|
int loginok = c.login(login, pwd, hwid);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,94 +22,68 @@
|
|||||||
package tools;
|
package tools;
|
||||||
|
|
||||||
import constants.string.CharsetConstants;
|
import constants.string.CharsetConstants;
|
||||||
import io.netty.buffer.ByteBufUtil;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.util.HexFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles converting back and forth from byte arrays to hex strings.
|
||||||
|
*/
|
||||||
public class HexTool {
|
public class HexTool {
|
||||||
private static final char[] HEX = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
|
||||||
|
|
||||||
private static String toString(byte byteValue) {
|
/**
|
||||||
int tmp = byteValue << 8;
|
* Convert a byte array to its hex string representation (upper case).
|
||||||
char[] retstr = new char[]{HEX[(tmp >> 12) & 0x0F], HEX[(tmp >> 8) & 0x0F]};
|
* Each byte value is converted to two hex characters delimited by a space.
|
||||||
return String.valueOf(retstr);
|
*
|
||||||
}
|
* @param bytes Byte array to convert to a hex string.
|
||||||
|
* Example: {1, 16, 127, -1} is converted to "01 F0 7F FF"
|
||||||
public static String toString(byte[] bytes) {
|
* @return The hex string
|
||||||
StringBuilder hexed = new StringBuilder();
|
*/
|
||||||
for (byte aByte : bytes) {
|
public static String toHexString(byte[] bytes) {
|
||||||
hexed.append(toString(aByte));
|
return HexFormat.ofDelimiter(" ").withUpperCase().formatHex(bytes);
|
||||||
hexed.append(' ');
|
|
||||||
}
|
|
||||||
return hexed.substring(0, hexed.length() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toCompressedString(byte[] bytes) {
|
|
||||||
StringBuilder hexed = new StringBuilder();
|
|
||||||
for (byte aByte : bytes) {
|
|
||||||
hexed.append(toString(aByte));
|
|
||||||
}
|
|
||||||
return hexed.substring(0, hexed.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] getByteArrayFromHexString(String hex) {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
int nexti = 0;
|
|
||||||
int nextb = 0;
|
|
||||||
boolean highoc = true;
|
|
||||||
outer:
|
|
||||||
for (; ; ) {
|
|
||||||
int number = -1;
|
|
||||||
while (number == -1) {
|
|
||||||
if (nexti == hex.length()) {
|
|
||||||
break outer;
|
|
||||||
}
|
|
||||||
char chr = hex.charAt(nexti);
|
|
||||||
if (chr >= '0' && chr <= '9') {
|
|
||||||
number = chr - '0';
|
|
||||||
} else if (chr >= 'a' && chr <= 'f') {
|
|
||||||
number = chr - 'a' + 10;
|
|
||||||
} else if (chr >= 'A' && chr <= 'F') {
|
|
||||||
number = chr - 'A' + 10;
|
|
||||||
} else {
|
|
||||||
number = -1;
|
|
||||||
}
|
|
||||||
nexti++;
|
|
||||||
}
|
|
||||||
if (highoc) {
|
|
||||||
nextb = number << 4;
|
|
||||||
highoc = false;
|
|
||||||
} else {
|
|
||||||
nextb |= number;
|
|
||||||
highoc = true;
|
|
||||||
baos.write(nextb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return baos.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toStringFromAscii(final byte[] bytes) {
|
|
||||||
byte[] ret = new byte[bytes.length];
|
|
||||||
for (int x = 0; x < bytes.length; x++) {
|
|
||||||
if (bytes[x] < 32 && bytes[x] >= 0) {
|
|
||||||
ret[x] = '.';
|
|
||||||
} else {
|
|
||||||
int chr = ((short) bytes[x]) & 0xFF;
|
|
||||||
ret[x] = (byte) chr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String(ret, CharsetConstants.CHARSET);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get upper case hex dump
|
* Convert a byte array to its hex string representation (upper case).
|
||||||
|
* Like {@link #toHexString(byte[]) HexTool.toString}, but with no space delimiter.
|
||||||
|
*
|
||||||
|
* @return The compact hex string
|
||||||
*/
|
*/
|
||||||
public static String bytesToHex(byte[] bytes) {
|
public static String toCompactHexString(byte[] bytes) {
|
||||||
return ByteBufUtil.hexDump(bytes).toUpperCase();
|
return HexFormat.of().withUpperCase().formatHex(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] hexToBytes(String hex) {
|
/**
|
||||||
return ByteBufUtil.decodeHexDump(hex);
|
* Convert a hex string to its byte array representation. Two consecutive hex characters are converted to one byte.
|
||||||
|
*
|
||||||
|
* @param hexString Hex string to convert to bytes. May be lower or upper case, and hex character pairs may be
|
||||||
|
* delimited by a space or not.
|
||||||
|
* Example: "01 10 7F FF" is converted to {1, 16, 127, -1}.
|
||||||
|
* The following hex strings are considered identical and are converted to the same byte array:
|
||||||
|
* "01 10 7F FF", "01107FFF", "01 10 7f ff", "01107fff"
|
||||||
|
* @return The byte array
|
||||||
|
*/
|
||||||
|
public static byte[] toBytes(String hexString) {
|
||||||
|
return HexFormat.of().parseHex(removeAllSpaces(hexString));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String removeAllSpaces(String input) {
|
||||||
|
return input.replaceAll("\\s", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toStringFromAscii(final byte[] bytes) {
|
||||||
|
byte[] filteredBytes = new byte[bytes.length];
|
||||||
|
for (int i = 0; i < bytes.length; i++) {
|
||||||
|
if (isSpecialCharacter(bytes[i])) {
|
||||||
|
filteredBytes[i] = '.';
|
||||||
|
} else {
|
||||||
|
filteredBytes[i] = (byte) (bytes[i] & 0xFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new String(filteredBytes, CharsetConstants.CHARSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isSpecialCharacter(byte asciiCode) {
|
||||||
|
return asciiCode >= 0 && asciiCode <= 31;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3307,7 +3307,7 @@ public class PacketCreator {
|
|||||||
p.writeByte(msgType);
|
p.writeByte(msgType);
|
||||||
p.writeByte(speaker);
|
p.writeByte(speaker);
|
||||||
p.writeString(talk);
|
p.writeString(talk);
|
||||||
p.writeBytes(HexTool.getByteArrayFromHexString(endBytes));
|
p.writeBytes(HexTool.toBytes(endBytes));
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6887,7 +6887,7 @@ public class PacketCreator {
|
|||||||
|
|
||||||
public static Packet customPacket(String packet) {
|
public static Packet customPacket(String packet) {
|
||||||
OutPacket p = new ByteBufOutPacket();
|
OutPacket p = new ByteBufOutPacket();
|
||||||
p.writeBytes(HexTool.getByteArrayFromHexString(packet));
|
p.writeBytes(HexTool.toBytes(packet));
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,21 +2,57 @@ package tools;
|
|||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
class HexToolTest {
|
class HexToolTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void upperCaseHexToBytesAndBack() {
|
void bytesToHexString() {
|
||||||
String hex = "A1B2C3";
|
byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 127, -1};
|
||||||
byte[] bytes = HexTool.hexToBytes(hex);
|
String expectedHexString = "01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 7F FF";
|
||||||
assertEquals(hex, HexTool.bytesToHex(bytes));
|
assertEquals(expectedHexString, HexTool.toHexString(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void mixedCaseHexToBytesAndBack() {
|
void bytesToCompactHexString() {
|
||||||
String hex = "aB5DaA";
|
byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 127, -1};
|
||||||
byte[] bytes = HexTool.hexToBytes(hex);
|
String expectedHexString = "0102030405060708090A0B0C0D0E0F10117FFF";
|
||||||
assertEquals(hex.toUpperCase(), HexTool.bytesToHex(bytes));
|
assertEquals(expectedHexString, HexTool.toCompactHexString(bytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void hexStringWithSpacesToBytes() {
|
||||||
|
String hexString = "01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 7F FF";
|
||||||
|
byte[] expectedBytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 127, -1};
|
||||||
|
assertArrayEquals(expectedBytes, HexTool.toBytes(hexString));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void compactHexStringToBytes() {
|
||||||
|
String hexString = "0102030405060708090A0B0C0D0E0F10117FFF";
|
||||||
|
byte[] expectedBytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 127, -1};
|
||||||
|
assertArrayEquals(expectedBytes, HexTool.toBytes(hexString));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void lowerCaseHexStringToBytes() {
|
||||||
|
String lowerCaseHexString = "01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 7f ff";
|
||||||
|
byte[] expectedBytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 127, -1};
|
||||||
|
assertArrayEquals(expectedBytes, HexTool.toBytes(lowerCaseHexString));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void lowerCaseCompactHexStringToBytes() {
|
||||||
|
String hexString = "0102030405060708090a0b0c0d0e0f10117fff";
|
||||||
|
byte[] expectedBytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 127, -1};
|
||||||
|
assertArrayEquals(expectedBytes, HexTool.toBytes(hexString));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toStringFromAscii() {
|
||||||
|
byte[] asciiBytes = new byte[]{1, 10, 20, 30, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 0, 31};
|
||||||
|
String expectedString = "....0123456789..";
|
||||||
|
assertEquals(expectedString, HexTool.toStringFromAscii(asciiBytes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user