Skip to content

Commit b6a4a41

Browse files
committed
Added support for PMs.
1 parent cc27b52 commit b6a4a41

File tree

4 files changed

+120
-14
lines changed

4 files changed

+120
-14
lines changed

src/bitbot/ChatServer.java

Lines changed: 95 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,37 @@
11
package bitbot;
22

3-
import java.util.ArrayList;
4-
import java.util.List;
3+
import java.util.HashMap;
4+
import java.util.Map;
55

6+
import org.jivesoftware.smack.Chat;
7+
import org.jivesoftware.smack.ChatManagerListener;
68
import org.jivesoftware.smack.Connection;
9+
import org.jivesoftware.smack.MessageListener;
710
import org.jivesoftware.smack.PacketListener;
811
import org.jivesoftware.smack.SmackConfiguration;
912
import org.jivesoftware.smack.XMPPConnection;
1013
import org.jivesoftware.smack.XMPPException;
1114
import org.jivesoftware.smack.packet.Message;
1215
import org.jivesoftware.smack.packet.Packet;
16+
import org.jivesoftware.smack.util.StringUtils;
1317
import org.jivesoftware.smackx.muc.DiscussionHistory;
1418
import org.jivesoftware.smackx.muc.MultiUserChat;
1519
import org.jivesoftware.smackx.muc.Occupant;
1620

1721

