<commit_before>package com.catikkas.aiorserver

import java.net.InetSocketAddress

import akka.actor._
import akka.event.LoggingReceive
import akka.io._
import akka.io.Udp._

@SuppressWarnings(Array("org.wartremover.warts.Var"))
class Server extends Actor with ActorLogging with Config {
  var robot = context.system.deadLetters

  override def preStart(): Unit = {
    import context.system
    IO(Udp) ! Bind(self, new InetSocketAddress(config.port))
    robot = context.actorOf(Robot.props, "robot")
  }

  def receive = notBound

  def notBound = LoggingReceive.withLabel("notBound") {
    case CommandFailed(_) =>
      log.error("failed to bind")
      context stop self

    case Bound(local) =>
      log.info("server started on {}", local.getPort)
      val socket = sender
      context become bound(socket)
  }

  import Messages._
  import Messages.AiocId._
  import Robot._

  def bound(socket: ActorRef) = LoggingReceive.withLabel("bound") {
    case Received(Aioc(ConnectionReceived), remote) =>
      log.info("connection attempt from {}", remote)
      socket ! Send(UdpConnectionAccepted.toJson, new InetSocketAddress(remote.getAddress, config.port))
      context become connected(remote)
  }

  def connected(remote: InetSocketAddress) = LoggingReceive.withLabel(s"connected $remote") {
    case Received(MouseMove(x, y), `remote`)         => robot ! MouseMoveDelta(x, y)
    case Received(Aioc(MouseLeftPress), `remote`)    => robot ! MousePress(MouseButton.Left)
    case Received(Aioc(MouseLeftRelease), `remote`)  => robot ! MouseRelease(MouseButton.Left)
    case Received(Aioc(MouseRightPress), `remote`)   => robot ! MousePress(MouseButton.Right)
    case Received(Aioc(MouseRightRelease), `remote`) => robot ! MouseRelease(MouseButton.Right)
    case Received(Aioc(MouseWheelDown), `remote`)    => robot ! MouseWheel(WheelDirection.Down)
    case Received(Aioc(MouseWheelUp), `remote`)      => robot ! MouseWheel(WheelDirection.Up)
    case Received(KeyboardString(chars), `remote`)   => robot ! PressKeys(chars)
    case Received(KeyboardInt(int), `remote`)        => robot ! PressKey(int)
    case Received(m, r)                              => log.debug("received unhandled {} from {}", m.utf8String, r)
  }
}

object Server {
  def props = Props(new Server)
}<commit_msg>Server should drop existing client when it receives a new connection.<commit_after>package com.catikkas.aiorserver

import java.net.InetSocketAddress

import akka.actor._
import akka.event.LoggingReceive
import akka.io._
import akka.io.Udp._

@SuppressWarnings(Array("org.wartremover.warts.Var"))
class Server extends Actor with ActorLogging with Config {
  var robot = context.system.deadLetters

  override def preStart(): Unit = {
    import context.system
    IO(Udp) ! Bind(self, new InetSocketAddress(config.port))
    robot = context.actorOf(Robot.props, "robot")
  }

  def receive: Receive = notBound

  def notBound: Receive = LoggingReceive.withLabel("notBound") {
    case CommandFailed(_) =>
      log.error("failed to bind")
      context stop self

    case Bound(local) =>
      log.info("server started on {}", local.getPort)
      val socket = sender
      context become bound(socket)
  }

  import Messages._
  import Messages.AiocId._
  import Robot._

  def bound(socket: ActorRef): Receive = LoggingReceive.withLabel("bound") {
    case Received(Aioc(ConnectionReceived), remote) =>
      log.info("connection attempt from {}", remote)
      socket ! Send(UdpConnectionAccepted.toJson, new InetSocketAddress(remote.getAddress, config.port))
      context become connected(socket, remote)
  }

  def connected(socket: ActorRef, remote: InetSocketAddress): Receive = LoggingReceive.withLabel(s"connected $remote") {
    case c @ Received(Aioc(ConnectionReceived), _) =>
      // Pretty much drop existing connected client and accept requests only from new client
      context become bound(socket)
      self forward c

    case Received(MouseMove(x, y), `remote`)         => robot ! MouseMoveDelta(x, y)
    case Received(Aioc(MouseLeftPress), `remote`)    => robot ! MousePress(MouseButton.Left)
    case Received(Aioc(MouseLeftRelease), `remote`)  => robot ! MouseRelease(MouseButton.Left)
    case Received(Aioc(MouseRightPress), `remote`)   => robot ! MousePress(MouseButton.Right)
    case Received(Aioc(MouseRightRelease), `remote`) => robot ! MouseRelease(MouseButton.Right)
    case Received(Aioc(MouseWheelDown), `remote`)    => robot ! MouseWheel(WheelDirection.Down)
    case Received(Aioc(MouseWheelUp), `remote`)      => robot ! MouseWheel(WheelDirection.Up)
    case Received(KeyboardString(chars), `remote`)   => robot ! PressKeys(chars)
    case Received(KeyboardInt(int), `remote`)        => robot ! PressKey(int)
    case Received(m, r)                              => log.debug("received unhandled {} from {}", m.utf8String, r)
  }
}

object Server {
  def props = Props(new Server)
}
{'fraction_non_alphanumeric': 0.11810064935064934, 'fraction_numerical': 0.00040584415584415587, 'mean_word_length': 4.009146341463414, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1365459', 'n_tokens_mistral': 1496, 'n_tokens_neox': 1493, 'n_words': 347}