From 2b4e55bd74c9cbeb0d34169e55e3c6840e14981b Mon Sep 17 00:00:00 2001 From: Josh-Larson Date: Sat, 25 Oct 2025 16:33:39 -0500 Subject: [PATCH] Converted NetBuffer and Encodable to Kotlin --- build.gradle.kts | 96 ++-- .../com/projectswg/common/data/Badges.java | 58 ++- .../java/com/projectswg/common/data/CRC.java | 12 +- .../java/com/projectswg/common/data/RGB.java | 12 +- .../data/customization/CustomizationString.kt | 5 +- .../common/data/encodables/chat/ChatAvatar.kt | 3 +- .../common/data/encodables/chat/ChatRoom.kt | 20 +- .../common/data/encodables/gcw/GcwGroup.kt | 17 +- .../data/encodables/gcw/GcwGroupZone.kt | 38 +- .../common/data/encodables/gcw/GcwRegion.kt | 17 +- .../data/encodables/gcw/GcwRegionZone.kt | 40 +- .../common/data/encodables/map/MapLocation.kt | 30 +- .../data/encodables/oob/OutOfBandPackage.kt | 16 +- .../data/encodables/oob/ProsePackage.kt | 25 +- .../common/data/encodables/oob/StringId.kt | 3 +- .../oob/waypoint/WaypointPackage.kt | 15 +- .../common/data/encodables/player/Mail.kt | 7 +- .../data/encodables/tangible/SkillMod.kt | 28 +- .../common/data/location/Location.java | 17 +- .../common/data/location/Point3D.java | 12 +- .../common/data/location/Quaternion.java | 3 +- .../common/data/radial/RadialOptionList.java | 15 +- .../data/schematic/DraftSlotDataOption.java | 17 +- .../common/data/schematic/IngridientSlot.java | 17 +- .../common/data/sui/SuiBaseWindow.kt | 16 +- .../common/data/sui/SuiComponent.kt | 10 +- .../projectswg/common/encoding/Encodable.kt | 27 +- .../projectswg/common/encoding/Encoder.java | 125 ----- .../com/projectswg/common/encoding/Encoder.kt | 104 ++++ .../projectswg/common/network/NetBuffer.java | 454 ------------------ .../projectswg/common/network/NetBuffer.kt | 437 +++++++++++++++++ .../swg/login/EnumerateCharacterId.java | 12 +- .../packets/swg/zone/chat/ChatRoomMessage.kt | 4 +- .../swg/zone/deltas/DeltasMessage.java | 12 +- .../ImageDesignChangeMessage.kt | 29 +- .../ImageDesignEndMessage.kt | 29 +- .../zone/object_controller/IndexParameter.kt | 28 +- .../zone/object_controller/MorphParameter.kt | 28 +- .../packets/swg/zone/spatial/AttributeList.kt | 13 +- 39 files changed, 967 insertions(+), 884 deletions(-) delete mode 100644 src/main/java/com/projectswg/common/encoding/Encoder.java create mode 100644 src/main/java/com/projectswg/common/encoding/Encoder.kt delete mode 100644 src/main/java/com/projectswg/common/network/NetBuffer.java create mode 100644 src/main/java/com/projectswg/common/network/NetBuffer.kt diff --git a/build.gradle.kts b/build.gradle.kts index a331517..56fd4cc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,89 +1,63 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget -/*********************************************************************************** - * Copyright (c) 2023 /// Project SWG /// www.projectswg.com * - * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * - * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * - * * - * This file is part of Holocore. * - * * - * --------------------------------------------------------------------------------* - * * - * Holocore is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * Holocore is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with Holocore. If not, see . * - ***********************************************************************************/ - plugins { idea `java-library` - kotlin("jvm") + kotlin("jvm") version "2.2.21" } +group = "com.projectswg" +version = "1.0.0" +description = "ProjectSWG's SWG Emulator Common Library" + val javaVersion = JavaVersion.current() -val kotlinTargetJdk = JvmTarget.fromTarget(javaVersion.majorVersion) -val junit5Version: String by ext +val kotlinTargetJdk: JvmTarget = JvmTarget.fromTarget(javaVersion.majorVersion) java { modularity.inferModulePath.set(true) + + toolchain { + languageVersion.set(JavaLanguageVersion.of(javaVersion.majorVersion)) + } +} + +kotlin { + compilerOptions { + jvmTarget.set(kotlinTargetJdk) + } } idea { + targetVersion = javaVersion.majorVersion module { inheritOutputDirs = true } } -sourceSets { - main { - java { - output.setResourcesDir(destinationDirectory.get()) - } - } -} - -tasks.named("processResources").configure { dependsOn("compileJava") } - repositories { maven("https://dev.joshlarson.me/maven2") mavenCentral() } -dependencies { - api(group="org.jetbrains", name="annotations", version="26.0.1") - api(group="me.joshlarson", name="jlcommon", version="1.10.1") - api(group="org.bouncycastle", name="bcprov-jdk18on", version="1.79") - implementation(kotlin("stdlib")) - implementation(group="org.mongodb", name="mongodb-driver-sync", version="5.2.1") - - testImplementation(group="org.junit.jupiter", name="junit-jupiter-api", version=junit5Version) - testImplementation(group="org.junit.jupiter", name="junit-jupiter-params", version=junit5Version) - testRuntimeOnly(group="org.junit.jupiter", name="junit-jupiter-engine", version=junit5Version) - testRuntimeOnly(group="org.junit.platform", name="junit-platform-launcher", version="1.12.2") -} - -tasks.withType { - duplicatesStrategy = DuplicatesStrategy.EXCLUDE -} - -tasks.withType().configureEach { - compilerOptions { - jvmTarget.set(kotlinTargetJdk) +sourceSets { + main { + dependencies { + api("org.jetbrains:annotations:20.1.0") + api("me.joshlarson:jlcommon:1.10.1") + api("org.bouncycastle:bcprov-jdk18on:1.71") + implementation(kotlin("stdlib")) + implementation("org.mongodb:mongodb-driver-sync:3.12.2") + } + kotlin.destinationDirectory = java.destinationDirectory + } + test { + dependencies { + testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") + testImplementation("org.junit.jupiter:junit-jupiter-params:5.8.1") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") + } + kotlin.destinationDirectory = java.destinationDirectory } - destinationDirectory.set(File(destinationDirectory.get().asFile.path.replace("kotlin", "java"))) } tasks.withType().configureEach { diff --git a/src/main/java/com/projectswg/common/data/Badges.java b/src/main/java/com/projectswg/common/data/Badges.java index aa4021c..cf0070e 100644 --- a/src/main/java/com/projectswg/common/data/Badges.java +++ b/src/main/java/com/projectswg/common/data/Badges.java @@ -1,29 +1,27 @@ /*********************************************************************************** - * Copyright (c) 2015 /// Project SWG /// www.projectswg.com * - * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * - * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * - * * - * This file is part of Holocore. * - * * - * -------------------------------------------------------------------------------- * - * * - * Holocore is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * Holocore is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with Holocore. If not, see . * - * * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * + * This file is part of PSWGCommon. * + * * + * --------------------------------------------------------------------------------* + * * + * PSWGCommon is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * PSWGCommon is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with PSWGCommon. If not, see . * ***********************************************************************************/ package com.projectswg.common.data; @@ -31,8 +29,8 @@ import com.projectswg.common.data.encodables.mongo.MongoData; import com.projectswg.common.data.encodables.mongo.MongoPersistable; import com.projectswg.common.encoding.Encodable; import com.projectswg.common.network.NetBuffer; +import org.jetbrains.annotations.NotNull; -import java.util.Arrays; import java.util.List; public class Badges implements Encodable, MongoPersistable { @@ -48,13 +46,13 @@ public class Badges implements Encodable, MongoPersistable { } @Override - public void decode(NetBuffer data) { - + public boolean decode(@NotNull NetBuffer data) { + return false; } @Override - public byte[] encode() { - NetBuffer buffer = NetBuffer.allocate(getLength()); + public byte @NotNull [] encode() { + NetBuffer buffer = NetBuffer.allocate(getLength()); // TODO: investigate this encoder, it looks like a list (e.g. 4-byte size then array of ints) buffer.addInt(15); // Bitmask count. MUST be 15, otherwise client will display "No Badges" diff --git a/src/main/java/com/projectswg/common/data/CRC.java b/src/main/java/com/projectswg/common/data/CRC.java index 1ca5ce2..4c2ef5b 100644 --- a/src/main/java/com/projectswg/common/data/CRC.java +++ b/src/main/java/com/projectswg/common/data/CRC.java @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -109,9 +108,10 @@ public class CRC implements Encodable, MongoPersistable { } @Override - public void decode(NetBuffer data) { + public boolean decode(NetBuffer data) { this.crc = data.getInt(); this.str = getString(crc); + return true; } @Override diff --git a/src/main/java/com/projectswg/common/data/RGB.java b/src/main/java/com/projectswg/common/data/RGB.java index 09c5b04..4de75a4 100644 --- a/src/main/java/com/projectswg/common/data/RGB.java +++ b/src/main/java/com/projectswg/common/data/RGB.java @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2023 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -56,10 +55,11 @@ public class RGB implements Encodable { } @Override - public void decode(NetBuffer data) { + public boolean decode(NetBuffer data) { r = data.getByte(); g = data.getByte(); b = data.getByte(); + return false; } @Override diff --git a/src/main/java/com/projectswg/common/data/customization/CustomizationString.kt b/src/main/java/com/projectswg/common/data/customization/CustomizationString.kt index b83659e..56c5d1c 100644 --- a/src/main/java/com/projectswg/common/data/customization/CustomizationString.kt +++ b/src/main/java/com/projectswg/common/data/customization/CustomizationString.kt @@ -91,9 +91,9 @@ class CustomizationString : Encodable, MongoPersistable { return str.toString() } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { val buffer = data.array - if (buffer.isEmpty()) return + if (buffer.isEmpty()) return true val stream = CustomizationStringInputStream(buffer) stream.read() // version - should be 0x02 val variableCount = stream.read() @@ -108,6 +108,7 @@ class CustomizationString : Encodable, MongoPersistable { } stream.read() // 0xFF stream.read() // 0x03 + return true } override fun encode(): ByteArray { diff --git a/src/main/java/com/projectswg/common/data/encodables/chat/ChatAvatar.kt b/src/main/java/com/projectswg/common/data/encodables/chat/ChatAvatar.kt index 6c6b9c4..197820b 100644 --- a/src/main/java/com/projectswg/common/data/encodables/chat/ChatAvatar.kt +++ b/src/main/java/com/projectswg/common/data/encodables/chat/ChatAvatar.kt @@ -52,10 +52,11 @@ class ChatAvatar(name: String) : Encodable { return buffer.array() } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { data.ascii // SWG data.ascii name = data.ascii.lowercase() + return true } override fun toString(): String { diff --git a/src/main/java/com/projectswg/common/data/encodables/chat/ChatRoom.kt b/src/main/java/com/projectswg/common/data/encodables/chat/ChatRoom.kt index d82f5b7..de2fc2f 100644 --- a/src/main/java/com/projectswg/common/data/encodables/chat/ChatRoom.kt +++ b/src/main/java/com/projectswg/common/data/encodables/chat/ChatRoom.kt @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -171,18 +170,19 @@ class ChatRoom : Encodable { return _banned.remove(avatar) } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { id = data.int type = data.int isModerated = data.boolean path = data.ascii - owner = data.getEncodable(ChatAvatar::class.java) - creator = data.getEncodable(ChatAvatar::class.java) + owner = data.getEncodable(ChatAvatar::class.java) ?: return false + creator = data.getEncodable(ChatAvatar::class.java) ?: return false title = data.unicode _moderators.clear() - _moderators.addAll(data.getList(ChatAvatar::class.java)) + _moderators.addAll(data.getList(ChatAvatar::class.java) ?: return false) _invited.clear() - _invited.addAll(data.getList(ChatAvatar::class.java)) + _invited.addAll(data.getList(ChatAvatar::class.java) ?: return false) + return true } override fun encode(): ByteArray { diff --git a/src/main/java/com/projectswg/common/data/encodables/gcw/GcwGroup.kt b/src/main/java/com/projectswg/common/data/encodables/gcw/GcwGroup.kt index 341773d..2a7d242 100644 --- a/src/main/java/com/projectswg/common/data/encodables/gcw/GcwGroup.kt +++ b/src/main/java/com/projectswg/common/data/encodables/gcw/GcwGroup.kt @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -29,9 +28,11 @@ package com.projectswg.common.data.encodables.gcw import com.projectswg.common.encoding.Encodable import com.projectswg.common.network.NetBuffer -class GcwGroup(private val planetName: String, private val zones: Collection) : Encodable { - override fun decode(data: NetBuffer) { - throw UnsupportedOperationException() +class GcwGroup(private var planetName: String, private var zones: Collection) : Encodable { + override fun decode(data: NetBuffer): Boolean { + planetName = data.ascii + zones = data.getList(GcwGroupZone::class.java) ?: return false + return true } override fun encode(): ByteArray { diff --git a/src/main/java/com/projectswg/common/data/encodables/gcw/GcwGroupZone.kt b/src/main/java/com/projectswg/common/data/encodables/gcw/GcwGroupZone.kt index 7cadf78..1abf334 100644 --- a/src/main/java/com/projectswg/common/data/encodables/gcw/GcwGroupZone.kt +++ b/src/main/java/com/projectswg/common/data/encodables/gcw/GcwGroupZone.kt @@ -1,36 +1,38 @@ /*********************************************************************************** - * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * - * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * - * * - * This file is part of Holocore. * - * * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * + * This file is part of PSWGCommon. * + * * * --------------------------------------------------------------------------------* - * * - * Holocore is free software: you can redistribute it and/or modify * + * * + * PSWGCommon is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * - * * - * Holocore is distributed in the hope that it will be useful, * + * * + * PSWGCommon is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Affero General Public License for more details. * - * * + * * * You should have received a copy of the GNU Affero General Public License * - * along with Holocore. If not, see //www.gnu.org/licenses/>. * - */ + * along with PSWGCommon. If not, see . * + ***********************************************************************************/ package com.projectswg.common.data.encodables.gcw import com.projectswg.common.encoding.Encodable import com.projectswg.common.network.NetBuffer -class GcwGroupZone(private val name: String, private val weight: Int) : Encodable { - override fun decode(data: NetBuffer) { +class GcwGroupZone(private var name: String, private var weight: Int) : Encodable { + override fun decode(data: NetBuffer): Boolean { + name = data.ascii + weight = data.int + return true } override fun encode(): ByteArray { diff --git a/src/main/java/com/projectswg/common/data/encodables/gcw/GcwRegion.kt b/src/main/java/com/projectswg/common/data/encodables/gcw/GcwRegion.kt index a4410e1..7a063e6 100644 --- a/src/main/java/com/projectswg/common/data/encodables/gcw/GcwRegion.kt +++ b/src/main/java/com/projectswg/common/data/encodables/gcw/GcwRegion.kt @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -29,9 +28,11 @@ package com.projectswg.common.data.encodables.gcw import com.projectswg.common.encoding.Encodable import com.projectswg.common.network.NetBuffer -class GcwRegion(private val planetName: String, private val zones: Collection) : Encodable { - override fun decode(data: NetBuffer) { - throw UnsupportedOperationException() +class GcwRegion(private var planetName: String, private var zones: Collection) : Encodable { + override fun decode(data: NetBuffer): Boolean { + planetName = data.ascii + zones = data.getList(GcwRegionZone::class.java) ?: return false + return true } override fun encode(): ByteArray { diff --git a/src/main/java/com/projectswg/common/data/encodables/gcw/GcwRegionZone.kt b/src/main/java/com/projectswg/common/data/encodables/gcw/GcwRegionZone.kt index 8419fd2..43632eb 100644 --- a/src/main/java/com/projectswg/common/data/encodables/gcw/GcwRegionZone.kt +++ b/src/main/java/com/projectswg/common/data/encodables/gcw/GcwRegionZone.kt @@ -1,36 +1,40 @@ /*********************************************************************************** - * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * - * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * - * * - * This file is part of Holocore. * - * * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * + * This file is part of PSWGCommon. * + * * * --------------------------------------------------------------------------------* - * * - * Holocore is free software: you can redistribute it and/or modify * + * * + * PSWGCommon is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * - * * - * Holocore is distributed in the hope that it will be useful, * + * * + * PSWGCommon is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Affero General Public License for more details. * - * * + * * * You should have received a copy of the GNU Affero General Public License * - * along with Holocore. If not, see //www.gnu.org/licenses/>. * - */ + * along with PSWGCommon. If not, see . * + ***********************************************************************************/ package com.projectswg.common.data.encodables.gcw import com.projectswg.common.encoding.Encodable import com.projectswg.common.network.NetBuffer -class GcwRegionZone(private val name: String, private val x: Float, private val z: Float, private val radius: Float) : Encodable { - override fun decode(data: NetBuffer) { +class GcwRegionZone(private var name: String, private var x: Float, private var z: Float, private var radius: Float) : Encodable { + override fun decode(data: NetBuffer): Boolean { + name = data.ascii + x = data.float + z = data.float + radius = data.float + return true } override fun encode(): ByteArray { diff --git a/src/main/java/com/projectswg/common/data/encodables/map/MapLocation.kt b/src/main/java/com/projectswg/common/data/encodables/map/MapLocation.kt index a0b13d3..7461624 100644 --- a/src/main/java/com/projectswg/common/data/encodables/map/MapLocation.kt +++ b/src/main/java/com/projectswg/common/data/encodables/map/MapLocation.kt @@ -1,29 +1,28 @@ /*********************************************************************************** - * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * - * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * - * * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * * This file is part of PSWGCommon. * - * * + * * * --------------------------------------------------------------------------------* - * * + * * * PSWGCommon is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * - * * + * * * PSWGCommon is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Affero General Public License for more details. * - * * + * * * You should have received a copy of the GNU Affero General Public License * - * along with PSWGCommon. If not, see //www.gnu.org/licenses/>. * - */ + * along with PSWGCommon. If not, see . * + ***********************************************************************************/ package com.projectswg.common.data.encodables.map import com.projectswg.common.encoding.CachedEncode @@ -122,7 +121,7 @@ class MapLocation() : Encodable { return cache.encode() } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { id = data.long name = data.unicode x = data.float @@ -130,12 +129,13 @@ class MapLocation() : Encodable { category = data.byte subcategory = data.byte isActive = data.boolean + return true } private fun encodeImpl(): ByteArray { val data = NetBuffer.allocate(length) data.addLong(id) - data.addUnicode(name) + data.addUnicode(name ?: "") data.addFloat(x) data.addFloat(y) data.addByte(category.toInt()) diff --git a/src/main/java/com/projectswg/common/data/encodables/oob/OutOfBandPackage.kt b/src/main/java/com/projectswg/common/data/encodables/oob/OutOfBandPackage.kt index 71e2b1f..8e5ac6d 100644 --- a/src/main/java/com/projectswg/common/data/encodables/oob/OutOfBandPackage.kt +++ b/src/main/java/com/projectswg/common/data/encodables/oob/OutOfBandPackage.kt @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -62,7 +61,7 @@ class OutOfBandPackage() : Encodable, MongoPersistable { return data.array() } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { var remaining = data.int * 2 while (remaining > 0) { val start = data.position() @@ -72,6 +71,7 @@ class OutOfBandPackage() : Encodable, MongoPersistable { data.seek(padding) remaining -= data.position() - start } + return true } override val length: Int @@ -112,6 +112,10 @@ class OutOfBandPackage() : Encodable, MongoPersistable { return } } + if (oob == null) { + Log.e("Failed to get encodable type $type") + return + } _packages.add(oob) } diff --git a/src/main/java/com/projectswg/common/data/encodables/oob/ProsePackage.kt b/src/main/java/com/projectswg/common/data/encodables/oob/ProsePackage.kt index 24106fc..0014933 100644 --- a/src/main/java/com/projectswg/common/data/encodables/oob/ProsePackage.kt +++ b/src/main/java/com/projectswg/common/data/encodables/oob/ProsePackage.kt @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -203,14 +202,15 @@ class ProsePackage() : OutOfBandData { return data.array() } - override fun decode(data: NetBuffer) { - base = data.getEncodable(StringId::class.java) - actor = data.getEncodable(Prose::class.java) - target = data.getEncodable(Prose::class.java) - other = data.getEncodable(Prose::class.java) + override fun decode(data: NetBuffer): Boolean { + base = data.getEncodable(StringId::class.java) ?: return false + actor = data.getEncodable(Prose::class.java) ?: return false + target = data.getEncodable(Prose::class.java) ?: return false + other = data.getEncodable(Prose::class.java) ?: return false di = data.int df = data.int.toFloat() grammarFlag = data.boolean + return true } override val length: Int @@ -288,10 +288,11 @@ class ProsePackage() : OutOfBandData { return data.array() } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { objectId = data.long - stringId = data.getEncodable(StringId::class.java) + stringId = data.getEncodable(StringId::class.java) ?: return false text = data.unicode + return true } override val length: Int diff --git a/src/main/java/com/projectswg/common/data/encodables/oob/StringId.kt b/src/main/java/com/projectswg/common/data/encodables/oob/StringId.kt index 3406bb2..007eba3 100644 --- a/src/main/java/com/projectswg/common/data/encodables/oob/StringId.kt +++ b/src/main/java/com/projectswg/common/data/encodables/oob/StringId.kt @@ -62,10 +62,11 @@ class StringId(file: String, key: String? = null) : OutOfBandData, MongoPersista return buffer.array() } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { file = data.ascii data.int key = data.ascii + return true } override val length: Int diff --git a/src/main/java/com/projectswg/common/data/encodables/oob/waypoint/WaypointPackage.kt b/src/main/java/com/projectswg/common/data/encodables/oob/waypoint/WaypointPackage.kt index d0089dc..a97bd09 100644 --- a/src/main/java/com/projectswg/common/data/encodables/oob/waypoint/WaypointPackage.kt +++ b/src/main/java/com/projectswg/common/data/encodables/oob/waypoint/WaypointPackage.kt @@ -1,5 +1,5 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * @@ -37,7 +37,7 @@ class WaypointPackage : OutOfBandData, MongoPersistable { var position: Point3D var objectId: Long = 0 - var terrain: Terrain? = null + var terrain: Terrain = Terrain.GONE var cellId: Long = 0 var name: String? = null var color: WaypointColor? = null @@ -63,23 +63,24 @@ class WaypointPackage : OutOfBandData, MongoPersistable { data.addInt(0) data.addEncodable(position) data.addLong(cellId) - data.addInt(terrain!!.crc) - data.addUnicode(name) + data.addInt(terrain.crc) + data.addUnicode(name ?: "") data.addLong(objectId) data.addByte(color?.value ?: 0) data.addBoolean(isActive) return data.array() } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { data.int position.decode(data) cellId = data.long terrain = Terrain.getTerrainFromCrc(data.int) name = data.unicode objectId = data.long - color = WaypointColor.Companion.valueOf(data.byte.toInt()) + color = WaypointColor.valueOf(data.byte.toInt()) isActive = data.boolean + return true } override val length: Int @@ -101,7 +102,7 @@ class WaypointPackage : OutOfBandData, MongoPersistable { data.getDocument("position", position) terrain = Terrain.valueOf(data.getString("terrain", "GONE")) name = data.getString("name", "New Waypoint") - color = WaypointColor.Companion.valueOf(data.getInteger("color", WaypointColor.BLUE.value)) + color = WaypointColor.valueOf(data.getInteger("color", WaypointColor.BLUE.value)) isActive = data.getBoolean("active", true) } diff --git a/src/main/java/com/projectswg/common/data/encodables/player/Mail.kt b/src/main/java/com/projectswg/common/data/encodables/player/Mail.kt index d85bcf8..138327d 100644 --- a/src/main/java/com/projectswg/common/data/encodables/player/Mail.kt +++ b/src/main/java/com/projectswg/common/data/encodables/player/Mail.kt @@ -1,5 +1,5 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * @@ -55,10 +55,11 @@ class Mail(var sender: String, subject: String, message: String, receiverId: Lon return data.array() } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { message = data.unicode subject = data.unicode - outOfBandPackage = data.getEncodable(OutOfBandPackage::class.java) + outOfBandPackage = data.getEncodable(OutOfBandPackage::class.java) ?: return false + return true } override val length: Int diff --git a/src/main/java/com/projectswg/common/data/encodables/tangible/SkillMod.kt b/src/main/java/com/projectswg/common/data/encodables/tangible/SkillMod.kt index 3fd5331..7aa381c 100644 --- a/src/main/java/com/projectswg/common/data/encodables/tangible/SkillMod.kt +++ b/src/main/java/com/projectswg/common/data/encodables/tangible/SkillMod.kt @@ -1,29 +1,28 @@ /*********************************************************************************** - * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * - * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * - * * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * * This file is part of PSWGCommon. * - * * + * * * --------------------------------------------------------------------------------* - * * + * * * PSWGCommon is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * * published by the Free Software Foundation, either version 3 of the * * License, or (at your option) any later version. * - * * + * * * PSWGCommon is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Affero General Public License for more details. * - * * + * * * You should have received a copy of the GNU Affero General Public License * - * along with PSWGCommon. If not, see //www.gnu.org/licenses/>. * - */ + * along with PSWGCommon. If not, see . * + ***********************************************************************************/ package com.projectswg.common.data.encodables.tangible import com.projectswg.common.data.encodables.mongo.MongoData @@ -41,9 +40,10 @@ class SkillMod @JvmOverloads constructor(private var base: Int = 0, private var return data.array() } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { base = data.int modifier = data.int + return true } override val length: Int diff --git a/src/main/java/com/projectswg/common/data/location/Location.java b/src/main/java/com/projectswg/common/data/location/Location.java index 7b78454..7304c3d 100644 --- a/src/main/java/com/projectswg/common/data/location/Location.java +++ b/src/main/java/com/projectswg/common/data/location/Location.java @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -30,6 +29,7 @@ import com.projectswg.common.data.encodables.mongo.MongoData; import com.projectswg.common.data.encodables.mongo.MongoPersistable; import com.projectswg.common.encoding.Encodable; import com.projectswg.common.network.NetBuffer; +import org.jetbrains.annotations.NotNull; public class Location implements Encodable, MongoPersistable { @@ -201,7 +201,7 @@ public class Location implements Encodable, MongoPersistable { } @Override - public byte[] encode() { + public byte @NotNull [] encode() { NetBuffer buf = NetBuffer.allocate(28); buf.addFloat((float) orientation.getX()); buf.addFloat((float) orientation.getY()); @@ -214,9 +214,8 @@ public class Location implements Encodable, MongoPersistable { } @Override - public void decode(NetBuffer data) { - orientation.decode(data); - point.decode(data); + public boolean decode(@NotNull NetBuffer data) { + return orientation.decode(data) && point.decode(data); } @Override diff --git a/src/main/java/com/projectswg/common/data/location/Point3D.java b/src/main/java/com/projectswg/common/data/location/Point3D.java index a7da292..443e332 100644 --- a/src/main/java/com/projectswg/common/data/location/Point3D.java +++ b/src/main/java/com/projectswg/common/data/location/Point3D.java @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -178,10 +177,11 @@ public class Point3D implements Encodable, MongoPersistable { } @Override - public void decode(NetBuffer data) { + public boolean decode(NetBuffer data) { x = data.getFloat(); y = data.getFloat(); z = data.getFloat(); + return true; } @Override diff --git a/src/main/java/com/projectswg/common/data/location/Quaternion.java b/src/main/java/com/projectswg/common/data/location/Quaternion.java index 8787b64..ec7c0fa 100644 --- a/src/main/java/com/projectswg/common/data/location/Quaternion.java +++ b/src/main/java/com/projectswg/common/data/location/Quaternion.java @@ -215,12 +215,13 @@ public class Quaternion implements Encodable, MongoPersistable { } @Override - public void decode(NetBuffer data) { + public boolean decode(NetBuffer data) { x = data.getFloat(); y = data.getFloat(); z = data.getFloat(); w = data.getFloat(); updateRotationMatrix(); + return true; } @Override diff --git a/src/main/java/com/projectswg/common/data/radial/RadialOptionList.java b/src/main/java/com/projectswg/common/data/radial/RadialOptionList.java index 1cb5c24..f803389 100644 --- a/src/main/java/com/projectswg/common/data/radial/RadialOptionList.java +++ b/src/main/java/com/projectswg/common/data/radial/RadialOptionList.java @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -35,6 +34,7 @@ import java.util.Map; import me.joshlarson.jlcommon.log.Log; import com.projectswg.common.encoding.Encodable; import com.projectswg.common.network.NetBuffer; +import org.jetbrains.annotations.NotNull; public class RadialOptionList implements Encodable { @@ -63,7 +63,7 @@ public class RadialOptionList implements Encodable { } @Override - public void decode(NetBuffer data) { + public boolean decode(NetBuffer data) { int optionsCount = data.getInt(); Map optionMap = new HashMap<>(); for (int i = 0; i < optionsCount; i++) { @@ -92,10 +92,11 @@ public class RadialOptionList implements Encodable { } } } + return true; } @Override - public byte [] encode() { + public byte @NotNull [] encode() { NetBuffer data = NetBuffer.allocate(4 + getOptionSize()); data.addInt(getOptionCount()); addOptions(data); diff --git a/src/main/java/com/projectswg/common/data/schematic/DraftSlotDataOption.java b/src/main/java/com/projectswg/common/data/schematic/DraftSlotDataOption.java index 91f983f..12a7fdc 100644 --- a/src/main/java/com/projectswg/common/data/schematic/DraftSlotDataOption.java +++ b/src/main/java/com/projectswg/common/data/schematic/DraftSlotDataOption.java @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -29,6 +28,7 @@ package com.projectswg.common.data.schematic; import com.projectswg.common.data.encodables.oob.StringId; import com.projectswg.common.encoding.Encodable; import com.projectswg.common.network.NetBuffer; +import org.jetbrains.annotations.NotNull; public class DraftSlotDataOption implements Encodable { @@ -68,15 +68,16 @@ public class DraftSlotDataOption implements Encodable { } @Override - public void decode(NetBuffer data) { + public boolean decode(NetBuffer data) { stfName = data.getEncodable(StringId.class); ingredientName = data.getUnicode(); slotType = SlotType.IDENTICAL.getSlotType(data.getByte()); - amount = data.getInt(); + amount = data.getInt(); + return false; } @Override - public byte[] encode() { + public byte @NotNull [] encode() { NetBuffer data = NetBuffer.allocate(getLength()); data.addEncodable(stfName); data.addUnicode(ingredientName); diff --git a/src/main/java/com/projectswg/common/data/schematic/IngridientSlot.java b/src/main/java/com/projectswg/common/data/schematic/IngridientSlot.java index e2cfba6..832b43f 100644 --- a/src/main/java/com/projectswg/common/data/schematic/IngridientSlot.java +++ b/src/main/java/com/projectswg/common/data/schematic/IngridientSlot.java @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -73,11 +72,15 @@ public class IngridientSlot implements Encodable{ } @Override - public void decode(NetBuffer data) { + public boolean decode(NetBuffer data) { name = data.getEncodable(StringId.class); optional = data.getBoolean(); slotOptions.clear(); - slotOptions.addAll(data.getList(DraftSlotDataOption.class)); + var draftSlotOptions = data.getList(DraftSlotDataOption.class); + if (draftSlotOptions == null) + return false; + slotOptions.addAll(draftSlotOptions); + return true; } @Override diff --git a/src/main/java/com/projectswg/common/data/sui/SuiBaseWindow.kt b/src/main/java/com/projectswg/common/data/sui/SuiBaseWindow.kt index feeea3d..61dda6d 100644 --- a/src/main/java/com/projectswg/common/data/sui/SuiBaseWindow.kt +++ b/src/main/java/com/projectswg/common/data/sui/SuiBaseWindow.kt @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -212,7 +211,7 @@ open class SuiBaseWindow : Encodable { override fun encode(): ByteArray { val data = NetBuffer.allocate(length) data.addInt(id) - data.addAscii(suiScript) + data.addAscii(suiScript ?: "") data.addList(components) data.addLong(rangeObjId) data.addFloat(maxDistance) @@ -221,14 +220,15 @@ open class SuiBaseWindow : Encodable { return data.array() } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { id = data.int suiScript = data.ascii - components = data.getList(SuiComponent::class.java) + components = data.getList(SuiComponent::class.java) ?: return false rangeObjId = data.long maxDistance = data.float // unk long // unk int + return true } override val length: Int diff --git a/src/main/java/com/projectswg/common/data/sui/SuiComponent.kt b/src/main/java/com/projectswg/common/data/sui/SuiComponent.kt index ff449a8..3315404 100644 --- a/src/main/java/com/projectswg/common/data/sui/SuiComponent.kt +++ b/src/main/java/com/projectswg/common/data/sui/SuiComponent.kt @@ -1,5 +1,5 @@ /*********************************************************************************** - * Copyright (c) 2024 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * @@ -30,7 +30,6 @@ import com.projectswg.common.encoding.StringType import com.projectswg.common.network.NetBuffer import me.joshlarson.jlcommon.log.Log import java.nio.charset.StandardCharsets -import kotlin.collections.ArrayList class SuiComponent(type: Type, widget: String) : Encodable { var type: Type = type @@ -122,10 +121,11 @@ class SuiComponent(type: Type, widget: String) : Encodable { return data.array() } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { type = Type.valueOf(data.byte) - _wideParams = data.getList(StringType.UNICODE) - _narrowParams = data.getList(StringType.ASCII) + _wideParams = data.getList(StringType.UNICODE) ?: return false + _narrowParams = data.getList(StringType.ASCII) ?: return false + return true } override val length: Int diff --git a/src/main/java/com/projectswg/common/encoding/Encodable.kt b/src/main/java/com/projectswg/common/encoding/Encodable.kt index 5e24e34..ba852d0 100644 --- a/src/main/java/com/projectswg/common/encoding/Encodable.kt +++ b/src/main/java/com/projectswg/common/encoding/Encodable.kt @@ -1,9 +1,34 @@ +/*********************************************************************************** + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * + * This file is part of PSWGCommon. * + * * + * --------------------------------------------------------------------------------* + * * + * PSWGCommon is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * PSWGCommon is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with PSWGCommon. If not, see . * + ***********************************************************************************/ package com.projectswg.common.encoding import com.projectswg.common.network.NetBuffer interface Encodable { - fun decode(data: NetBuffer) + fun decode(data: NetBuffer): Boolean fun encode(): ByteArray val length: Int } \ No newline at end of file diff --git a/src/main/java/com/projectswg/common/encoding/Encoder.java b/src/main/java/com/projectswg/common/encoding/Encoder.java deleted file mode 100644 index 37b4a75..0000000 --- a/src/main/java/com/projectswg/common/encoding/Encoder.java +++ /dev/null @@ -1,125 +0,0 @@ -/*********************************************************************************** - * Copyright (c) 2023 /// Project SWG /// www.projectswg.com * - * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * - * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * - * * - * This file is part of PSWGCommon. * - * * - * --------------------------------------------------------------------------------* - * * - * PSWGCommon is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * PSWGCommon is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with PSWGCommon. If not, see . * - ***********************************************************************************/ -package com.projectswg.common.encoding; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.charset.StandardCharsets; - -import me.joshlarson.jlcommon.log.Log; - -public class Encoder { - - public static byte[] encode(Object object) { - return encode(object, StringType.UNSPECIFIED); - } - - public static byte[] encode(Object object, StringType strType) { - if (strType != StringType.UNSPECIFIED && object instanceof String) { - switch (strType) { - case ASCII -> { - return encodeAscii((String) object); - } - case UNICODE -> { - return encodeUnicode((String) object); - } - } - } else { - if (object instanceof Encodable) { - return encodeObject((Encodable) object); - } else if (object instanceof Integer) { - return encodeInteger((Integer) object); - } else if (object instanceof Long) { - return encodeLong((Long) object); - } else if (object instanceof Short) { - return encodeShort((Short) object); - } else if (object instanceof Byte) { - return encodeByte((Byte) object); - } else if (object instanceof Boolean) { - return encodeBoolean((boolean) object); - } else if (object instanceof Float || object instanceof Double) { - return encodeFloat(object); - } else if (object instanceof String) { - throw new UnsupportedOperationException("You must specify a String type!"); - } else { - Log.e("Do not know how to encode instance type " + object.getClass().getName()); - } - } - return null; - } - - public static byte[] encodeObject(Encodable encodable) { - return encodable.encode(); - } - - private static byte[] encodeFloat(Object object) { - ByteBuffer buffer = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN); - buffer.putFloat((object instanceof Float ? (Float) object : ((Double) object).floatValue())); - return buffer.array(); - } - - private static byte[] encodeByte(Byte object) { - return new byte[] {(object)}; - } - - private static byte[] encodeBoolean(boolean object) { - return encodeByte((byte) (object ? 1 : 0)); - } - - public static byte[] encodeShort(Short object) { - ByteBuffer buffer = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN); - buffer.putShort(object); - return buffer.array(); - } - - public static byte[] encodeInteger(int integer) { - ByteBuffer buffer = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN); - buffer.putInt(integer); - return buffer.array(); - } - - public static byte[] encodeLong(long l) { - ByteBuffer buffer = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN); - buffer.putLong(l); - return buffer.array(); - } - - public static byte[] encodeAscii(String string) { - ByteBuffer buffer = ByteBuffer.allocate(2 + string.length()).order(ByteOrder.LITTLE_ENDIAN); - buffer.putShort((short) string.length()); - buffer.put(string.getBytes(StandardCharsets.UTF_8)); - return buffer.array(); - } - - public static byte[] encodeUnicode(String string) { - ByteBuffer buffer = ByteBuffer.allocate(4 + (string.length() * 2)).order(ByteOrder.LITTLE_ENDIAN); - buffer.putInt(string.length()); - buffer.put(string.getBytes(StandardCharsets.UTF_16LE)); - return buffer.array(); - } - -} diff --git a/src/main/java/com/projectswg/common/encoding/Encoder.kt b/src/main/java/com/projectswg/common/encoding/Encoder.kt new file mode 100644 index 0000000..3a16886 --- /dev/null +++ b/src/main/java/com/projectswg/common/encoding/Encoder.kt @@ -0,0 +1,104 @@ +/*********************************************************************************** + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * + * This file is part of PSWGCommon. * + * * + * --------------------------------------------------------------------------------* + * * + * PSWGCommon is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * PSWGCommon is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with PSWGCommon. If not, see . * + ***********************************************************************************/ +package com.projectswg.common.encoding + +import me.joshlarson.jlcommon.log.Log +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.charset.StandardCharsets + +object Encoder { + @JvmStatic + @JvmOverloads + fun encode(`object`: Any, strType: StringType = StringType.UNSPECIFIED): ByteArray? { + return when { + strType == StringType.ASCII && `object` is String -> encodeAscii(`object`) + strType == StringType.UNICODE && `object` is String -> encodeUnicode(`object`) + `object` is Encodable -> encodeObject(`object`) + `object` is Int -> encodeInteger(`object`) + `object` is Long -> encodeLong(`object`) + `object` is Short -> encodeShort(`object`) + `object` is Byte -> encodeByte(`object`) + `object` is Boolean -> encodeBoolean(`object`) + `object` is Float || `object` is Double -> encodeFloat(`object`) + `object` is String -> throw UnsupportedOperationException("You must specify a String type!") + else -> { + Log.e("Do not know how to encode instance type " + `object`.javaClass.getName()) + null + } + } + } + + fun encodeObject(encodable: Encodable): ByteArray { + return encodable.encode() + } + + private fun encodeFloat(`object`: Any): ByteArray { + val buffer = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN) + buffer.putFloat((if (`object` is Float) `object` else (`object` as Double).toFloat())) + return buffer.array() + } + + private fun encodeByte(`object`: Byte): ByteArray { + return byteArrayOf((`object`)) + } + + private fun encodeBoolean(`object`: Boolean): ByteArray { + return encodeByte((if (`object`) 1 else 0).toByte()) + } + + fun encodeShort(`object`: Short): ByteArray { + val buffer = ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN) + buffer.putShort(`object`) + return buffer.array() + } + + fun encodeInteger(integer: Int): ByteArray { + val buffer = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN) + buffer.putInt(integer) + return buffer.array() + } + + fun encodeLong(l: Long): ByteArray { + val buffer = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN) + buffer.putLong(l) + return buffer.array() + } + + fun encodeAscii(string: String): ByteArray { + val buffer = ByteBuffer.allocate(2 + string.length).order(ByteOrder.LITTLE_ENDIAN) + buffer.putShort(string.length.toShort()) + buffer.put(string.toByteArray(StandardCharsets.UTF_8)) + return buffer.array() + } + + fun encodeUnicode(string: String): ByteArray { + val buffer = ByteBuffer.allocate(4 + (string.length * 2)).order(ByteOrder.LITTLE_ENDIAN) + buffer.putInt(string.length) + buffer.put(string.toByteArray(StandardCharsets.UTF_16LE)) + return buffer.array() + } +} diff --git a/src/main/java/com/projectswg/common/network/NetBuffer.java b/src/main/java/com/projectswg/common/network/NetBuffer.java deleted file mode 100644 index 02d4e33..0000000 --- a/src/main/java/com/projectswg/common/network/NetBuffer.java +++ /dev/null @@ -1,454 +0,0 @@ -/*********************************************************************************** - * Copyright (c) 2023 /// Project SWG /// www.projectswg.com * - * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * - * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * - * * - * This file is part of PSWGCommon. * - * * - * --------------------------------------------------------------------------------* - * * - * PSWGCommon is free software: you can redistribute it and/or modify * - * it under the terms of the GNU Affero General Public License as * - * published by the Free Software Foundation, either version 3 of the * - * License, or (at your option) any later version. * - * * - * PSWGCommon is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Affero General Public License for more details. * - * * - * You should have received a copy of the GNU Affero General Public License * - * along with PSWGCommon. If not, see . * - ***********************************************************************************/ -package com.projectswg.common.network; - -import java.lang.reflect.InvocationTargetException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import me.joshlarson.jlcommon.log.Log; -import com.projectswg.common.encoding.Encodable; -import com.projectswg.common.encoding.StringType; - - -public class NetBuffer { - - public final Charset ASCII = StandardCharsets.UTF_8; - public final Charset UNICODE = StandardCharsets.UTF_16LE; - - private final ByteBuffer data; - private final int size; - - private NetBuffer(ByteBuffer data) { - this.data = data; - this.size = data.capacity(); - } - - public static NetBuffer allocate(int size) { - return new NetBuffer(ByteBuffer.allocate(size)); - } - - public static NetBuffer allocateDirect(int size) { - return new NetBuffer(ByteBuffer.allocateDirect(size)); - } - - public static NetBuffer wrap(byte [] data) { - return new NetBuffer(ByteBuffer.wrap(data)); - } - - public static NetBuffer wrap(ByteBuffer data) { - return new NetBuffer(data); - } - - public boolean hasRemaining() { - return data.hasRemaining(); - } - - public int remaining() { - return data.remaining(); - } - - public int position() { - return data.position(); - } - - public int limit() { - return data.limit(); - } - - public int capacity() { - return data.capacity(); - } - - public void position(int position) { - data.position(position); - } - - public void seek(int relative) { - data.position(data.position()+relative); - } - - public void clear() { - data.clear(); - } - - public void flip() { - data.flip(); - } - - public void mark() { - data.mark(); - } - - public void rewind() { - data.rewind(); - } - - public void compact() { - data.compact(); - } - - public ByteBuffer getBuffer() { - return data; - } - - public void add(NetBuffer buffer) { - add(buffer.getBuffer()); - } - - public void add(ByteBuffer buffer) { - data.put(buffer); - } - - public void addBoolean(boolean b) { - data.put(b ? (byte)1 : (byte)0); - } - - public void addAscii(String s) { - addArray(s.getBytes(ASCII)); - } - - public void addUnicode(String s) { - addInt(s.length()); - data.put(s.getBytes(UNICODE)); - } - - public void addLong(long l) { - data.order(ByteOrder.LITTLE_ENDIAN).putLong(l); - } - - public void addInt(int i) { - data.order(ByteOrder.LITTLE_ENDIAN).putInt(i); - } - - public void addFloat(float f) { - data.order(ByteOrder.LITTLE_ENDIAN).putFloat(f); - } - - public void addDouble(double d) { - data.order(ByteOrder.LITTLE_ENDIAN).putDouble(d); - } - - public void addShort(int i) { - data.order(ByteOrder.LITTLE_ENDIAN).putShort((short)i); - } - - public void addNetLong(long l) { - data.order(ByteOrder.BIG_ENDIAN).putLong(l); - } - - public void addNetInt(int i) { - data.order(ByteOrder.BIG_ENDIAN).putInt(i); - } - - public void addNetShort(int i) { - data.order(ByteOrder.BIG_ENDIAN).putShort((short)i); - } - - public void addByte(int b) { - data.put((byte)b); - } - - public void addArray(byte [] b) { - addShort(b.length); - data.put(b); - } - - public void addArrayLarge(byte [] b) { - addInt(b.length); - data.put(b); - } - - public void addRawArray(byte [] b) { - data.put(b); - } - - public void addByteSizedList(Collection list) { - if (list == null) { - addByte(0); - return; - } - - addByte(list.size()); - for (Encodable encodable : list) { - addEncodable(encodable); - } - } - - public void addList(Collection list) { - if (list == null) { - addInt(0); - return; - } - - addInt(list.size()); - for (Encodable encodable : list) { - addEncodable(encodable); - } - } - - public void addList(List list, StringType type) { - addInt(list.size()); - - switch (type) { - case ASCII: - for (String s : list) { - addAscii(s); - } - break; - case UNICODE: - for (String s : list) { - addUnicode(s); - } - break; - default: - Log.e("Cannot encode StringType " + type); - break; - } - } - - public void addEncodable(Encodable e) { - data.put(e.encode()); - } - - public boolean getBoolean() { - return getByte() == 1; - } - - public String getAscii() { - return new String(getArray(), ASCII); - } - - public String getUnicode() { - return new String(getArray(getInt() * 2), UNICODE); - } - - public String getString(StringType type) { - if (type == StringType.ASCII) - return getAscii(); - if (type == StringType.UNICODE) - return getUnicode(); - throw new IllegalArgumentException("Unknown StringType: " + type); - } - - public byte getByte() { - return data.get(); - } - - public short getShort() { - return data.order(ByteOrder.LITTLE_ENDIAN).getShort(); - } - - public int getInt() { - return data.order(ByteOrder.LITTLE_ENDIAN).getInt(); - } - - public float getFloat() { - return data.getFloat(); - } - - public double getDouble() { - return data.getDouble(); - } - - public long getLong() { - return data.order(ByteOrder.LITTLE_ENDIAN).getLong(); - } - - public short getNetShort() { - return data.order(ByteOrder.BIG_ENDIAN).getShort(); - } - - public int getNetInt() { - return data.order(ByteOrder.BIG_ENDIAN).getInt(); - } - - public long getNetLong() { - return data.order(ByteOrder.BIG_ENDIAN).getLong(); - } - - public byte [] getArray() { - return getArray(getShort()); - } - - public byte [] getArrayLarge() { - return getArray(getInt()); - } - - public byte [] getArray(int size) { - byte [] bData = new byte[size]; - data.get(bData); - return bData; - } - - public int [] getIntArray() { - int [] ints = new int[getInt()]; - for (int i = 0; i < ints.length; i++) - ints[i] = getInt(); - return ints; - } - - public int [] getIntArray(int size) { - int [] ints = new int[size]; - for (int i = 0; i < ints.length; i++) - ints[i] = getInt(); - return ints; - } - - public boolean[] getBooleanArray() { - boolean[] booleans = new boolean[getInt()]; - for(int i = 0; i < booleans.length; i++) - booleans[i] = getBoolean(); - return booleans; - } - - public Object getGeneric(Class type) { - if (Encodable.class.isAssignableFrom(type)) { - Object instance = null; - try { - instance = type.getConstructor().newInstance(); - ((Encodable) instance).decode(this); - } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { - Log.e(e); - } - - return instance; - } else if (Integer.class.isAssignableFrom(type) || Integer.TYPE.isAssignableFrom(type)) - return getInt(); - else if (Long.class.isAssignableFrom(type) || Long.TYPE.isAssignableFrom(type)) - return getLong(); - else if (Float.class.isAssignableFrom(type) || Float.TYPE.isAssignableFrom(type)) - return getFloat(); - else if (StringType.ASCII.getClass().isAssignableFrom(type)) - return getAscii(); - else if (StringType.UNICODE.getClass().isAssignableFrom(type)) - return getAscii(); - return null; - } - - public List getList(Class type, int size) { - if (size < 0) { - Log.e("Read list with size less than zero!"); - return null; - } else if (size == 0) { - return new ArrayList<>(); - } - - List list = new ArrayList<>(); - - try { - for (int i = 0; i < size; i++) { - T instance = type.getConstructor().newInstance(); - instance.decode(this); - list.add(instance); - } - } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { - Log.e(e); - } - - if (size != list.size()) - Log.e("Expected list size %d but only have %d elements in the list", size, list.size()); - return list; - } - - public List getList(Class type) { - int size = getInt(); - - return getList(type, size); - } - - public List getList(StringType type) { - int size = getInt(); - - if (size < 0) { - Log.e("Read list with size less than zero!"); - return null; - } else if (size == 0) { - return new ArrayList<>(); - } - - List list = new ArrayList<>(); - - switch (type) { - case ASCII: - for (int i = 0; i < size; i++) { - list.add(getAscii()); - } - break; - case UNICODE: - for (int i = 0; i < size; i++) { - list.add(getUnicode()); - } - break; - default: - Log.e("Do not know how to read list of StringType " + type); - break; - } - - return list; - } - - public T getEncodable(Class type) { - T instance = null; - try { - instance = type.getConstructor().newInstance(); - instance.decode(this); - } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { - Log.e(e); - } - - return instance; - } - - public byte [] array() { - return data.array(); - } - - public int size() { - return size; - } - - public byte [] copyArray() { - return copyArray(0, size); - } - - public byte [] copyArray(int offset, int length) { - if (length < 0) - throw new IllegalArgumentException("Length cannot be less than 0!"); - if (offset+length > size) - throw new IllegalArgumentException("Length extends past the end of the array!"); - byte [] ret = new byte[length]; - System.arraycopy(array(), offset, ret, 0, length); - return ret; - } - -} diff --git a/src/main/java/com/projectswg/common/network/NetBuffer.kt b/src/main/java/com/projectswg/common/network/NetBuffer.kt new file mode 100644 index 0000000..2741fa3 --- /dev/null +++ b/src/main/java/com/projectswg/common/network/NetBuffer.kt @@ -0,0 +1,437 @@ +/*********************************************************************************** + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * + * This file is part of PSWGCommon. * + * * + * --------------------------------------------------------------------------------* + * * + * PSWGCommon is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * PSWGCommon is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with PSWGCommon. If not, see . * + ***********************************************************************************/ +package com.projectswg.common.network + +import com.projectswg.common.encoding.Encodable +import com.projectswg.common.encoding.StringType +import me.joshlarson.jlcommon.log.Log +import java.lang.reflect.InvocationTargetException +import java.nio.ByteBuffer +import java.nio.ByteOrder +import java.nio.charset.Charset +import java.nio.charset.StandardCharsets + +class NetBuffer private constructor(val buffer: ByteBuffer) { + val ASCII: Charset = StandardCharsets.UTF_8 + val UNICODE: Charset = StandardCharsets.UTF_16LE + + private val size: Int = buffer.capacity() + + fun hasRemaining(): Boolean { + return buffer.hasRemaining() + } + + fun remaining(): Int { + return buffer.remaining() + } + + fun position(): Int { + return buffer.position() + } + + fun limit(): Int { + return buffer.limit() + } + + fun capacity(): Int { + return buffer.capacity() + } + + fun position(position: Int) { + buffer.position(position) + } + + fun seek(relative: Int) { + buffer.position(buffer.position() + relative) + } + + fun clear() { + buffer.clear() + } + + fun flip() { + buffer.flip() + } + + fun mark() { + buffer.mark() + } + + fun rewind() { + buffer.rewind() + } + + fun compact() { + buffer.compact() + } + + fun add(buffer: NetBuffer) { + add(buffer.buffer) + } + + fun add(buffer: ByteBuffer) { + this.buffer.put(buffer) + } + + fun addBoolean(b: Boolean) { + buffer.put(if (b) 1.toByte() else 0.toByte()) + } + + fun addAscii(s: String) { + addArray(s.toByteArray(ASCII)) + } + + fun addUnicode(s: String) { + addInt(s.length) + buffer.put(s.toByteArray(UNICODE)) + } + + fun addLong(l: Long) { + buffer.order(ByteOrder.LITTLE_ENDIAN).putLong(l) + } + + fun addInt(i: Int) { + buffer.order(ByteOrder.LITTLE_ENDIAN).putInt(i) + } + + fun addFloat(f: Float) { + buffer.order(ByteOrder.LITTLE_ENDIAN).putFloat(f) + } + + fun addDouble(d: Double) { + buffer.order(ByteOrder.LITTLE_ENDIAN).putDouble(d) + } + + fun addShort(i: Int) { + buffer.order(ByteOrder.LITTLE_ENDIAN).putShort(i.toShort()) + } + + fun addNetLong(l: Long) { + buffer.order(ByteOrder.BIG_ENDIAN).putLong(l) + } + + fun addNetInt(i: Int) { + buffer.order(ByteOrder.BIG_ENDIAN).putInt(i) + } + + fun addNetShort(i: Int) { + buffer.order(ByteOrder.BIG_ENDIAN).putShort(i.toShort()) + } + + fun addByte(b: Int) { + buffer.put(b.toByte()) + } + + fun addArray(b: ByteArray) { + addShort(b.size) + buffer.put(b) + } + + fun addArrayLarge(b: ByteArray) { + addInt(b.size) + buffer.put(b) + } + + fun addRawArray(b: ByteArray) { + buffer.put(b) + } + + fun addByteSizedList(list: MutableCollection?) { + if (list == null) { + addByte(0) + return + } + + addByte(list.size) + for (encodable in list) { + addEncodable(encodable) + } + } + + fun addList(list: Collection?) { + if (list == null) { + addInt(0) + return + } + + addInt(list.size) + for (encodable in list) { + addEncodable(encodable) + } + } + + fun addList(list: Collection, type: StringType) { + addInt(list.size) + + when (type) { + StringType.ASCII -> for (s in list) { + addAscii(s) + } + + StringType.UNICODE -> for (s in list) { + addUnicode(s) + } + + else -> Log.e("Cannot encode StringType " + type) + } + } + + fun addEncodable(e: Encodable) { + buffer.put(e.encode()) + } + + val boolean: Boolean + get() = this.byte.toInt() == 1 + + val ascii: String + get() = String(this.array, ASCII) + + val unicode: String + get() = String(getArray(this.int * 2), UNICODE) + + fun getString(type: StringType?): String { + if (type == StringType.ASCII) return this.ascii + if (type == StringType.UNICODE) return this.unicode + throw IllegalArgumentException("Unknown StringType: " + type) + } + + val byte: Byte + get() = buffer.get() + + val short: Short + get() = buffer.order(ByteOrder.LITTLE_ENDIAN).getShort() + + val int: Int + get() = buffer.order(ByteOrder.LITTLE_ENDIAN).getInt() + + val float: Float + get() = buffer.getFloat() + + val double: Double + get() = buffer.getDouble() + + val long: Long + get() = buffer.order(ByteOrder.LITTLE_ENDIAN).getLong() + + val netShort: Short + get() = buffer.order(ByteOrder.BIG_ENDIAN).getShort() + + val netInt: Int + get() = buffer.order(ByteOrder.BIG_ENDIAN).getInt() + + val netLong: Long + get() = buffer.order(ByteOrder.BIG_ENDIAN).getLong() + + val array: ByteArray + get() = getArray(this.short.toInt()) + + val arrayLarge: ByteArray + get() = getArray(this.int) + + fun getArray(size: Int): ByteArray { + val bData = ByteArray(size) + buffer.get(bData) + return bData + } + + val intArray: IntArray + get() { + val ints = IntArray(this.int) + for (i in ints.indices) ints[i] = this.int + return ints + } + + fun getIntArray(size: Int): IntArray { + val ints = IntArray(size) + for (i in ints.indices) ints[i] = this.int + return ints + } + + val booleanArray: BooleanArray + get() { + val booleans = BooleanArray(this.int) + for (i in booleans.indices) booleans[i] = this.boolean + return booleans + } + + fun getGeneric(type: Class<*>): Any? { + if (Encodable::class.java.isAssignableFrom(type)) { + try { + val instance = type.getConstructor().newInstance() + if (!(instance as Encodable).decode(this)) + return null + return instance + } catch (e: NoSuchMethodException) { + Log.e(e) + } catch (e: InvocationTargetException) { + Log.e(e) + } catch (e: InstantiationException) { + Log.e(e) + } catch (e: IllegalAccessException) { + Log.e(e) + } + + return null + } + return when { + Integer::class.java.isAssignableFrom(type) || Int::class.java.isAssignableFrom(type) || Integer.TYPE.isAssignableFrom(type) -> this.int + Long::class.java.isAssignableFrom(type) || java.lang.Long.TYPE.isAssignableFrom(type) -> this.long + Float::class.java.isAssignableFrom(type) || java.lang.Float.TYPE.isAssignableFrom(type) -> this.float + StringType.ASCII.javaClass.isAssignableFrom(type) -> this.ascii + StringType.UNICODE.javaClass.isAssignableFrom(type) -> this.unicode + else -> throw IllegalArgumentException() + } + } + + fun getList(type: Class, size: Int): MutableList? { + if (size < 0) { + Log.e("Read list with size less than zero!") + return null + } else if (size == 0) { + return ArrayList() + } + + val list: MutableList = ArrayList() + try { + for (i in 0.. getList(type: Class): MutableList? { + val size = this.int + + return getList(type, size) + } + + fun getList(type: StringType): MutableList? { + val size = this.int + + if (size < 0) { + Log.e("Read list with size less than zero!") + return null + } else if (size == 0) { + return ArrayList() + } + + val list: MutableList = ArrayList() + + when (type) { + StringType.ASCII -> { + var i = 0 + while (i < size) { + list.add(this.ascii) + i++ + } + } + + StringType.UNICODE -> { + var i = 0 + while (i < size) { + list.add(this.unicode) + i++ + } + } + + else -> Log.e("Do not know how to read list of StringType $type") + } + + return list + } + + fun getEncodable(type: Class): T? { + try { + val instance = type.getConstructor().newInstance() ?: return null + if (!instance.decode(this)) + return null + return instance + } catch (e: NoSuchMethodException) { + Log.e(e) + } catch (e: InvocationTargetException) { + Log.e(e) + } catch (e: InstantiationException) { + Log.e(e) + } catch (e: IllegalAccessException) { + Log.e(e) + } + + return null + } + + fun array(): ByteArray { + return buffer.array() + } + + fun size(): Int { + return size + } + + @JvmOverloads + fun copyArray(offset: Int = 0, length: Int = size): ByteArray { + require(length >= 0) { "Length cannot be less than 0!" } + require(offset + length <= size) { "Length extends past the end of the array!" } + val ret = ByteArray(length) + System.arraycopy(array(), offset, ret, 0, length) + return ret + } + + companion object { + @JvmStatic + fun allocate(size: Int): NetBuffer { + return NetBuffer(ByteBuffer.allocate(size)) + } + + @JvmStatic + fun allocateDirect(size: Int): NetBuffer { + return NetBuffer(ByteBuffer.allocateDirect(size)) + } + + @JvmStatic + fun wrap(data: ByteArray): NetBuffer { + return NetBuffer(ByteBuffer.wrap(data)) + } + + @JvmStatic + fun wrap(data: ByteBuffer): NetBuffer { + return NetBuffer(data) + } + } +} diff --git a/src/main/java/com/projectswg/common/network/packets/swg/login/EnumerateCharacterId.java b/src/main/java/com/projectswg/common/network/packets/swg/login/EnumerateCharacterId.java index f34a69d..cec8764 100644 --- a/src/main/java/com/projectswg/common/network/packets/swg/login/EnumerateCharacterId.java +++ b/src/main/java/com/projectswg/common/network/packets/swg/login/EnumerateCharacterId.java @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -96,12 +95,13 @@ public class EnumerateCharacterId extends SWGPacket { } @Override - public void decode(NetBuffer data) { + public boolean decode(NetBuffer data) { name = data.getUnicode(); raceCrc = data.getInt(); id = data.getLong(); galaxyId = data.getInt(); type = data.getInt(); + return true; } @Override diff --git a/src/main/java/com/projectswg/common/network/packets/swg/zone/chat/ChatRoomMessage.kt b/src/main/java/com/projectswg/common/network/packets/swg/zone/chat/ChatRoomMessage.kt index a79efcc..d5ad851 100644 --- a/src/main/java/com/projectswg/common/network/packets/swg/zone/chat/ChatRoomMessage.kt +++ b/src/main/java/com/projectswg/common/network/packets/swg/zone/chat/ChatRoomMessage.kt @@ -39,10 +39,10 @@ class ChatRoomMessage( override fun decode(data: NetBuffer) { if (!super.checkDecode(data, CRC)) return - avatar = data.getEncodable(ChatAvatar::class.java) + avatar = data.getEncodable(ChatAvatar::class.java) ?: return roomId = data.int message = data.unicode - outOfBandPackage = data.getEncodable(OutOfBandPackage::class.java) + outOfBandPackage = data.getEncodable(OutOfBandPackage::class.java) ?: return } override fun encode(): NetBuffer { diff --git a/src/main/java/com/projectswg/common/network/packets/swg/zone/deltas/DeltasMessage.java b/src/main/java/com/projectswg/common/network/packets/swg/zone/deltas/DeltasMessage.java index 585d6a5..3d14878 100644 --- a/src/main/java/com/projectswg/common/network/packets/swg/zone/deltas/DeltasMessage.java +++ b/src/main/java/com/projectswg/common/network/packets/swg/zone/deltas/DeltasMessage.java @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2018 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -32,6 +31,7 @@ import com.projectswg.common.network.NetBuffer; import com.projectswg.common.network.packets.SWGPacket; import com.projectswg.common.network.packets.swg.zone.baselines.Baseline.BaselineType; import com.projectswg.common.utilities.ByteUtilities; +import org.jetbrains.annotations.NotNull; public class DeltasMessage extends SWGPacket { @@ -60,7 +60,7 @@ public class DeltasMessage extends SWGPacket { } @Override - public void decode(NetBuffer data) { + public void decode(@NotNull NetBuffer data) { if (!super.checkDecode(data, CRC)) return; objId = data.getLong(); diff --git a/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/ImageDesignChangeMessage.kt b/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/ImageDesignChangeMessage.kt index 89d8bc5..ea90dac 100644 --- a/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/ImageDesignChangeMessage.kt +++ b/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/ImageDesignChangeMessage.kt @@ -1,3 +1,28 @@ +/*********************************************************************************** + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * + * This file is part of PSWGCommon. * + * * + * --------------------------------------------------------------------------------* + * * + * PSWGCommon is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * PSWGCommon is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with PSWGCommon. If not, see . * + ***********************************************************************************/ package com.projectswg.common.network.packets.swg.zone.object_controller import com.projectswg.common.data.customization.CustomizationString @@ -55,8 +80,8 @@ class ImageDesignChangeMessage : ObjectController { faceSkillMod = data.int markingsSkillMod = data.int hairSkillMod = data.int - morphParameters = data.getList(MorphParameter::class.java) - indexParameters = data.getList(IndexParameter::class.java) + morphParameters = data.getList(MorphParameter::class.java) ?: return + indexParameters = data.getList(IndexParameter::class.java) ?: return holoemote = data.ascii } diff --git a/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/ImageDesignEndMessage.kt b/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/ImageDesignEndMessage.kt index 7d8b552..0ac86ae 100644 --- a/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/ImageDesignEndMessage.kt +++ b/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/ImageDesignEndMessage.kt @@ -1,3 +1,28 @@ +/*********************************************************************************** + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * + * This file is part of PSWGCommon. * + * * + * --------------------------------------------------------------------------------* + * * + * PSWGCommon is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * PSWGCommon is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with PSWGCommon. If not, see . * + ***********************************************************************************/ package com.projectswg.common.network.packets.swg.zone.object_controller import com.projectswg.common.data.customization.CustomizationString @@ -55,8 +80,8 @@ class ImageDesignEndMessage : ObjectController { faceSkillMod = data.int markingsSkillMod = data.int hairSkillMod = data.int - morphParameters = data.getList(MorphParameter::class.java) - indexParameters = data.getList(IndexParameter::class.java) + morphParameters = data.getList(MorphParameter::class.java) ?: return + indexParameters = data.getList(IndexParameter::class.java) ?: return holoemote = data.ascii } diff --git a/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/IndexParameter.kt b/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/IndexParameter.kt index f3ad3a4..a488038 100644 --- a/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/IndexParameter.kt +++ b/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/IndexParameter.kt @@ -1,3 +1,28 @@ +/*********************************************************************************** + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * + * This file is part of PSWGCommon. * + * * + * --------------------------------------------------------------------------------* + * * + * PSWGCommon is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * PSWGCommon is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with PSWGCommon. If not, see . * + ***********************************************************************************/ package com.projectswg.common.network.packets.swg.zone.object_controller import com.projectswg.common.encoding.Encodable @@ -8,9 +33,10 @@ class IndexParameter : Encodable { var name = "" var value = 0 - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { name = data.ascii value = data.int + return true } override fun encode(): ByteArray { diff --git a/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/MorphParameter.kt b/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/MorphParameter.kt index dbac053..c4c1f12 100644 --- a/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/MorphParameter.kt +++ b/src/main/java/com/projectswg/common/network/packets/swg/zone/object_controller/MorphParameter.kt @@ -1,3 +1,28 @@ +/*********************************************************************************** + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * + * * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * + * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * + * * + * This file is part of PSWGCommon. * + * * + * --------------------------------------------------------------------------------* + * * + * PSWGCommon is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * PSWGCommon is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with PSWGCommon. If not, see . * + ***********************************************************************************/ package com.projectswg.common.network.packets.swg.zone.object_controller import com.projectswg.common.encoding.Encodable @@ -8,9 +33,10 @@ class MorphParameter : Encodable { var name = "" var multiplier = 0f - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { name = data.ascii multiplier = data.float + return true } override fun encode(): ByteArray { diff --git a/src/main/java/com/projectswg/common/network/packets/swg/zone/spatial/AttributeList.kt b/src/main/java/com/projectswg/common/network/packets/swg/zone/spatial/AttributeList.kt index 02e989b..14a226a 100644 --- a/src/main/java/com/projectswg/common/network/packets/swg/zone/spatial/AttributeList.kt +++ b/src/main/java/com/projectswg/common/network/packets/swg/zone/spatial/AttributeList.kt @@ -1,11 +1,10 @@ /*********************************************************************************** - * Copyright (c) 2023 /// Project SWG /// www.projectswg.com * + * Copyright (c) 2025 /// Project SWG /// www.projectswg.com * * * - * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * + * ProjectSWG is an emulation project for Star Wars Galaxies founded on * * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * - * Our goal is to create an emulator which will provide a server for players to * - * continue playing a game similar to the one they used to play. We are basing * - * it on the final publish of the game prior to end-game events. * + * Our goal is to create one or more emulators which will provide servers for * + * players to continue playing a game similar to the one they used to play. * * * * This file is part of PSWGCommon. * * * @@ -30,7 +29,6 @@ import com.projectswg.common.encoding.Encodable import com.projectswg.common.network.NetBuffer import java.text.NumberFormat import java.util.* -import kotlin.collections.LinkedHashMap class AttributeList : Encodable { @@ -68,12 +66,13 @@ class AttributeList : Encodable { map[attribute] = formattedValue + suffix } - override fun decode(data: NetBuffer) { + override fun decode(data: NetBuffer): Boolean { val size = data.int for (i in 0..size) { map[data.ascii] = data.unicode } + return true } override fun encode(): ByteArray {