Skip to content

Commit

Permalink
mbaxter edition
Browse files Browse the repository at this point in the history
  • Loading branch information
octylFractal committed Sep 16, 2016
1 parent 3004066 commit 40c6bb6
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 28 deletions.
7 changes: 5 additions & 2 deletions src/main/java/org/kitteh/irc/client/library/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.kitteh.irc.client.library.event.client.ClientConnectedEvent;
import org.kitteh.irc.client.library.event.user.DCCConnectedEvent;
import org.kitteh.irc.client.library.event.user.DCCFailedEvent;
import org.kitteh.irc.client.library.event.user.DCCSocketBoundEvent;
import org.kitteh.irc.client.library.event.user.PrivateCTCPQueryEvent;
import org.kitteh.irc.client.library.feature.AuthManager;
import org.kitteh.irc.client.library.feature.CapabilityManager;
Expand Down Expand Up @@ -835,8 +836,10 @@ default void sendMultiLineNotice(@Nonnull MessageReceiver target, @Nonnull Strin
/**
* Sends a DCC CHAT request to the target.
*
* <p>When the chat is connected, a {@link DCCConnectedEvent} will be fired. If the connection fails,
* a {@link DCCFailedEvent} will be fired.</p>
* <p>When the server socket is bound locally, a
* {@link DCCSocketBoundEvent} will be fired. When the chat is connected,
* a {@link DCCConnectedEvent} will be fired. If the connection fails, a
* {@link DCCFailedEvent} will be fired.</p>
*/
void requestDCCChat(@Nonnull User target);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public interface DCCChat extends DCCExchange {
/**
* Sends the user a message over DCC chat.
*
* <p>This method won't return until the chat is connected and the message has
* been sent.</p>
* <p>This method won't work if the chat is not
* {@link #isConnected() connected}.</p>
*
* @param message the message to send
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,24 @@
*/
public interface DCCExchange extends Actor {
/**
* Gets the socket address of the local end.
* May return {@link Optional#empty()} if not connected.
*
* @return the socket address of the local end
*/
Optional<SocketAddress> getLocalSocketAddress();

/**
* Gets the socket address of the remote end.
* May return {@link Optional#empty()} if not connected.
*
* @return the socket address of the remote end
*/
Optional<SocketAddress> getRemoteSocketAddress();

/**
* Gets the connection status.
*
* @return {@code true} if the exchange is connected, otherwise false
* @return {@code true} if the exchange is connected, otherwise
* {@code false}
*/
boolean isConnected();

/**
* Closes this DCC chat.
* Closes this DCC exchange. It will no longer be
* {@link #isConnected() connected}.
*/
void close();
}
11 changes: 7 additions & 4 deletions src/main/java/org/kitteh/irc/client/library/element/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.kitteh.irc.client.library.Client;
import org.kitteh.irc.client.library.event.user.DCCConnectedEvent;
import org.kitteh.irc.client.library.event.user.DCCFailedEvent;
import org.kitteh.irc.client.library.event.user.DCCSocketBoundEvent;
import org.kitteh.irc.client.library.feature.CapabilityManager;
import org.kitteh.irc.client.library.feature.ServerInfo;

Expand Down Expand Up @@ -104,16 +105,18 @@ public interface User extends MessageReceiver, Staleable {
*/
boolean isAway();


/**
* Sends a DCC CHAT request to this user.
* Sends a DCC CHAT request to the target.
*
* <p>When the chat is connected, a {@link DCCConnectedEvent} will be fired. If the connection fails,
* a {@link DCCFailedEvent} will be fired.</p>
* <p>When the server socket is bound locally, a
* {@link DCCSocketBoundEvent} will be fired. When the chat is connected,
* a {@link DCCConnectedEvent} will be fired. If the connection fails, a
* {@link DCCFailedEvent} will be fired.</p>
*
* @see Client#requestDCCChat(User)
*/
default void requestDCCChat() {
this.getClient().requestDCCChat(this);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.kitteh.irc.client.library.event.user;

import org.kitteh.irc.client.library.Client;
import org.kitteh.irc.client.library.element.ServerMessage;
import org.kitteh.irc.client.library.element.User;
import org.kitteh.irc.client.library.event.abstractbase.ActorEventBase;
import org.kitteh.irc.client.library.util.Sanity;

import javax.annotation.Nonnull;
import java.util.List;

public class DCCRequestEvent extends ActorEventBase<User> {
private final String type;
private final String ip;
private final int port;

public DCCRequestEvent(@Nonnull Client client, @Nonnull List<ServerMessage> originalMessages, @Nonnull String type, @Nonnull String ip, int port, @Nonnull User actor) {
super(client, originalMessages, actor);
Sanity.nullCheck(type, "type cannot be null");
Sanity.nullCheck(ip, "ip cannot be null");
this.type = type;
this.ip = ip;
this.port = port;
}

public String getType() {
return this.type;
}

public String getIp() {
return this.ip;
}

public int getPort() {
return this.port;
}

/**
* Accepts the request and connect to the socket.
*
* <p>This will trigger {@link DCCConnectedEvent} if successful and
* {@link DCCFailedEvent} otherwise.</p>
*/
public void accept() {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,9 @@ private IRCDCCChatSnapshot(@Nonnull IRCDCCChat actor) {
@Override
public void sendMessage(@Nonnull String message) {
Sanity.nullCheck(message, "message cannot be null");
if (this.nettyChannel == null) {
return;
}
this.nettyChannel.writeAndFlush(message.trim());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
import org.kitteh.irc.client.library.event.helper.ClientEvent;
import org.kitteh.irc.client.library.event.helper.ClientReceiveServerMessageEvent;
import org.kitteh.irc.client.library.event.helper.MonitoredNickStatusEvent;
import org.kitteh.irc.client.library.event.user.DCCRequestEvent;
import org.kitteh.irc.client.library.event.user.MonitoredNickListEvent;
import org.kitteh.irc.client.library.event.user.MonitoredNickListFullEvent;
import org.kitteh.irc.client.library.event.user.MonitoredNickOfflineEvent;
Expand Down Expand Up @@ -978,11 +979,7 @@ public void ctcp(ClientReceiveCommandEvent event) {
reply = "FINGER om nom nom tasty finger";
break;
case "DCC":
// Handle targeted DCC chat
// this.fire(new DCCRequestEvent());
// TODO how can the parameters be extracted @mbaxter???
// I only have DCC of the following:
// DCC <CHAT> <chat> <ip> <addr>
handleDccEvent(user, event.getOriginalMessages(), event.getParameters());
break;
}
if (ctcpMessage.startsWith("PING ")) {
Expand All @@ -1005,6 +1002,27 @@ public void ctcp(ClientReceiveCommandEvent event) {
}
}

private void handleDccEvent(User user, List<ServerMessage> originalMessages, List<String> parameters) {
String dccType = CTCPUtil.fromCTCP(parameters.get(2));
if (dccType.equals("CHAT")) {
String chatType = CTCPUtil.fromCTCP(parameters.get(3));
if (!chatType.equals("chat")) {
return;
}
String ip = CTCPUtil.fromCTCP(parameters.get(4));
String port = CTCPUtil.fromCTCP(parameters.get(5));
int portInt;
try {
portInt = Integer.parseInt(port);
} catch (NumberFormatException invalidPort) {
return;
}
fire(new DCCRequestEvent(this.client, originalMessages, dccType, ip, portInt, user));
} else {
// do logging
}
}

@CommandFilter("MODE")
@Handler(priority = Integer.MAX_VALUE - 1)
public void mode(ClientReceiveCommandEvent event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,9 @@ public String toString() {
}

static class DCCConnection extends ChannelInitializer<SocketChannel> {

private final IRCDCCExchange exchange;
private final InternalClient client;
// Only allow one connection per DCC. Weird, I know.
private boolean oneConnection;
private int connectionsMade;

private DCCConnection(IRCDCCExchange ex, InternalClient client) {
this.exchange = ex;
Expand All @@ -319,11 +317,12 @@ private DCCConnection(IRCDCCExchange ex, InternalClient client) {

@Override
public void initChannel(SocketChannel channel) throws Exception {
if (this.oneConnection) {
if (this.connectionsMade > 0) {
// Only one connection is allowed.
channel.close();
return;
}
this.oneConnection = true;
this.connectionsMade++;
this.exchange.setNettyChannel(channel);
dccConnections.computeIfAbsent(this.client, c -> new ArrayList<>()).add(channel);

Expand Down Expand Up @@ -384,6 +383,11 @@ protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Except
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
// kill DCC when inactive
ctx.close();
DCCConnection.this.exchange.setLocalAddress(null);
DCCConnection.this.exchange.setRemoteAddress(null);
DCCConnection.this.exchange.setConnected(false);
// Close related ServerSocket
ctx.channel().parent().close();
DCCConnection.this.client.getEventManager().callEvent(new DCCConnectionClosedEvent(DCCConnection.this.client, Collections.emptyList(), DCCConnection.this.exchange.snapshot()));
}
});
Expand Down

0 comments on commit 40c6bb6

Please sign in to comment.