diff --git a/client/src/main/kotlin/org/hso/texturesyncclient/controller/net/Connection.kt b/client/src/main/kotlin/org/hso/texturesyncclient/controller/net/Connection.kt index c646f55..4b878a7 100644 --- a/client/src/main/kotlin/org/hso/texturesyncclient/controller/net/Connection.kt +++ b/client/src/main/kotlin/org/hso/texturesyncclient/controller/net/Connection.kt @@ -5,6 +5,7 @@ import javafx.scene.image.Image import org.hso.texturesyncclient.model.Sha256 import org.hso.texturesyncclient.model.Texture import java.io.* +import java.lang.IllegalArgumentException import java.lang.RuntimeException import java.net.* import java.util.* @@ -214,17 +215,102 @@ class Connection(val address: InetAddress, val port: Int = 10796) : Closeable { } } + @Throws(IOException::class, ConnectionException::class, IllegalArgumentException::class) + @Synchronized + private fun replaceTexture(old: Texture?, new : Texture?, image : ByteArray? ) { + val io = getStreams() + + val obj = JsonObject() + obj.add("replace_texture", { + val inner = JsonObject() + if(old != null) { + inner.add("old", Gson().toJsonTree(InternalTexture(old), InternalTexture::class.java)) + } else { + inner.add("old", null) + } + if(new != null) { + inner.add("new", Gson().toJsonTree(InternalTexture(new), InternalTexture::class.java)) + } else { + inner.add("new", null) + } + inner + }()) + + JsonPackage(obj).write(io.second) + + when (val pkg = Package.read(io.first)) { + is JsonPackage -> { + if (pkg.content == JsonPrimitive(true)) { + // everthing is fine! + return + } else if (image != null) { + // should be { "get_texture_file": { texture_hash : }} + // we don't check, since there is no good way to handle it. + + BinaryPackage(image).write(io.second) + when (val ipkg = Package.read(io.first)) { + is JsonPackage -> { + if(ipkg.content != JsonPrimitive(true)) { + // Protokoll Assertion failed + throw ConnectionUnexpecedPacketException() + } + } + is BinaryPackage -> throw ConnectionUnexpecedPacketException() + is ErrorPackage -> throw ConnectionErrorException(ipkg) + else -> throw RuntimeException("Unreachable") + } + } else { + ErrorPackage(404, "Texture not found!").write(io.second) + close() // gets re-opened on next request. + throw IllegalArgumentException("Image Argument was needed.") + } + } + is BinaryPackage -> throw ConnectionUnexpecedPacketException() + is ErrorPackage -> throw ConnectionErrorException(pkg) + else -> throw RuntimeException("Unreachable") + } + } + + @Throws(IOException::class, ConnectionException::class, IllegalArgumentException::class) + @Synchronized + fun uploadTexture(texture: Texture, image : ByteArray ) { + if(texture.textureHash != Sha256(image)) { + throw IllegalArgumentException("Sha256 of Image does not Match with Texture.") + } + + replaceTexture(null, texture, image) + } + + @Throws(IOException::class, ConnectionException::class, IllegalArgumentException::class) + @Synchronized + fun updateTexture(old: Texture, new : Texture, image : ByteArray ) { + if(new.textureHash != Sha256(image)) { + throw IllegalArgumentException("Sha256 of Image does not Match with Texture.") + } + + replaceTexture(old, new, image) + } + + @Throws(IOException::class, ConnectionException::class, IllegalArgumentException::class) + @Synchronized + fun deleteTexture(texture : Texture) { + replaceTexture(texture, null , null) + } + @Throws(IOException::class) @Synchronized override fun close() { if (output != null) { output!!.close() + output = null } if (input != null) { input!!.close() + input = null } if (socket != null) { socket!!.close() + socket = null } } diff --git a/client/src/main/kotlin/org/hso/texturesyncclient/model/DataModel.kt b/client/src/main/kotlin/org/hso/texturesyncclient/model/DataModel.kt index a8036dc..588006d 100644 --- a/client/src/main/kotlin/org/hso/texturesyncclient/model/DataModel.kt +++ b/client/src/main/kotlin/org/hso/texturesyncclient/model/DataModel.kt @@ -56,4 +56,19 @@ class Sha256 { } return s.toString() } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as Sha256 + + if (!hashBytes.contentEquals(other.hashBytes)) return false + + return true + } + + override fun hashCode(): Int { + return hashBytes.contentHashCode() + } } \ No newline at end of file