Added MSG command (broadcast) to pixelwar

This commit is contained in:
Marcel Hellkamp 2015-02-09 18:35:08 +01:00
parent 2bb13b0685
commit ad19b4ffb3
3 changed files with 80 additions and 28 deletions

View file

@ -1,6 +1,7 @@
package de.paws.pixelwar; package de.paws.pixelwar;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
import java.awt.Canvas;
import java.awt.Color; import java.awt.Color;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -13,7 +14,7 @@ import java.awt.image.BufferedImage;
import javax.swing.JFrame; import javax.swing.JFrame;
public class Canvas { public class NetCanvas {
private volatile BufferedImage drawBuffer; private volatile BufferedImage drawBuffer;
private volatile BufferedImage overlayBuffer; private volatile BufferedImage overlayBuffer;
private volatile BufferedImage paintBuffer; private volatile BufferedImage paintBuffer;
@ -21,8 +22,9 @@ public class Canvas {
private final BufferStrategy strategy; private final BufferStrategy strategy;
private final Thread refresher; private final Thread refresher;
private final JFrame frame; private final JFrame frame;
private final Canvas canvas;
public Canvas() { public NetCanvas() {
frame = new JFrame() { frame = new JFrame() {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -52,15 +54,21 @@ public class Canvas {
} }
}; };
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); canvas = new Canvas();
frame.setUndecorated(true); canvas.setSize(800, 600);
frame.setResizable(true);
frame.setSize(800, 600);
frame.setVisible(true);
frame.setAlwaysOnTop(true);
frame.createBufferStrategy(2); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
strategy = frame.getBufferStrategy(); frame.setTitle("Pixelflut");
// frame.setUndecorated(true);
frame.setResizable(true);
// frame.setAlwaysOnTop(true);
frame.add(canvas);
frame.pack();
frame.setVisible(true);
canvas.createBufferStrategy(2);
strategy = canvas.getBufferStrategy();
resizeBuffer(1024, 1024); resizeBuffer(1024, 1024);
refresher = new Thread(new Runnable() { refresher = new Thread(new Runnable() {

View file

@ -3,14 +3,48 @@ package de.paws.pixelwar;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import java.util.HashSet;
import java.util.Set;
public class PixelClientHandler extends SimpleChannelInboundHandler<String> { public class PixelClientHandler extends SimpleChannelInboundHandler<String> {
private final Canvas canvas; private static Set<PixelClientHandler> clients = new HashSet<>();
public PixelClientHandler(Canvas canvas) { private final NetCanvas canvas;
private long connected;
private long c = 0;
private ChannelHandlerContext channel;
public PixelClientHandler(NetCanvas canvas) {
this.canvas = canvas; this.canvas = canvas;
} }
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
this.connected = System.currentTimeMillis();
channel = ctx;
synchronized (clients) {
clients.add(this);
}
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx);
long passed = System.currentTimeMillis() - connected;
System.out.print(c * 1000 / passed);
synchronized (clients) {
clients.remove(this);
}
}
public void writeIfPossible(String str) {
if (channel.channel().isWritable()) {
channel.writeAndFlush(str.trim() + "\n");
}
}
@Override @Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) protected void channelRead0(ChannelHandlerContext ctx, String msg)
throws Exception { throws Exception {
@ -21,6 +55,7 @@ public class PixelClientHandler extends SimpleChannelInboundHandler<String> {
String command = parts[0].toUpperCase(); String command = parts[0].toUpperCase();
if (command.equals("PX")) { if (command.equals("PX")) {
c++;
if (parts.length == 3) { if (parts.length == 3) {
int x = Integer.parseInt(parts[1]); int x = Integer.parseInt(parts[1]);
int y = Integer.parseInt(parts[2]); int y = Integer.parseInt(parts[2]);
@ -34,13 +69,23 @@ public class PixelClientHandler extends SimpleChannelInboundHandler<String> {
if (parts[3].length() == 6) if (parts[3].length() == 6)
color += 0xff000000; color += 0xff000000;
canvas.setPixel(x, y, color); canvas.setPixel(x, y, color);
} else {
ctx.writeAndFlush("ERR\n");
ctx.close();
} }
} else if (command.equals("SIZE")) { } else if (command.equals("SIZE")) {
ctx.write(String.format("SIZE %d %d\n", canvas.getWidth(), ctx.writeAndFlush(String.format("SIZE %d %d\n", canvas.getWidth(),
canvas.getHeight())); canvas.getHeight()));
ctx.flush(); } else if (command.equals("MSG")) {
} else if (command.equals("TILE") && parts.length == 3) { String text = command + " "
+ msg.substring(command.length()).trim();
for (PixelClientHandler c : clients) {
if (c != this)
c.writeIfPossible(text);
}
} else {
ctx.writeAndFlush("ERR\n");
ctx.close();
} }
} }
} }

View file

@ -5,6 +5,7 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption; import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup; import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.SocketChannel;
@ -18,12 +19,12 @@ import io.netty.handler.logging.LoggingHandler;
public class PixelServer extends ChannelHandlerAdapter { public class PixelServer extends ChannelHandlerAdapter {
private final Canvas canvas; private final NetCanvas canvas;
private final int port; private final int port;
public PixelServer(int port) { public PixelServer(int port) {
this.port = port; this.port = port;
this.canvas = new Canvas(); this.canvas = new NetCanvas();
} }
public void run() throws InterruptedException { public void run() throws InterruptedException {
@ -39,19 +40,17 @@ public class PixelServer extends ChannelHandlerAdapter {
@Override @Override
public void initChannel(SocketChannel ch) public void initChannel(SocketChannel ch)
throws Exception { throws Exception {
ChannelPipeline p = ch.pipeline();
ch.pipeline().addLast( // p.addLast("logger", new LoggingHandler(
"framer", // LogLevel.DEBUG));
new DelimiterBasedFrameDecoder(128, p.addLast("framer", new DelimiterBasedFrameDecoder(
Delimiters.lineDelimiter())); 128, Delimiters.lineDelimiter()));
ch.pipeline().addLast("decoder", p.addLast("decoder", new StringDecoder());
new StringDecoder()); p.addLast("encoder", new StringEncoder());
ch.pipeline().addLast("encoder",
new StringEncoder());
// and then business logic. // and then business logic.
ch.pipeline().addLast("handler", p.addLast("handler", new PixelClientHandler(canvas));
new PixelClientHandler(canvas));
} }
}); });