1822
public class ChatServer {
1923

20-
private final List<Room> rooms = new ArrayList<Room>();
24+
private final Map<String, Room> rooms = new HashMap<String, Room>();
2125
private final ChatServerConfig config;
2226
private final MessageHandler messageHandler;
27+
private final PrivateChats privateChats;
2328

2429
private Connection connection;
2530

2631
public ChatServer(ChatServerConfig config, MessageHandler messageHandler) {
2732
this.config = config;
2833
this.messageHandler = messageHandler;
34+
privateChats = new PrivateChats();
2935
}
3036

3137
public void connect() {
@@ -35,6 +41,7 @@ public void connect() {
3541
System.out.println("Connected to " + connection.getServiceName());
3642
connection.login(config.getUsername(), config.getPassword(), config.getResource());
3743
System.out.println("Logged in as " + connection.getUser());
44+
connection.getChatManager().addChatListener(new ChatHandler());
3845
} catch (XMPPException e) {
3946
System.out.println("Failed to connect to " + config.getServer() + ": " + e);
4047
}
@@ -47,13 +54,32 @@ public void disconnect() {
4754

4855
public void joinRoom(RoomConfig roomConfig) {
4956
try {
50-
rooms.add(new Room(roomConfig));
57+
rooms.put(roomConfig.getRoom(), new Room(roomConfig));
5158
} catch (XMPPException e) {
5259
System.out.println("Failed to join " + roomConfig.getRoom() + ": " + e);
5360
}
5461
}
5562

56-
private class Room implements PacketListener {
63+
private final class ChatHandler implements ChatManagerListener {
64+
65+
@Override
66+
public void chatCreated(Chat chat, boolean createdLocally) {
67+
if (!createdLocally) {
68+
Room room = rooms.get(StringUtils.parseBareAddress(chat.getParticipant()));
69+
if (room != null) {
70+
System.out.println("New room private chat by " + chat.getParticipant());
71+
chat.addMessageListener(room);
72+
} else {
73+
System.out.println("New private chat by " + chat.getParticipant());
74+
chat.addMessageListener(privateChats);
75+
}
76+
} else {
77+
System.out.println("Ignore chat created locally: " + chat.getParticipant());
78+
}
79+
}
80+
}
81+
82+
private class Room implements PacketListener, MessageListener {
5783

5884
private MultiUserChat muc;
5985

@@ -77,19 +103,29 @@ public void processPacket(Packet packet) {
77103
} else if (occupant.getNick().equals(muc.getNickname())) {
78104
System.out.println("Ignoring own message");
79105
}
80-
messageHandler.processMessage(msg.getBody(), new User(occupant), false, new RoomReplier(muc, msg.getFrom()));
106+
messageHandler.processMessage(msg.getBody(), User.fromOccupant(occupant), false, new RoomReplier(this, muc, msg.getFrom()));
81107
} else {
82108
System.out.println("Unhandled packet type from room: " + packet.getClass());
83109
}
84110
}
111+
112+
@Override
113+
public void processMessage(Chat chat, Message msg) {
114+
System.out.println("Room PM: " + chat.getParticipant() + ": " + msg.getBody());
115+
messageHandler.processMessage(msg.getBody(), User.fromRoomJID(chat.getParticipant()), true, new PrivateReplier(chat));
116+
}
85117
}
86118

87-
private static class RoomReplier implements Replier {
119+
private class RoomReplier implements Replier {
88120

121+
private final Room room;
89122
private final MultiUserChat muc;
90123
private final String user;
91124

92-
public RoomReplier(MultiUserChat muc, String user) {
125+
private Chat chat;
126+
127+
public RoomReplier(Room room, MultiUserChat muc, String user) {
128+
this.room = room;
93129
this.muc = muc;
94130
this.user = user;
95131
}
@@ -103,6 +139,57 @@ public void reply(String text) {
103139
}
104140
}
105141

142+
@Override
143+
public void replyPrivately(String text) {
144+
try {
145+
if (chat == null) {
146+
System.out.println("Starting private chat with " + user);
147+
chat = muc.createPrivateChat(user, room);
148+
}
149+
System.out.println("Sending to " + chat.getParticipant() + ": " + text);
150+
chat.sendMessage(text);
151+
} catch (XMPPException e) {
152+
System.out.println("Failed to send message to occupant " + chat.getParticipant() + ": " + e);
153+
}
154+
}
155+
156+
}
157+
158+
private class PrivateChats implements MessageListener {
159+
160+
public PrivateChats() {
161+
}
162+
163+
@Override
164+
public void processMessage(Chat chat, Message msg) {
165+
System.out.println("PM: " + chat.getParticipant() + ": " + msg.getBody());
166+
messageHandler.processMessage(msg.getBody(), User.fromRealJID(chat.getParticipant()), true, new PrivateReplier(chat));
167+
}
168+
}
169+
170+
private class PrivateReplier implements Replier {
171+
172+
private final Chat chat;
173+
174+
public PrivateReplier(Chat chat) {
175+
this.chat = chat;
176+
}
177+
178+
@Override
179+
public void reply(String text) {
180+
try {
181+
System.out.println("PM to " + chat.getParticipant() + ": " + text);
182+
chat.sendMessage(text);
183+
} catch (XMPPException e) {
184+
System.out.println("Failed to set PM to " + chat.getParticipant() + ": " + e);
185+
}
186+
}
187+
188+
@Override
189+
public void replyPrivately(String text) {
190+
reply(text);
191+
}
192+
106193
}
107194

108195
}

src/bitbot/MessageHandler.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@ public void processMessage(String text, User user, boolean pm, Replier replier)
1515
if (text.charAt(0) == commandPrefix) {
1616
text = text.substring(1);
1717
}
18-
String[] parts = text.split("\\s", 1);
18+
String[] parts = text.split("\\s", 2);
1919
String cmd = parts[0];
20-
String args = parts.length == 1 ? null : parts[1];
20+
String args = parts.length == 1 ? "" : parts[1];
2121
if (cmd.equalsIgnoreCase("hej")) {
2222
replier.reply("Hej, " + user.getNick());
23+
} else if (cmd.equalsIgnoreCase("test")) {
24+
for (String s : args.split("\\s")) {
25+
replier.replyPrivately(s);
26+
}
2327
}
2428
}
2529
}

src/bitbot/Replier.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ public interface Replier {
55

66
void reply(String text);
77

8+
void replyPrivately(String text);
9+
810
}

src/bitbot/User.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,31 @@
11
package bitbot;
22

3+
import org.jivesoftware.smack.util.StringUtils;
34
import org.jivesoftware.smackx.muc.Occupant;
45

56

67
public class User {
78

8-
private final Occupant occupant;
9+
static User fromOccupant(Occupant occupant) {
10+
return new User(occupant.getNick());
11+
}
12+
13+
static User fromRealJID(String jid) {
14+
return new User(StringUtils.parseName(jid));
15+
}
16+
17+
static User fromRoomJID(String jid) {
18+
return new User(StringUtils.parseResource(jid));
19+
}
20+
21+
private final String nick;
922

10-
public User(Occupant occupant) {
11-
this.occupant = occupant;
23+
private User(String nick) {
24+
this.nick = nick;
1225
}
1326

1427
public String getNick() {
15-
return occupant.getNick();
28+
return nick;
1629
}
1730

1831
}

0 commit comments

Comments
 (0)