diff --git a/src/network/PacketType.java b/src/network/PacketType.java
index 7cb5b10ea..3a22eb5b5 100644
--- a/src/network/PacketType.java
+++ b/src/network/PacketType.java
@@ -107,6 +107,7 @@ public enum PacketType {
// Chat
CHAT_CREATE_ROOM (ChatCreateRoom.CRC, ChatCreateRoom.class),
+ CHAT_DESTROY_ROOM (ChatDestroyRoom.CRC, ChatDestroyRoom.class),
CHAT_ON_CREATE_ROOM (ChatOnCreateRoom.CRC, ChatOnCreateRoom.class),
CHAT_FRIENDS_LIST_UPDATE (ChatFriendsListUpdate.CRC, ChatFriendsListUpdate.class),
CHAT_IGNORE_LIST (ChatIgnoreList.CRC, ChatIgnoreList.class),
diff --git a/src/network/packets/swg/zone/chat/ChatDestroyRoom.java b/src/network/packets/swg/zone/chat/ChatDestroyRoom.java
new file mode 100644
index 000000000..55d319ea0
--- /dev/null
+++ b/src/network/packets/swg/zone/chat/ChatDestroyRoom.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com
+ *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies.
+ * Our goal is to create an emulator which will provide a server for players to
+ * continue playing a game similar to the one they used to play. We are basing
+ * it on the final publish of the game prior to end-game events.
+ *
+ * This file is part of Holocore.
+ *
+ * --------------------------------------------------------------------------------
+ *
+ * Holocore is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * Holocore is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Holocore. If not, see
+ ******************************************************************************/
+
+package network.packets.swg.zone.chat;
+
+import network.packets.swg.SWGPacket;
+
+import java.nio.ByteBuffer;
+
+/**
+ * @author Waverunner
+ */
+public class ChatDestroyRoom extends SWGPacket {
+ public static final int CRC = getCrc("ChatDestroyRoom");
+
+ private int roomId;
+ private int sequence;
+
+ public ChatDestroyRoom() {}
+
+ @Override
+ public void decode(ByteBuffer data) {
+ if (!super.decode(data, CRC))
+ return;
+ roomId = getInt(data);
+ sequence = getInt(data);
+ }
+
+ @Override
+ public ByteBuffer encode() {
+ ByteBuffer bb = ByteBuffer.allocate(14);
+ addShort(bb, 3);
+ addInt(bb, CRC);
+ addInt(bb, roomId);
+ addInt(bb, sequence);
+ return bb;
+ }
+
+ public int getRoomId() {
+ return roomId;
+ }
+
+ public int getSequence() {
+ return sequence;
+ }
+
+ @Override
+ public String toString() {
+ return "ChatDestroyRoom[roomId=" + roomId + ", sequence=" + sequence + "]";
+ }
+}
diff --git a/src/resources/chat/ChatResult.java b/src/resources/chat/ChatResult.java
index d689fd718..5d2464686 100644
--- a/src/resources/chat/ChatResult.java
+++ b/src/resources/chat/ChatResult.java
@@ -38,7 +38,7 @@ public enum ChatResult {
ROOM_INVALID_NAME(6),
ROOM_NOT_MODERATOR(9),
ROOM_AVATAR_BANNED(12),
- ROOM_AVATAR_NOT_INVITED(16),
+ ROOM_AVATAR_NO_PERMISSION(16),
IGNORED(23),
ROOM_ALREADY_EXISTS(24),
ROOM_ALREADY_JOINED(36),
diff --git a/src/resources/chat/ChatRoom.java b/src/resources/chat/ChatRoom.java
index 897ec6961..74cccf4c4 100644
--- a/src/resources/chat/ChatRoom.java
+++ b/src/resources/chat/ChatRoom.java
@@ -163,7 +163,7 @@ public class ChatRoom implements Encodable, Serializable {
if (isPublic() || invited.contains(avatar))
return ChatResult.SUCCESS;
- return ChatResult.ROOM_AVATAR_NOT_INVITED;
+ return ChatResult.ROOM_AVATAR_NO_PERMISSION;
}
public ChatResult canSendMessage(ChatAvatar avatar) {
diff --git a/src/resources/common/CRC.java b/src/resources/common/CRC.java
index bef7a256f..31631849e 100644
--- a/src/resources/common/CRC.java
+++ b/src/resources/common/CRC.java
@@ -129,7 +129,7 @@ public class CRC {
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
-
+
public static int getCrc(String input) {
byte [] bytes = input.getBytes();
int crc = 0xffffffff;
diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java
index e24fbb0ed..e3fd1b828 100644
--- a/src/resources/objects/player/PlayerObject.java
+++ b/src/resources/objects/player/PlayerObject.java
@@ -395,13 +395,19 @@ public class PlayerObject extends IntangibleObject {
public boolean addJoinedChannel(String path) {
synchronized (joinedChannels) {
- return !joinedChannels.contains(path) && joinedChannels.add(path);
+ return true;
+ // TODO: Refactor
+ /*System.out.println("add joined channel: " + path);
+ return !joinedChannels.contains(path) && joinedChannels.add(path);*/
}
}
public boolean removeJoinedChannel(String path) {
synchronized (joinedChannels) {
- return joinedChannels.remove(path);
+ return true;
+ // TODO: Refactor
+ /*System.out.println("remove joined channel: " + path);
+ return joinedChannels.remove(path);*/
}
}
diff --git a/src/services/chat/ChatRoomService.java b/src/services/chat/ChatRoomService.java
index bb4332127..d99b9f143 100644
--- a/src/services/chat/ChatRoomService.java
+++ b/src/services/chat/ChatRoomService.java
@@ -27,11 +27,13 @@
package services.chat;
+import intents.NotifyPlayersPacketIntent;
import intents.chat.ChatRoomUpdateIntent;
import intents.network.GalacticPacketIntent;
import network.packets.Packet;
import network.packets.swg.SWGPacket;
import network.packets.swg.zone.chat.ChatCreateRoom;
+import network.packets.swg.zone.chat.ChatDestroyRoom;
import network.packets.swg.zone.chat.ChatEnterRoomById;
import network.packets.swg.zone.chat.ChatOnCreateRoom;
import network.packets.swg.zone.chat.ChatOnDestroyRoom;
@@ -57,6 +59,7 @@ import services.player.PlayerManager;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -136,6 +139,9 @@ public class ChatRoomService extends Service {
case CHAT_CREATE_ROOM:
if (p instanceof ChatCreateRoom) handleChatCreateRoom(player, (ChatCreateRoom) p);
break;
+ case CHAT_DESTROY_ROOM:
+ if (p instanceof ChatDestroyRoom) handleChatDestroyRoom(player, (ChatDestroyRoom) p);
+ break;
default: break;
}
}
@@ -143,12 +149,27 @@ public class ChatRoomService extends Service {
private void processChatRoomUpdateIntent(ChatRoomUpdateIntent i) {
switch(i.getUpdateType()) {
case CREATE: createRoom(i.getAvatar(), i.isPublic(), i.getPath(), i.getTitle()); break;
+ case DESTROY: notifyDestroyRoom(i.getAvatar(), i.getPath(), 0); break;
default: break;
}
}
/* Chat Rooms */
+ private void handleChatDestroyRoom(Player player, ChatDestroyRoom p) {
+ ChatRoom room = roomMap.get(p.getRoomId());
+ ChatAvatar avatar = ChatAvatar.getFromPlayer(player);
+
+ if ((room == null || !room.getCreator().equals(avatar) || !room.getOwner().equals(avatar))) {
+ player.sendPacket(new ChatOnDestroyRoom(ChatAvatar.getFromPlayer(player), ChatResult.ROOM_AVATAR_NO_PERMISSION.getCode(), p.getRoomId(), p.getSequence()));
+ return;
+ }
+
+ if (!notifyDestroyRoom(avatar, room.getPath(), p.getSequence())) {
+ player.sendPacket(new ChatOnDestroyRoom(ChatAvatar.getFromPlayer(player), ChatResult.NONE.getCode(), p.getRoomId(), p.getSequence()));
+ }
+ }
+
private void handleChatCreateRoom(Player player, ChatCreateRoom p) {
String path = p.getRoomName();
String title = p.getRoomTitle();
@@ -282,8 +303,8 @@ public class ChatRoomService extends Service {
// Re-send the player the room list with just this room as it could have been private/hidden
// This also "refreshes" the client, not sending this will cause a Chat channel unavailable message.
- ChatRoomList roomList = new ChatRoomList(room);
- player.sendPacket(roomList);
+ if (!room.isPublic())
+ player.sendPacket(new ChatRoomList(room));
// Notify players of success, it's ChatResult.SUCCESS at this point
player.sendPacket(new ChatOnEnteredRoom(avatar, result.getCode(), room.getId(), sequence));
@@ -382,6 +403,32 @@ public class ChatRoomService extends Service {
return room;
}
+ public boolean notifyDestroyRoom(ChatAvatar destroyer, String roomPath, int sequence) {
+ ChatRoom room = getRoom(roomPath);
+ if (roomPath == null)
+ return false;
+
+ if (!destroyRoom(room))
+ return false;
+
+ // Send the ChatOnDestroyRoom packet to every else in the room besides the person destroying the packet
+ List networkIds = new ArrayList<>();
+ room.getMembers().forEach(member -> {
+ if (!destroyer.equals(member))
+ networkIds.add(member.getNetworkId());
+ });
+
+ new NotifyPlayersPacketIntent(new ChatOnDestroyRoom(destroyer, ChatResult.SUCCESS.getCode(), room.getId(), 0),
+ networkIds).broadcast();
+
+ if (!destroyer.equals(ChatAvatar.getSystemAvatar(destroyer.getGalaxy()))) {
+ new NotifyPlayersPacketIntent(new ChatOnDestroyRoom(destroyer, ChatResult.SUCCESS.getCode(), room.getId(), sequence),
+ Collections.singletonList(destroyer.getNetworkId())).broadcast();
+ }
+
+ return true;
+ }
+
public boolean destroyRoom(ChatRoom room) {
return room != null && roomMap.remove(room.getId()) != null;
}