Skip to content

Commit d76b635

Browse files
committed
Add tag support to commands, add PRIVMSG NOTICE and TAGMSG commands
1 parent f00ef02 commit d76b635

16 files changed

+403
-25
lines changed

src/main/java/org/kitteh/irc/client/library/command/AwayCommand.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@
2929
import org.kitteh.irc.client.library.util.Sanity;
3030
import org.kitteh.irc.client.library.util.ToStringer;
3131

32+
import java.util.List;
33+
3234
/**
3335
* Sends an AWAY request to the server.
3436
*/
35-
public class AwayCommand extends Command {
37+
public class AwayCommand extends Command<AwayCommand> {
3638
private @Nullable String message;
3739

3840
/**
@@ -74,7 +76,7 @@ public void execute() {
7476
if (this.message != null) {
7577
exec += " :" + this.message;
7678
}
77-
this.getClient().sendRawLine(exec);
79+
this.sendCommandLine(exec);
7880
}
7981

8082
@Override

src/main/java/org/kitteh/irc/client/library/command/CapabilityRequestCommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
/**
3636
* Sends a capability request to the server.
3737
*/
38-
public class CapabilityRequestCommand extends Command {
38+
public class CapabilityRequestCommand extends Command<CapabilityRequestCommand> {
3939
private final List<String> requests = new ArrayList<>();
4040

4141
/**
@@ -89,7 +89,7 @@ public synchronized void execute() {
8989
}
9090

9191
private void send(@NonNull String requests) {
92-
this.getClient().sendRawLineImmediately("CAP REQ :" + requests);
92+
this.sendCommandLine("CAP REQ :" + requests, true);
9393
}
9494

9595
@Override

src/main/java/org/kitteh/irc/client/library/command/ChannelCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
/**
3232
* A command only executed on a channel.
3333
*/
34-
public abstract class ChannelCommand extends Command {
34+
public abstract class ChannelCommand<C extends ChannelCommand<C>> extends Command<ChannelCommand<C>> {
3535
private final String channel;
3636

3737
/**

src/main/java/org/kitteh/irc/client/library/command/ChannelModeCommand.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
/**
4444
* Commands a la MODE.
4545
*/
46-
public class ChannelModeCommand extends ChannelCommand {
46+
public class ChannelModeCommand extends ChannelCommand<ChannelModeCommand> {
4747
private static final int PARAMETER_MODES_PER_LINE = 3;
4848

4949
private final List<ModeStatus<ChannelMode>> changes = new ArrayList<>();
@@ -116,7 +116,7 @@ public ChannelModeCommand(@NonNull Client client, @NonNull String channel) {
116116
@Override
117117
public synchronized void execute() {
118118
if (this.changes.isEmpty()) {
119-
this.getClient().sendRawLine("MODE " + this.getChannel());
119+
this.sendCommandLine("MODE " + this.getChannel());
120120
return;
121121
}
122122
int parameterModesPerLine = -1;
@@ -144,7 +144,7 @@ public synchronized void execute() {
144144
}
145145

146146
private void send(@NonNull List<ModeStatus<ChannelMode>> queue) {
147-
this.getClient().sendRawLine("MODE " + this.getChannel() + ' ' + DefaultModeStatusList.of(new ArrayList<>(queue)).getAsString());
147+
this.sendCommandLine("MODE " + this.getChannel() + ' ' + DefaultModeStatusList.of(new ArrayList<>(queue)).getAsString());
148148
queue.clear();
149149
}
150150

src/main/java/org/kitteh/irc/client/library/command/Command.java

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,50 @@
2626
import org.checkerframework.checker.nullness.qual.NonNull;
2727
import org.kitteh.irc.client.library.Client;
2828
import org.kitteh.irc.client.library.element.ClientLinked;
29+
import org.kitteh.irc.client.library.element.MessageTag;
30+
import org.kitteh.irc.client.library.feature.MessageTagManager;
2931
import org.kitteh.irc.client.library.util.Sanity;
3032
import org.kitteh.irc.client.library.util.ToStringer;
3133

34+
import java.util.ArrayList;
35+
import java.util.List;
36+
3237
/**
3338
* Represents a command which is executable on the server by the client.
3439
*/
35-
public abstract class Command implements ClientLinked {
40+
public abstract class Command<C extends Command<C>> implements ClientLinked {
41+
public class Tags {
42+
private List<MessageTag> tags = new ArrayList<>();
43+
44+
public Tags add(@NonNull MessageTag tag) {
45+
this.tags.add(Sanity.nullCheck(tag, "Tag cannot be null"));
46+
return this;
47+
}
48+
49+
public Tags add(@NonNull String name) {
50+
this.tags.add(new MessageTagManager.DefaultMessageTag(Sanity.nullCheck(name, "Name cannot be null"), null));
51+
return this;
52+
}
53+
54+
public Tags add(@NonNull String name, @NonNull String value) {
55+
Sanity.nullCheck(name, "Name cannot be null");
56+
Sanity.nullCheck(value, "Value cannot be null");
57+
this.tags.add(new MessageTagManager.DefaultMessageTag(name, value));
58+
return this;
59+
}
60+
61+
public Tags clear() {
62+
this.tags.clear();
63+
return this;
64+
}
65+
66+
public C then() {
67+
return (C) Command.this;
68+
}
69+
}
70+
3671
private final Client client;
72+
private Tags tags;
3773

3874
/**
3975
* Constructs the command.
@@ -60,6 +96,40 @@ protected Command(@NonNull Client client) {
6096
*/
6197
public abstract void execute();
6298

99+
protected void sendCommandLine(@NonNull String line) {
100+
this.sendCommandLine(line, false);
101+
}
102+
103+
protected void sendCommandLine(@NonNull String line, boolean immediately) {
104+
if (this.tags == null || this.tags.tags.isEmpty()) {
105+
if (immediately) {
106+
this.client.sendRawLineImmediately(line);
107+
} else {
108+
this.client.sendRawLine(line);
109+
}
110+
} else {
111+
StringBuilder builder = new StringBuilder();
112+
builder.append('@');
113+
for (MessageTag tag : this.tags.tags) {
114+
builder.append(tag.getAsString()).append(';');
115+
}
116+
builder.setCharAt(builder.length() - 1, ' ');
117+
builder.append(line);
118+
if (immediately) {
119+
this.client.sendRawLineImmediately(builder.toString());
120+
} else {
121+
this.client.sendRawLine(builder.toString());
122+
}
123+
}
124+
}
125+
126+
public Tags tags() {
127+
if (this.tags == null) {
128+
this.tags = new Tags();
129+
}
130+
return this.tags;
131+
}
132+
63133
@Override
64134
public String toString() {
65135
return this.toStringer().toString();

src/main/java/org/kitteh/irc/client/library/command/KickCommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
/**
3636
* Get your KICKs on Route 66.
3737
*/
38-
public class KickCommand extends ChannelCommand {
38+
public class KickCommand extends ChannelCommand<KickCommand> {
3939
private String target;
4040
private @Nullable String reason;
4141

@@ -101,7 +101,7 @@ public void execute() {
101101
if (this.target == null) {
102102
throw new IllegalStateException("Target not defined");
103103
}
104-
this.getClient().sendRawLine("KICK " + this.getChannel() + ' ' + this.target + (this.reason != null ? (" :" + this.reason) : ""));
104+
this.sendCommandLine("KICK " + this.getChannel() + ' ' + this.target + (this.reason != null ? (" :" + this.reason) : ""));
105105
}
106106

107107
@Override
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* * Copyright (C) 2013-2019 Matt Baxter https://kitteh.org
3+
*
4+
* Permission is hereby granted, free of charge, to any person
5+
* obtaining a copy of this software and associated documentation
6+
* files (the "Software"), to deal in the Software without
7+
* restriction, including without limitation the rights to use, copy,
8+
* modify, merge, publish, distribute, sublicense, and/or sell copies
9+
* of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be
13+
* included in all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package org.kitteh.irc.client.library.command;
25+
26+
import org.checkerframework.checker.nullness.qual.NonNull;
27+
import org.checkerframework.checker.nullness.qual.Nullable;
28+
import org.kitteh.irc.client.library.Client;
29+
import org.kitteh.irc.client.library.element.MessageReceiver;
30+
import org.kitteh.irc.client.library.util.Sanity;
31+
import org.kitteh.irc.client.library.util.ToStringer;
32+
33+
/**
34+
* Sends a message.
35+
*/
36+
// TODO multi-line, cutter
37+
public class MessageCommand extends Command<MessageCommand> {
38+
private String target;
39+
private String message;
40+
41+
/**
42+
* Constructs a message command.
43+
*
44+
* @param client the client on which this command is executing
45+
* @throws IllegalArgumentException if null parameters
46+
*/
47+
public MessageCommand(@NonNull Client client) {
48+
super(client);
49+
}
50+
51+
/**
52+
* Sets the target of this message.
53+
*
54+
* @param target target
55+
* @return this command
56+
* @throws IllegalArgumentException if target is null or contains invalid characters
57+
*/
58+
public @NonNull MessageCommand target(@NonNull String target) {
59+
this.target = Sanity.safeMessageCheck(target, "Target");
60+
return this;
61+
}
62+
63+
public @NonNull MessageCommand target(@NonNull MessageReceiver target) {
64+
this.target = Sanity.nullCheck(target, "Target cannot be null").getMessagingName();
65+
return this;
66+
}
67+
68+
/**
69+
* Sets the message to send.
70+
*
71+
* @param message message
72+
* @return this command
73+
* @throws IllegalArgumentException if message contains invalid characters
74+
*/
75+
public @NonNull MessageCommand message(@Nullable String message) {
76+
this.message = Sanity.safeMessageCheck(message, "Message");
77+
return this;
78+
}
79+
80+
/**
81+
* Executes the command.
82+
*
83+
* @throws IllegalStateException if target or message is not defined
84+
*/
85+
@Override
86+
public void execute() {
87+
if (this.target == null) {
88+
throw new IllegalStateException("Target not defined");
89+
}
90+
if (this.message == null) {
91+
throw new IllegalStateException("Message not defined");
92+
}
93+
this.sendCommandLine("PRIVMSG " + this.target + " :" + this.message);
94+
}
95+
96+
@Override
97+
protected @NonNull ToStringer toStringer() {
98+
return super.toStringer().add("target", this.target).add("message", this.message);
99+
}
100+
}

src/main/java/org/kitteh/irc/client/library/command/MonitorCommand.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
/**
3737
* Sends a MONITOR request to the server.
3838
*/
39-
public class MonitorCommand extends Command {
39+
public class MonitorCommand extends Command<MonitorCommand> {
4040
/**
4141
* Describes an action to take with the MONITOR command.
4242
*/
@@ -164,11 +164,11 @@ public synchronized void execute() {
164164
}
165165

166166
private void monitorCommand(@NonNull Action action) {
167-
this.getClient().sendRawLine("MONITOR " + action.getCharacter());
167+
this.sendCommandLine("MONITOR " + action.getCharacter());
168168
}
169169

170170
private void monitorCommand(@NonNull Action action, @NonNull String targets) {
171-
this.getClient().sendRawLine("MONITOR " + action.getCharacter() + ' ' + targets);
171+
this.sendCommandLine("MONITOR " + action.getCharacter() + ' ' + targets);
172172
}
173173

174174
@Override

0 commit comments

Comments
 (0)