diff --git a/src/main/java/com/projectswg/common/data/swgfile/ClientStringParser.kt b/src/main/java/com/projectswg/common/data/swgfile/ClientStringParser.kt new file mode 100644 index 0000000..a073f12 --- /dev/null +++ b/src/main/java/com/projectswg/common/data/swgfile/ClientStringParser.kt @@ -0,0 +1,81 @@ +/*********************************************************************************** + * Copyright (c) 2024 /// 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.swgfile + +import com.projectswg.common.data.encodables.oob.StringId +import com.projectswg.common.network.NetBuffer +import me.joshlarson.jlcommon.log.Log +import java.io.File +import java.nio.channels.FileChannel + +class ClientStringParser private constructor(private val buffer: NetBuffer, private val swgFileName: String) { + + val strings = HashMap() + + private fun parseVersion0() { + assert(false) // No .stf's I'm aware of use this version + } + + private fun parseVersion1() { + buffer.int // nextUniqueId + val entryCount = buffer.int + val values = HashMap(entryCount) + for (i in 0 until entryCount) { + val id = buffer.int + buffer.int // source CRC used to generate the string--unused for us + values[id] = buffer.unicode + } + for (i in 0 until entryCount) { + val id = buffer.int + val key = String(buffer.arrayLarge, Charsets.US_ASCII) + if (!values.contains(id)) + Log.w("Unknown string value for key: %d (key text: %s)", id, key) + strings[StringId(swgFileName, key)] = values[id] ?: continue + } + } + + companion object { + + fun parse(filepath: File, swgFileName: String): ClientStringParser { + FileChannel.open(filepath.toPath()).use { channel -> + val buffer = NetBuffer.wrap(channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size())) + val magic = buffer.int + val version = buffer.byte.toInt() + check(magic == 0xABCD) { "invalid magic bytes at start of file" } + + val parser = ClientStringParser(buffer, swgFileName) + when (version) { + 0 -> parser.parseVersion0() + 1 -> parser.parseVersion1() + else -> error("invalid version $version") + } + return parser + } + } + + } + +}