99 lines
3.6 KiB
Java
99 lines
3.6 KiB
Java
/*
|
|
* Copyright (C) 2025 Minecon724
|
|
* Tweaks724 is licensed under the GNU General Public License. See the LICENSE.md file
|
|
* in the project root for the full license text.
|
|
*/
|
|
|
|
package eu.m724.tweaks.module.redstone;
|
|
|
|
import eu.m724.tweaks.DebugLogger;
|
|
import eu.m724.tweaks.TweaksConfig;
|
|
import eu.m724.tweaks.module.TweaksModule;
|
|
|
|
import java.io.IOException;
|
|
import java.net.*;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.function.Consumer;
|
|
|
|
public class RedstoneModule extends TweaksModule {
|
|
private final RedstoneGateways redstoneGateways = new RedstoneGateways(getPlugin());
|
|
|
|
private DatagramSocket socket;
|
|
private RedstoneStateUpdateRunnable runnable;
|
|
|
|
@Override
|
|
protected void onInit() {
|
|
RedstoneStore.init(getPlugin());
|
|
var gatewayItem = new GatewayItem(getPlugin());
|
|
|
|
registerEvents(new RedstoneListener(redstoneGateways, gatewayItem));
|
|
registerCommand("retstone", new RedstoneCommands(gatewayItem));
|
|
|
|
this.runnable = new RedstoneStateUpdateRunnable(redstoneGateways);
|
|
this.runnable.runTaskTimer(getPlugin(), 0, 20); // TODO configurable
|
|
|
|
var listenAddress = TweaksConfig.getConfig().redstoneListen().split(":");
|
|
InetSocketAddress bindAddress;
|
|
if (listenAddress.length == 1) {
|
|
bindAddress = new InetSocketAddress(Integer.parseInt(listenAddress[0]));
|
|
} else {
|
|
bindAddress = new InetSocketAddress(listenAddress[0], Integer.parseInt(listenAddress[1]));
|
|
}
|
|
|
|
try {
|
|
initSocket(bindAddress);
|
|
} catch (SocketException e) {
|
|
throw new RuntimeException("Starting socket", e);
|
|
}
|
|
}
|
|
|
|
private void initSocket(SocketAddress bindAddress) throws SocketException {
|
|
socket = new DatagramSocket(bindAddress);
|
|
|
|
Executors.newSingleThreadExecutor().execute(() -> {
|
|
byte[] buf = new byte[4];
|
|
|
|
while (!socket.isClosed()) {
|
|
DatagramPacket packet
|
|
= new DatagramPacket(buf, buf.length);
|
|
try {
|
|
socket.receive(packet);
|
|
} catch (IOException e) {
|
|
DebugLogger.severe("Error reading packet: " + e.getMessage());
|
|
continue;
|
|
}
|
|
|
|
boolean write = (buf[0] >> 7 & 1) == 1;
|
|
byte data = (byte) (buf[3] & 0xF);
|
|
int gatewayId = ((buf[0] & 0x7F) << 24) | ((buf[1] & 0xFF) << 16) | ((buf[2] & 0xFF) << 8) | (buf[3] & 0xF0);
|
|
|
|
if (write) {
|
|
enqueueUpdate(gatewayId, data);
|
|
} else {
|
|
var newPacket = new DatagramPacket(new byte[1], 1, packet.getSocketAddress());
|
|
|
|
enqueueRetrieve(gatewayId, value -> {
|
|
DebugLogger.fine("Retrieved for " + gatewayId + " power " + value);
|
|
newPacket.setData(new byte[] { (byte) Math.max(value, 0) });
|
|
|
|
try {
|
|
socket.send(newPacket);
|
|
} catch (IOException e) {
|
|
throw new RuntimeException("Sending response to get repeater value", e);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private void enqueueUpdate(int gatewayId, byte power) {
|
|
DebugLogger.finer("Update enqueued " + gatewayId + " " + power);
|
|
runnable.enqueueUpdate(gatewayId, power);
|
|
}
|
|
|
|
private void enqueueRetrieve(int gatewayId, Consumer<Byte> consumer) {
|
|
DebugLogger.finer("Retrieve enqueued " + gatewayId);
|
|
runnable.enqueueRetrieve(gatewayId, consumer);
|
|
}
|
|
}
|