class Player(idd: Int, xx: Int, yy: Int) { var id = idd var x = xx var y = yy }
class Packet ( comm:Int, player: Player ) { val com = comm // val id = player.id // id val x = player.x val y = player.y }
object Protocol { // def encode( packet: Packet ): ByteBuffer = { val rez: ByteBuffer = ByteBuffer.allocate(16) rez.putInt(packet.com) rez.putInt(packet.id) rez.putInt(packet.x) rez.putInt(packet.y) rez } // def decode( buffer: ByteBuffer ): Packet = { val com = buffer.getInt(0) val idd = buffer.getInt(4) val xx = buffer.getInt(8) val yy = buffer.getInt(12) val rez: Packet = new Packet( com, new Player(idd, xx, yy) ) rez } }
object GameServer extends Runnable { var isActive = true var selector: Selector = null var numClients = 0 var port = 7778 // var sessions = new HashMap[ SocketChannel, Actor ] var lock: AnyRef = new Object() // def addPlayerMsg(player: Player) { lock.synchronized { ..... } } // def init(portt: Int) { port = portt try { selector = Selector.open println( "Selector opened" ) } catch { case e => println( "Problems during Socket Selector init: " + e ) } } override def run() { // bindSocket( "", port) // while ( isActive ) { Loop() } } def Loop() { if ( selector.select > 0 ) { val it = selector.selectedKeys().iterator() while ( it.hasNext ) { val skey = it.next it.remove() if ( !skey.isValid ) { continue() } // if ( skey.isAcceptable ) { val socket:ServerSocketChannel = skey.channel().asInstanceOf[ServerSocketChannel] try { numClients = numClients + 1 val channel = socket.accept channel.configureBlocking(false) channel.register(selector, SelectionKey.OP_READ) // val player = new Player(numClients, numClients * 20, numClients * 20) val actor = new ClientHandler(player, channel) actor.start() // val packet = new Packet( 0, player) actor.packets += packet // sessions += channel -> actor println( "Accepted connection from:" + channel.socket().getInetAddress + ":" + channel.socket().getPort ) } catch { case e: Exception => println( "Game Loop Exception: " + e.getMessage ) } } // else { val channel:SocketChannel = skey.channel.asInstanceOf[SocketChannel] val actor = sessions.get(channel).get.asInstanceOf[ClientHandler] if ( actor.packets.size > 0 ) { skey.interestOps(SelectionKey.OP_WRITE) } actor ! skey } } } } def close(remoteAddress:String, channel:SocketChannel) { channel.close(); println("Session close: " + remoteAddress); } // def bindSocket(address: String, port: Int) { try { // val hostAddr: InetAddress = null val isa = new InetSocketAddress(hostAddr, port) val serverChannel = ServerSocketChannel.open serverChannel.configureBlocking(false) serverChannel.socket.bind(isa) serverChannel.socket.setReuseAddress(true) serverChannel.register(selector, SelectionKey.OP_ACCEPT ) println( "Listening game on port: " + port ) } catch { case e: IOException => println("Could not listen on port: " + port + ".") System.exit(-1) case e => println("Unknown error " + e) System.exit(-1) } } }
class ClientHandler(player: Player, chanel:SocketChannel) extends Actor { val player_id = player.id val channel = chanel val remoteAddress = channel.socket().getRemoteSocketAddress.toString var packets = new HashSet[ Packet ] def act() { loop { receive { // case key: SelectionKey => { try { // if (key.isReadable) { val buffer = ByteBuffer.allocate(16) channel.read(buffer) match { case -1 => close(remoteAddress, channel) case 0 => case x => processMessageRead(key, buffer) } } // else if (key.isWritable) { packets.synchronized { for(packet <- packets) { processMessageWrite( Protocol.encode(packet) ) packets.remove(packet) } } if(packets.isEmpty) key.interestOps(SelectionKey.OP_READ) } } catch { case e: SocketException => println("ClientHandler SocketException error " + e.getMessage) case e: IOException => println("ClientHandler IOException error " + e.getMessage) case e => println("ClientHandler Unknown error " + e.getMessage) } } } } } // def processMessageRead(key: SelectionKey, buffer: ByteBuffer) { if ( buffer.limit() == 0 ) { return } buffer.flip val protocol = Protocol.decode( buffer ) println( "Client : " + player.id + " - " + new Date + " - " + "com:" + protocol.com + " x:" + protocol.x + " y:" + protocol.y ) player.x = protocol.x player.y = protocol.y buffer.clear if (protocol.com == 0) { key.interestOps(SelectionKey.OP_WRITE) } else if (protocol.com == 1) { GameServer.addPlayerMsg(player) } } // def processMessageWrite(buffer: ByteBuffer) { if ( buffer.limit() == 0 ) { return } buffer.flip channel.write(buffer) println( "Client write: " + player.id + " - " + new Date + " - " + buffer.array().mkString(":") ) buffer.clear } def close(remoteAddress: String, channel: SocketChannel) { channel.close() println("Session " + player.id + " close: " + remoteAddress) } }
public class Player extends MovieClip { public var Name:String = "Player"; public var id:int = 0; [Embed(source = '../../../../lib/tank.png')] public var _tank: Class; public var tank:Bitmap; public function Player() { width = 30; height = 30; tank = new _tank(); tank.width = 30; tank.height = 30; addChild(tank); } }
// public function sendMessage(val:int):void { if (socket.connected) { var bytes:ByteArray = new ByteArray(); bytes.writeInt(val); bytes.writeInt(player.id); bytes.writeInt(player.x); bytes.writeInt(player.y); socket.writeBytes( bytes, 0, 16); socket.flush(); } } // private function dataHandler(e:ProgressEvent):void { var bytes:ByteArray = new ByteArray(); socket.readBytes(bytes, 0, 16); var com:int = bytes.readInt(); var id:int = bytes.readInt(); var x:int = bytes.readInt(); var y:int = bytes.readInt(); switch (com) { // case 0: … // case 1: ... } }
Source: https://habr.com/ru/post/124311/
All Articles