Added MSG command (broadcast) to pixelwar
This commit is contained in:
parent
2bb13b0685
commit
ad19b4ffb3
3 changed files with 80 additions and 28 deletions
|
|
@ -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() {
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue