First commit

This commit is contained in:
Maschell 2018-09-15 12:41:02 +02:00
commit c6ca27edd5
12 changed files with 810 additions and 0 deletions

18
.circleci/circle.yml Normal file
View File

@ -0,0 +1,18 @@
machine:
java:
version: oraclejdk8
compile:
override:
- mvn package -Dci-build=true
general:
artifacts:
- "ci"
deployment:
nightlies:
branch: master
commands:
- go get github.com/tcnksm/ghr
- ghr -t $GITHUB_TOKEN -u $CIRCLE_PROJECT_USERNAME -r $CIRCLE_PROJECT_REPONAME -prerelease -b 'Nightly release - Use caution! We recommend downloading a stable release from the README.' `echo "v0.1-nightly-$(git rev-parse --short=7 HEAD)"` ci/

18
README.MD Normal file
View File

@ -0,0 +1,18 @@
# Streaming Plugin Client
A Java client for the [Wii U Streaming Plugin](https://github.com/Maschell/StreamingPluginWiiU).
# Usage
Start the plugin via the [WiiUPluginSystemLoader](https://github.com/Maschell/WiiUPluginSystem) on your WiiU. Now start Java client by either
- provide the ip address of your Wii U as a argument. Example: ``java -jar StreamingPluginClient[...].jar --ip 192.168.0.11`
- **or** just double click on the .jar. A little dialog should appear where you can enter the IP address of your Wii U console.
Requires Java 8.
# Building
This is a maven project. Use following command to create a .jar with dependencies in the `target` folder.
```
mvn package
```

86
pom.xml Normal file
View File

@ -0,0 +1,86 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>StreamingPluginClient</groupId>
<artifactId>StreamingPluginClient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>StreamingPluginClient</name>
<url>https://github.com/Maschell/StreamingPluginClient</url>
<profiles>
<profile>
<id>normal-build</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<jar_dir>./target</jar_dir>
</properties>
</profile>
<profile>
<id>ci-build</id>
<activation>
<property>
<name>ci-build</name>
<value>true</value>
</property>
</activation>
<properties>
<jar_dir>./ci</jar_dir>
</properties>
</profile>
</profiles>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-assembly</id>
<configuration>
<archive>
<manifest>
<mainClass>de.mas.wiiu.streaming.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- Stick jar in root dir, if you want -->
<outputDirectory>${jar_dir}</outputDirectory>
<finalName>StreamingPluginClient-${project.version}-nightly</finalName>
</configuration>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,196 @@
/*******************************************************************************
* Copyright (c) 2018 Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package de.mas.wiiu.streaming;
import java.io.IOException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.zip.CRC32;
import javax.swing.JOptionPane;
import de.mas.wiiu.streaming.gui.IImageProvider;
import de.mas.wiiu.streaming.gui.ImageProvider;
import de.mas.wiiu.streaming.network.TCPClient;
import de.mas.wiiu.streaming.network.UDPClient;
import de.mas.wiiu.streaming.utilities.Utilities;
import lombok.Synchronized;
import lombok.extern.java.Log;
@Log
public class ImageStreamer {
private final ImageProvider imageProvider = new ImageProvider();
private final TCPClient tcpClient;
private final UDPClient udpClient;
public ImageStreamer(String ip) throws SocketException {
tcpClient = new TCPClient(ip, 8092, 200);
udpClient = new UDPClient(9445);
new Thread(udpClient, "UDPClient").start();
udpClient.setOnDataCallback(this::udpDataHandler);
new Thread(() -> {
while (true) {
if (!tcpClient.isConnected()) {
System.out.print("Connecting..");
try {
tcpClient.connect();
System.out.println("success!");
} catch (IllegalArgumentException | UnknownHostException e1) {
JOptionPane.showMessageDialog(null, "Make sure to enter a valid ip address.", e1.getClass().getName(), JOptionPane.WARNING_MESSAGE);
System.exit(-1);
} catch (SocketTimeoutException e) {
System.out.println("time out...");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
sendPing();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(() -> {
while (true) {
if (tcpClient.isConnected()) {
System.out.println("FPS:" + framesThisSecond);
framesThisSecond = 0;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
private boolean sendTCP(byte[] rawCommand) {
boolean result = false;
try {
tcpClient.send(rawCommand);
result = true;
} catch (Exception e) {
result = false;
}
return result;
}
void sendPing() {
if (sendTCP(new byte[] { 0x15 })) {
byte pong;
try {
pong = tcpClient.recvByte();
if (pong == 0x16) {
// log.info("Ping...Pong!");
} else {
log.info("Got no valid response to a Ping. Disconnecting.");
tcpClient.abort();
}
} catch (IOException e) {
log.info("Failed to get PONG. Disconnecting.");
tcpClient.abort();
}
} else {
log.info("Sending the PING failed");
}
}
private final Object lock = new Object();
private DataState state = DataState.UNKNOWN;
private int curcrc32 = 0;
private int curJPEGSize = 0;
private byte[] jpegBuffer = {};
private int curLenPos = 0;
private int framesThisSecond = 0;
@Synchronized("lock")
private void udpDataHandler(byte[] data) {
if (state == DataState.UNKNOWN) {
// System.out.println("GET CRC");
if (data.length == 4) {
ByteBuffer wrapped = ByteBuffer.wrap(data); // big-endian by default
curcrc32 = wrapped.getInt(); // 1
state = DataState.CRC32_RECEIVED;
} else {
state = DataState.UNKNOWN;
return;
}
} else if (state == DataState.CRC32_RECEIVED) {
// System.out.println("GET Size");
if (data.length == 8) {
ByteBuffer wrapped = ByteBuffer.wrap(data); // big-endian by default
curJPEGSize = (int) wrapped.getLong();
jpegBuffer = new byte[curJPEGSize];
state = DataState.RECEIVING_IMAGE;
curLenPos = 0;
} else {
// System.out.println("...");
state = DataState.UNKNOWN;
return;
}
} else if (state == DataState.RECEIVING_IMAGE) {
// System.out.println("GET IMAGE");
System.arraycopy(data, 0, jpegBuffer, curLenPos, data.length > curJPEGSize ? curJPEGSize : data.length);
curJPEGSize -= data.length;
curLenPos += data.length;
if (curJPEGSize <= 0) {
CRC32 crc = new CRC32();
crc.update(jpegBuffer);
if ((int) crc.getValue() == curcrc32) {
imageProvider.updateImage(Utilities.byteArrayToImage(jpegBuffer));
framesThisSecond++;
} else {
System.out.println("Hash mismatch, dropping frame.");
}
state = DataState.UNKNOWN;
}
}
}
public IImageProvider getImageProvider() {
return imageProvider;
}
public enum DataState {
UNKNOWN, CRC32_RECEIVED, RECEIVING_IMAGE, IMAGE_RECEIVED
}
}

View File

@ -0,0 +1,75 @@
/*******************************************************************************
* Copyright (c) 2018 Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package de.mas.wiiu.streaming;
import java.net.BindException;
import java.net.SocketException;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import de.mas.wiiu.streaming.gui.StreamWindow;
public class Main {
public static void main(String[] args) throws Exception {
CommandLineParser parser = new DefaultParser();
Options options = new Options();
options.addOption("ip", "ip", true, "IP address of your Wii U Console.");
CommandLine line = parser.parse(options, args);
String ip = null;
if (line.hasOption("ip")) {
ip = line.getOptionValue("ip");
} else {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("streamingTool", options);
ip = JOptionPane.showInputDialog(null, "Please enter the local IP address of your Wii U", "Wii U streaming client", JOptionPane.PLAIN_MESSAGE);
}
try {
new Main(ip);
} catch (BindException e) {
JOptionPane.showMessageDialog(null, "Can't bind socket. The client is probably already running.", e.getClass().getName(),
JOptionPane.WARNING_MESSAGE);
System.exit(-1);
}
}
public Main(String ip) throws SocketException {
ImageStreamer imageStreamer = new ImageStreamer(ip);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new StreamWindow(imageStreamer.getImageProvider());
}
});
}
}

View File

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2018 Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package de.mas.wiiu.streaming.gui;
import java.awt.Image;
import java.util.function.Consumer;
public interface IImageProvider {
void setOnImageChange(Consumer<Image> function);
}

View File

@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2018 Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package de.mas.wiiu.streaming.gui;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JPanel;
public final class ImagePanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = -127096088663141229L;
private Image image;
private final int preferedWidth;
private final int preferedHeight;
public ImagePanel(int width, int height) {
super(true);
preferedWidth = width;
preferedHeight = height;
}
public void setImage(Image image) {
this.image = image;
repaint();
}
public Dimension getPreferredSize() {
return new Dimension(preferedWidth, preferedHeight);
}
public void paint(Graphics g) {
super.paint(g);
if (image != null) {
g.drawImage(image, 0, 0, getWidth(), getHeight(), 0, 0, image.getWidth(this), image.getHeight(this), this);
}
}
}

View File

@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 2018 Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package de.mas.wiiu.streaming.gui;
import java.awt.Image;
import java.util.function.Consumer;
public final class ImageProvider implements IImageProvider {
private Consumer<Image> onImageChangeFunction = null;
public void updateImage(Image image) {
if (onImageChangeFunction != null) {
onImageChangeFunction.accept(image);
}
}
@Override
public void setOnImageChange(Consumer<Image> function) {
this.onImageChangeFunction = function;
}
}

View File

@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2018 Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package de.mas.wiiu.streaming.gui;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class StreamWindow {
private final ImagePanel image = new ImagePanel(1280, 720);
public StreamWindow(IImageProvider imageProvider) {
JFrame editorFrame = new JFrame("Stream");
editorFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
imageProvider.setOnImageChange((bi) -> image.setImage(bi));
editorFrame.add(image);
editorFrame.pack();
editorFrame.setLocationRelativeTo(null);
editorFrame.setVisible(true);
}
}

View File

@ -0,0 +1,119 @@
/*******************************************************************************
* Copyright (c) 2017,2018 Ash (QuarkTheAwesome) & Maschell
* Taken from the HID to VPAD Networkclient. Modified for the StreamingPluginClient.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package de.mas.wiiu.streaming.network;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import lombok.Synchronized;
import lombok.extern.java.Log;
@Log
final public class TCPClient {
private final Object lock = new Object();
private Socket sock;
private DataInputStream in;
private DataOutputStream out;
private final String ip;
private final int port;
private final int timeout;
public TCPClient(String ip, int port, int timeout) {
this.ip = ip;
this.port = port;
this.timeout = timeout;
}
@Synchronized("lock")
public void connect() throws IOException {
sock = new Socket();
sock.connect(new InetSocketAddress(ip, port), timeout);
in = new DataInputStream(sock.getInputStream());
out = new DataOutputStream(sock.getOutputStream());
}
@Synchronized("lock")
public boolean abort() {
try {
sock.close();
} catch (IOException e) {
log.info(e.getMessage()); // TODO: handle
return false;
}
return true;
}
@Synchronized("lock")
public void send(byte[] rawCommand) throws IOException {
try {
out.write(rawCommand);
out.flush();
} catch (IOException e) {
throw e;
}
}
void send(int value) throws IOException {
send(ByteBuffer.allocate(4).putInt(value).array());
}
public void send(byte _byte) throws IOException {
send(ByteBuffer.allocate(1).put(_byte).array());
}
@Synchronized("lock")
public byte recvByte() throws IOException {
return in.readByte();
}
@Synchronized("lock")
short recvShort() throws IOException {
try {
return in.readShort();
} catch (IOException e) {
log.info(e.getMessage());
throw e;
}
}
@Synchronized("lock")
int recvInt() throws IOException {
try {
return in.readInt();
} catch (IOException e) {
log.info(e.getMessage());
throw e;
}
}
@Synchronized("lock")
public boolean isConnected() {
return (sock != null && sock.isConnected() && !sock.isClosed());
}
}

View File

@ -0,0 +1,65 @@
/*******************************************************************************
* Copyright (c) 2018 Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package de.mas.wiiu.streaming.network;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Arrays;
import java.util.function.Consumer;
import lombok.extern.java.Log;
@Log
public final class UDPClient implements Runnable {
private final DatagramSocket sock;
public UDPClient(int port) throws SocketException {
sock = new DatagramSocket(port);
}
private Consumer<byte[]> onDataCallback = null;
public void setOnDataCallback(Consumer<byte[]> function) {
onDataCallback = function;
}
@Override
public void run() {
log.info("UDPClient running.");
byte[] receiveData = new byte[1400];
while (true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
try {
sock.receive(receivePacket);
} catch (IOException e) {
continue;
}
byte[] data = Arrays.copyOf(receivePacket.getData(), receivePacket.getLength());
if (onDataCallback != null) {
onDataCallback.accept(data);
}
}
}
}

View File

@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2018 Maschell
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*******************************************************************************/
package de.mas.wiiu.streaming.utilities;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
public class Utilities {
private Utilities() {
//
}
public static String ByteArrayToString(byte[] ba) {
if (ba == null)
return null;
StringBuilder hex = new StringBuilder(ba.length * 2);
for (byte b : ba) {
hex.append(String.format("%02X", b));
}
return hex.toString();
}
public static BufferedImage byteArrayToImage(byte[] bytes) {
BufferedImage bufferedImage = null;
try {
InputStream inputStream = new ByteArrayInputStream(bytes);
bufferedImage = ImageIO.read(inputStream);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
return bufferedImage;
}
}