diff --git a/proto/protofiles_sources/compile_proto.sh b/proto/protofiles_sources/compile_proto.sh
index f39ad34ab71..d6fa2ceb41c 100755
--- a/proto/protofiles_sources/compile_proto.sh
+++ b/proto/protofiles_sources/compile_proto.sh
@@ -1,5 +1,6 @@
#!/bin/bash
-parent_path=$( cd "$(dirname "${BASH_SOURCE}")" ; pwd -P )
-cd "$parent_path"
+PROTOC="../compiler/build/protoc"
+cd "$(dirname "${BASH_SOURCE}")"
mkdir out -p
-../compiler/build/protoc --kotlin_out="./out/" --proto_path="./server_car" ./server_car/*.proto
+${PROTOC} --kotlin_out="./out/" --proto_path="./server_car" ./server_car/*.proto
+${PROTOC} --kotlin_out="./out/" --proto_path="./server_client" ./server_client/*.proto
diff --git a/proto/protofiles_sources/server_client/cars.proto b/proto/protofiles_sources/server_client/cars.proto
deleted file mode 100644
index a64d281e290..00000000000
--- a/proto/protofiles_sources/server_client/cars.proto
+++ /dev/null
@@ -1,8 +0,0 @@
-package carkot;
-
-option java_package = "client";
-option java_out_classname = "Car";
-
-message car {
- repeated string ids = 1;
-}
diff --git a/proto/protofiles_sources/server_client/direction.proto b/proto/protofiles_sources/server_client/direction.proto
index de8567822b2..0debe83e1e6 100644
--- a/proto/protofiles_sources/server_client/direction.proto
+++ b/proto/protofiles_sources/server_client/direction.proto
@@ -11,8 +11,5 @@ message DirectionRequest {
}
Command command = 1;
int32 sid = 2;
-}
-
-message DirectionResponse {
- int32 code = 1;
-}
+ bool stop = 3;
+}
\ No newline at end of file
diff --git a/server/.idea/modules/server.iml b/server/.idea/modules/server.iml
index 8b292b004de..94a5e3f4ba6 100644
--- a/server/.idea/modules/server.iml
+++ b/server/.idea/modules/server.iml
@@ -20,8 +20,6 @@
-
-
@@ -31,5 +29,7 @@
+
+
\ No newline at end of file
diff --git a/server/src/main/java/algorithm/RoomModel.kt b/server/src/main/java/algorithm/RoomModel.kt
index b1af7a177e8..7364e18e8a3 100644
--- a/server/src/main/java/algorithm/RoomModel.kt
+++ b/server/src/main/java/algorithm/RoomModel.kt
@@ -1,5 +1,5 @@
package algorithm
-
+import Waypoints
/**
* Created by user on 8/23/16.
*/
@@ -7,4 +7,34 @@ object RoomModel {
val point = arrayListOf>()
+
+// DEBUG BELOW
+ val rng = java.util.Random(42)
+ var iter = 0
+ var currentPosition_x = 0
+ var currentPosition_y = 0
+ fun getUpdate(): Waypoints {
+ if (iter == 5) {
+ web.server.Server.changeMode(web.server.Server.ServerMode.IDLE)
+ return Waypoints.BuilderWaypoints(IntArray(0), IntArray(0), IntArray(0), IntArray(0), true).build()
+ }
+
+ val begin_x = IntArray(10)
+ val begin_y = IntArray(10)
+ val end_x = IntArray(10)
+ val end_y = IntArray(10)
+
+ for (i in 0..9) {
+ begin_x[i] = currentPosition_x
+ begin_y[i] = currentPosition_y
+
+ currentPosition_x += rng.nextInt(3)
+ currentPosition_y += rng.nextInt(3)
+
+ end_x[i] = currentPosition_x
+ end_y[i] = currentPosition_y
+ }
+ iter++
+ return Waypoints.BuilderWaypoints(begin_x, begin_y, end_x, end_y, false).build()
+ }
}
\ No newline at end of file
diff --git a/server/src/main/java/car/client/ClientHandler.kt b/server/src/main/java/car/client/ClientHandler.kt
index c7b0f8ed7db..576482e26eb 100644
--- a/server/src/main/java/car/client/ClientHandler.kt
+++ b/server/src/main/java/car/client/ClientHandler.kt
@@ -98,6 +98,7 @@ class ClientHandler : SimpleChannelInboundHandler {
override fun channelRead0(ctx: ChannelHandlerContext?, msg: Any?) {
if (msg is DefaultHttpContent) {
+ // TODO: refactor variable names. It's hard as hell to read code with "contentBytes" and "content(!)s(!)Bytes" in lines of code.
val contentsBytes = msg.content()
contentBytes = ByteArray(contentsBytes.capacity())
contentsBytes.readBytes(contentBytes)
diff --git a/server/src/main/java/web/server/Handler.kt b/server/src/main/java/web/server/Handler.kt
index e76ff595a26..a334a0f4a76 100644
--- a/server/src/main/java/web/server/Handler.kt
+++ b/server/src/main/java/web/server/Handler.kt
@@ -5,26 +5,117 @@ import io.netty.channel.ChannelHandlerContext
import io.netty.channel.SimpleChannelInboundHandler
import io.netty.handler.codec.http.*
import io.netty.util.CharsetUtil
+import GenericResponse
+import CodedOutputStream
+import CodedInputStream
+import java.util.*
class Handler : SimpleChannelInboundHandler() {
var contentBytes: ByteArray = ByteArray(0)
+ var url: String? = null
+ var method: HttpMethod? = null
override fun channelReadComplete(ctx: ChannelHandlerContext) {
+ when (url) {
+ Constants.changeModeURL -> {
+ if (Server.serverMode != Server.ServerMode.IDLE && Server.serverMode != Server.ServerMode.MANUAL_MODE) {
+ throw IllegalStateException("Can't change server mode in algorithm execution mode!")
+ }
- val response = DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.copiedBuffer("" + Math.random() * 10000, CharsetUtil.UTF_8))
- response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes())
- ctx.writeAndFlush(response).addListener(io.netty.channel.ChannelFutureListener.CLOSE)
- }
+ // Parse mode change request
+ val ins = CodedInputStream(Base64.getDecoder().decode(contentBytes))
+ val request = ModeChange.BuilderModeChange(ModeChange.Mode.ManualControl).parseFrom(ins)
- override fun channelRead0(ctx: ChannelHandlerContext, msg: Any) {
- if (msg is DefaultHttpContent) {
- val contentsBytes = msg.content()
- contentBytes = ByteArray(contentsBytes.capacity())
- contentsBytes.readBytes(contentBytes)
+ // Change server mode
+ Server.changeMode(Server.ServerMode.fromProtoMode(request.newMode))
+
+ // Respond with "OK"-protobuf
+ val protoResponse = GenericResponse.BuilderGenericResponse(Result.BuilderResult(0).build())
+ val outs = CodedOutputStream(ByteArray(protoResponse.getSizeNoTag()))
+ protoResponse.writeTo(outs)
+ val response = DefaultFullHttpResponse(
+ HttpVersion.HTTP_1_1,
+ HttpResponseStatus.OK,
+ Unpooled.copiedBuffer(Base64.getEncoder().encodeToString(outs.buffer), CharsetUtil.UTF_8)
+ )
+ response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes())
+ response.headers().add("Access-Control-Allow-Origin", "*");
+ response.headers().add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
+ response.headers().add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Content-Length");
+ ctx.writeAndFlush(response).addListener(io.netty.channel.ChannelFutureListener.CLOSE)
+ }
+ Constants.getWaypointsURL -> {
+ if (Server.serverMode != Server.ServerMode.PERIMETER_BUILDING) {
+ throw IllegalStateException("Can't get waypoints when in not Permiter Building mode")
+ }
+
+ // Build update for UI
+ val msg = RoomModel.getUpdate()
+ val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag()))
+ msg.writeTo(outs)
+ val response = DefaultFullHttpResponse(
+ HttpVersion.HTTP_1_1,
+ HttpResponseStatus.OK,
+ Unpooled.copiedBuffer(Base64.getEncoder().encodeToString(outs.buffer), CharsetUtil.UTF_8)
+ )
+ response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes())
+ response.headers().add("Access-Control-Allow-Origin", "*");
+ response.headers().add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
+ response.headers().add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Content-Length");
+ ctx.writeAndFlush(response).addListener(io.netty.channel.ChannelFutureListener.CLOSE)
+ }
+ Constants.directionOrderURL -> {
+ if (Server.serverMode != Server.ServerMode.MANUAL_MODE) {
+ throw IllegalStateException("Can't execute move order when not in manual mode")
+ }
+
+ // Parse direction order
+ val ins = CodedInputStream(contentBytes)
+ val order = DirectionRequest.BuilderDirectionRequest(DirectionRequest.Command.FORWARD, 0, false).parseFrom(ins)
+ if (order.stop) {
+ web.server.Server.changeMode(Server.ServerMode.IDLE)
+ return
+ }
+
+ sendCarOrder(order.command)
+
+ // TODO: should be done as callback after sending car order
+ // Send update back
+ val msg = RoomModel.getUpdate()
+ val outs = CodedOutputStream(ByteArray(msg.getSizeNoTag()))
+ msg.writeTo(outs)
+ val response = DefaultFullHttpResponse(
+ HttpVersion.HTTP_1_1,
+ HttpResponseStatus.OK,
+ Unpooled.copiedBuffer(Base64.getEncoder().encodeToString(outs.buffer), CharsetUtil.UTF_8)
+ )
+ response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes())
+ response.headers().add("Access-Control-Allow-Origin", "*");
+ response.headers().add("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
+ response.headers().add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Content-Length");
+ ctx.writeAndFlush(response).addListener(io.netty.channel.ChannelFutureListener.CLOSE)
+ }
}
}
+ // TODO: stub!!
+ fun sendCarOrder(cmd: DirectionRequest.Command) {
+ println("Sent order ${cmd.toString()}")
+ }
+
+ override fun channelRead0(ctx: ChannelHandlerContext, msg: Any) {
+ if (msg is HttpRequest) {
+ url = msg.uri()
+ method = msg.method()
+ }
+
+ if (msg is DefaultHttpContent) {
+ val contentBuffer = msg.content()
+ contentBytes = ByteArray(contentBuffer.capacity())
+ contentBuffer.readBytes(contentBytes)
+ }
+ }
override fun exceptionCaught(ctx: ChannelHandlerContext?, cause: Throwable?) {
println("exception")
diff --git a/server/src/main/java/web/server/Server.kt b/server/src/main/java/web/server/Server.kt
index 00e2b665036..767d89626f5 100644
--- a/server/src/main/java/web/server/Server.kt
+++ b/server/src/main/java/web/server/Server.kt
@@ -6,7 +6,30 @@ import io.netty.channel.socket.nio.NioServerSocketChannel
import kotlin.concurrent.thread
object Server {
+ enum class ServerMode {
+ IDLE,
+ MANUAL_MODE,
+ PERIMETER_BUILDING;
+
+ companion object {
+ fun fromProtoMode(mode: ModeChange.Mode): ServerMode {
+ return when (mode) {
+ ModeChange.Mode.ManualControl -> MANUAL_MODE
+ ModeChange.Mode.PerimeterBuilding -> PERIMETER_BUILDING
+ else -> throw IllegalArgumentException("Illegal argument when parsing ServerMode from Protobuf Mode")
+ }
+ }
+ }
+ }
+
private val handlerThreadsCount: Int = 10
+ var serverMode = ServerMode.IDLE
+
+ fun changeMode(newMode: ServerMode) {
+ println("Changing mode from ${serverMode.toString()} to ${newMode.toString()}")
+ serverMode = newMode
+ }
+
fun getWebServerThread(webServerPort: Int): Thread {
return thread(false, false, null, "webServer", -1, {
println("web server started")