Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@
<version>4.1.82.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/gg/playit/control/ChannelSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@
import gg.playit.messages.ControlRequestWriter;
import gg.playit.messages.DecodeException;
import gg.playit.minecraft.utils.DecoderException;
import gg.playit.minecraft.utils.Logger;

import java.io.IOException;
import java.net.*;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Comparator;
import java.util.logging.Logger;

public class ChannelSetup {
public static final int CONTROL_PORT = 5525;

static Logger log = Logger.getLogger(ChannelSetup.class.getName());
static Logger log = new Logger(ChannelSetup.class.getName());

public static FindSuitableChannel start() throws UnknownHostException {
InetAddress[] allByName = InetAddress.getAllByName("control.playit.gg");
Expand Down Expand Up @@ -155,7 +155,7 @@ public PlayitControlChannel authenticate(String secretKey) throws IOException {

if (response instanceof ControlFeedReader.Error error) {
if (error == ControlFeedReader.Error.RequestQueued) {
log.info("request queued, waiting 1 second before resend");
log.debug("request queued, waiting 1 second before resend");

try {
Thread.sleep(1000);
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/gg/playit/control/PlayitControlChannel.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import gg.playit.messages.ControlFeedReader;
import gg.playit.messages.ControlRequestWriter;
import gg.playit.messages.DecodeException;
import gg.playit.minecraft.utils.Logger;

import java.io.Closeable;
import java.io.IOException;
Expand All @@ -16,12 +17,11 @@
import java.time.Instant;
import java.util.Arrays;
import java.util.Optional;
import java.util.logging.Logger;

import static gg.playit.control.ChannelSetup.CONTROL_PORT;

public class PlayitControlChannel implements Closeable {
static Logger log = Logger.getLogger(ChannelSetup.class.getName());
static Logger log = new Logger(ChannelSetup.class.getName());

ApiClient apiClient;
DatagramSocket socket;
Expand Down Expand Up @@ -57,7 +57,7 @@ public Optional<ControlFeedReader.ControlFeed> update() throws IOException {

var tillExpire = this.registered.expiresAt - now;
if (tillExpire < 60_000 && 10_000 < now - lastKeepAlive) {
log.info("send keep alive");
log.debug("send keep alive");
lastKeepAlive = now;

this.sendKeepAlive();
Expand Down
53 changes: 48 additions & 5 deletions src/main/java/gg/playit/minecraft/PlayitBukkit.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import gg.playit.api.ApiClient;
import gg.playit.api.ApiError;
import gg.playit.api.models.Notice;
import gg.playit.minecraft.utils.Logger;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import org.bukkit.Bukkit;
Expand All @@ -17,13 +18,14 @@

import java.io.IOException;
import java.util.List;
import java.util.logging.Logger;

public final class PlayitBukkit extends JavaPlugin implements Listener {
public static final String CFG_AGENT_SECRET_KEY = "agent-secret";
public static final String CFG_CONNECTION_TIMEOUT_SECONDS = "mc-timeout-sec";
public static final String CFG_DEBUG_LOGGING = "debug-logging";
private static boolean debugLogging = false;

static Logger log = Logger.getLogger(PlayitBukkit.class.getName());
static Logger log = new Logger(PlayitBukkit.class.getName());
final EventLoopGroup eventGroup = new NioEventLoopGroup();

private final Object managerSync = new Object();
Expand All @@ -40,15 +42,24 @@ public void onEnable() {
command.setExecutor(this);
command.setTabCompleter(this);
} else {
log.severe("failed to setup command /playit");
log.error("failed to setup command /playit");
}

getConfig().addDefault("agent-secret", "");
getConfig().addDefault("debug-logging", "false");
saveDefaultConfig();

var secretKey = getConfig().getString("agent-secret");
resetConnection(secretKey);

var debugLogging = getConfig().getString(CFG_DEBUG_LOGGING);
if ("true".equals(debugLogging)) {
setDebugLogging(true);
} else if ("false".equals(debugLogging)) {
setDebugLogging(false);
}
getConfig().set(CFG_DEBUG_LOGGING, hasDebugLogging());

try {
PluginManager pm = Bukkit.getServer().getPluginManager();
pm.registerEvents(this, this);
Expand Down Expand Up @@ -239,14 +250,32 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
log.warning("failed to create guest secret: " + e);
sender.sendMessage("error: " + e.getMessage());
} catch (IOException e) {
log.severe("failed to create guest secret: " + e);
log.error("failed to create guest secret: " + e);
}
}).start();

return true;
}
}

if (args.length > 0 && args[0].equals("logging")) {
if (args.length > 1 && args[1].equals("enable")) {
getConfig().set(CFG_DEBUG_LOGGING, true);
saveConfig();
setDebugLogging(true);
sender.sendMessage("enabled debug logging");
return true;
}

if (args.length > 1 && args[1].equals("disable")) {
getConfig().set(CFG_DEBUG_LOGGING, false);
saveConfig();
setDebugLogging(false);
sender.sendMessage("disabled debug logging");
return true;
}
}

return false;
}

Expand Down Expand Up @@ -286,7 +315,7 @@ public List<String> onTabComplete(CommandSender sender, Command command, String
}

if (argCount == 0) {
return List.of("agent", "tunnel", "prop", "account");
return List.of("agent", "tunnel", "prop", "account", "logging");
}

if (args[0].equals("account")) {
Expand Down Expand Up @@ -321,6 +350,12 @@ public List<String> onTabComplete(CommandSender sender, Command command, String
}
}

if (args[0].equals("logging")) {
if (argCount == 1) {
return List.of("enable", "disable");
}
}

return null;
}

Expand All @@ -331,4 +366,12 @@ public void onDisable() {
playitManager = null;
}
}

public static boolean hasDebugLogging() {
return debugLogging;
}

public void setDebugLogging(boolean debugLogging) {
PlayitBukkit.debugLogging = debugLogging;
}
}
20 changes: 10 additions & 10 deletions src/main/java/gg/playit/minecraft/PlayitKeysSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
import gg.playit.api.models.PortType;
import gg.playit.api.models.TunnelType;
import gg.playit.minecraft.utils.Hex;
import gg.playit.minecraft.utils.Logger;

import java.io.IOException;
import java.net.InetAddress;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;

public class PlayitKeysSetup {
private static final Logger log = Logger.getLogger(PlayitKeysSetup.class.getName());
private static final Logger log = new Logger(PlayitKeysSetup.class.getName());
public final AtomicInteger state;
public static final int STATE_INIT = 1;
public static final int STATE_MISSING_SECRET = 2;
Expand Down Expand Up @@ -55,18 +55,18 @@ public PlayitKeys progress() throws IOException {
}

state.compareAndSet(STATE_INIT, STATE_CHECKING_SECRET);
log.info("secret key found, checking");
log.debug("secret key found, checking");
return null;
}
case STATE_MISSING_SECRET -> {
if (claimCode == null) {
byte[] array = new byte[8];
new Random().nextBytes(array);
claimCode = Hex.encodeHexString(array);
log.info("secret key not set, generate claim code: " + claimCode);
log.debug("secret key not set, generate claim code: " + claimCode);
}

log.info("trying to exchange claim code for secret");
log.debug("trying to exchange claim code for secret");
keys.secretKey = openClient.exchangeClaimForSecret(claimCode);

if (keys.secretKey == null) {
Expand All @@ -78,7 +78,7 @@ public PlayitKeys progress() throws IOException {
return null;
}
case STATE_CHECKING_SECRET -> {
log.info("check secret");
log.debug("check secret");

var api = new ApiClient(keys.secretKey);
try {
Expand All @@ -94,11 +94,11 @@ public PlayitKeys progress() throws IOException {
} catch (ApiError e) {
if (e.statusCode == 401 || e.statusCode == 400) {
if (claimCode == null) {
log.info("secret key invalid, starting over");
log.debug("secret key invalid, starting over");
state.compareAndSet(STATE_CHECKING_SECRET, STATE_MISSING_SECRET);
} else {
state.compareAndSet(STATE_CHECKING_SECRET, STATE_ERROR);
log.info("secret failed verification after creating, moving to error state");
log.debug("secret failed verification after creating, moving to error state");
}

return null;
Expand All @@ -116,12 +116,12 @@ public PlayitKeys progress() throws IOException {
for (AccountTunnel tunnel : tunnels.tunnels) {
if (tunnel.tunnelType == TunnelType.MinecraftJava) {
keys.tunnelAddress = tunnel.displayAddress;
log.info("found minecraft java tunnel: " + keys.tunnelAddress);
log.debug("found minecraft java tunnel: " + keys.tunnelAddress);
return keys;
}
}

log.info("create new minecraft java tunnel");
log.debug("create new minecraft java tunnel");

var create = new CreateTunnel();
create.localIp = "127.0.0.1";
Expand Down
28 changes: 14 additions & 14 deletions src/main/java/gg/playit/minecraft/PlayitManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
import gg.playit.api.models.Notice;
import gg.playit.control.PlayitControlChannel;
import gg.playit.messages.ControlFeedReader;
import gg.playit.minecraft.utils.Logger;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;

public class PlayitManager implements Runnable {
static Logger log = Logger.getLogger(PlayitManager.class.getName());
static Logger log = new Logger(PlayitManager.class.getName());
private final AtomicInteger state = new AtomicInteger(STATE_INIT);
private final PlayitConnectionTracker tracker = new PlayitConnectionTracker();

Expand Down Expand Up @@ -86,11 +86,11 @@ public void run() {
keys = setup.progress();

if (keys != null) {
log.info("keys and tunnel setup");
log.debug("keys and tunnel setup");
break;
}
} catch (IOException e) {
log.severe("got error during setup: " + e);
log.error("got error during setup: " + e);

try {
Thread.sleep(3000);
Expand Down Expand Up @@ -120,7 +120,7 @@ public void run() {
}

if (keys == null) {
log.info("shutdown reached, tunnel connection never started");
log.debug("shutdown reached, tunnel connection never started");
return;
}

Expand All @@ -136,7 +136,7 @@ public void run() {
try {
var key = api.createGuestWebSessionKey();
var url = "https://playit.gg/login/guest-account/" + key;
log.info("setup playit.gg account: " + url);
log.debug("setup playit.gg account: " + url);

if (state.get() == STATE_SHUTDOWN) {
return;
Expand All @@ -149,7 +149,7 @@ public void run() {
}
}
} catch (IOException e) {
log.severe("failed to generate web session key: " + e);
log.error("failed to generate web session key: " + e);
}
} else if (!keys.isEmailVerified) {
plugin.broadcast(ChatColor.RED + "WARNING: " + ChatColor.RESET + "email associated with playit.gg account is not verified");
Expand All @@ -174,11 +174,11 @@ public void run() {
var feedMessage = messageOpt.get();

if (feedMessage instanceof ControlFeedReader.NewClient newClient) {
log.info("got new client: " + feedMessage);
log.debug("got new client: " + feedMessage);

var key = newClient.peerAddr + "-" + newClient.connectAddr;
if (tracker.addConnection(key)) {
log.info("starting tcp tunnel for client");
log.debug("starting tcp tunnel for client");

new PlayitTcpTunnel(
new InetSocketAddress(InetAddress.getByAddress(newClient.peerAddr.ipBytes), Short.toUnsignedInt(newClient.peerAddr.portNumber)),
Expand All @@ -197,7 +197,7 @@ public void run() {
}
} catch (IOException e) {
state.compareAndSet(STATE_ONLINE, STATE_ERROR_WAITING);
log.severe("failed when communicating with tunnel server, error: " + e);
log.error("failed when communicating with tunnel server, error: " + e);

if (e.getMessage().contains("invalid authentication")) {
state.set(STATE_INVALID_AUTH);
Expand All @@ -209,17 +209,17 @@ public void run() {
}
} finally {
if (state.compareAndSet(STATE_SHUTDOWN, STATE_OFFLINE)) {
log.info("control channel shutdown");
log.debug("control channel shutdown");
} else if (state.compareAndSet(STATE_ERROR_WAITING, STATE_CONNECTING)) {
log.info("trying to connect again");
log.debug("trying to connect again");
} else if (state.compareAndSet(STATE_ONLINE, STATE_CONNECTING)) {
log.warning("unexpected state ONLINE, moving to CONNECTING");
}
if (state.get() == STATE_CONNECTING) {
log.info("failed to connect, retrying");
log.debug("failed to connect, retrying");
}
if (state.get() == STATE_INVALID_AUTH) {
log.info("invalid auth, done trying");
log.debug("invalid auth, done trying");
}
}
}
Expand Down
Loading