mirror of
https://github.com/ProjectSWGCore/Holocore.git
synced 2026-10-04 19:13:19 -04:00
Changed ChatService to a manager and moved chat room functionality to ChatRoomService under ChatManager
NotifyPlayersPacketIntent can now accept a list of networkId's to notify players with a packet
This commit is contained in:
@@ -32,19 +32,35 @@ import resources.Terrain;
|
||||
import resources.control.Intent;
|
||||
import resources.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NotifyPlayersPacketIntent extends Intent {
|
||||
|
||||
public static final String TYPE = "GalaxyWidePacketIntent";
|
||||
|
||||
private Packet packet;
|
||||
private Terrain terrain;
|
||||
private List<Long> networkIds;
|
||||
private ConditionalNotify condition;
|
||||
|
||||
public NotifyPlayersPacketIntent(Packet packet, Terrain terrain, ConditionalNotify condition) {
|
||||
|
||||
public NotifyPlayersPacketIntent(Packet packet, Terrain terrain, ConditionalNotify condition, List<Long> networkIds) {
|
||||
super(TYPE);
|
||||
this.packet = packet;
|
||||
this.terrain = terrain;
|
||||
this.condition = condition;
|
||||
this.networkIds = networkIds;
|
||||
}
|
||||
|
||||
public NotifyPlayersPacketIntent(Packet packet, Terrain terrain, ConditionalNotify condition) {
|
||||
this(packet, terrain, condition, null);
|
||||
}
|
||||
|
||||
public NotifyPlayersPacketIntent(Packet packet, ConditionalNotify condition, List<Long> networkIds) {
|
||||
this(packet, null, condition, networkIds);
|
||||
}
|
||||
|
||||
public NotifyPlayersPacketIntent(Packet packet, List<Long> networkIds) {
|
||||
this(packet, null, null, networkIds);
|
||||
}
|
||||
|
||||
public NotifyPlayersPacketIntent(Packet packet, Terrain terrain) {
|
||||
@@ -52,12 +68,13 @@ public class NotifyPlayersPacketIntent extends Intent {
|
||||
}
|
||||
|
||||
public NotifyPlayersPacketIntent(Packet p) {
|
||||
this(p, null, null);
|
||||
this(p, null, null, null);
|
||||
}
|
||||
|
||||
public Packet getPacket() { return packet; }
|
||||
public Terrain getTerrain() { return terrain; }
|
||||
public ConditionalNotify getCondition() { return condition; }
|
||||
public List<Long> getNetworkIds() { return networkIds; }
|
||||
|
||||
public interface ConditionalNotify {
|
||||
boolean meetsCondition(Player player);
|
||||
|
||||
@@ -50,6 +50,7 @@ import resources.chat.ChatResult;
|
||||
import resources.chat.ChatRoom;
|
||||
import resources.collections.SWGList;
|
||||
import resources.control.Intent;
|
||||
import resources.control.Manager;
|
||||
import resources.control.Service;
|
||||
import resources.encodables.OutOfBandPackage;
|
||||
import resources.encodables.ProsePackage;
|
||||
@@ -74,26 +75,18 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ChatService extends Service {
|
||||
public class ChatManager extends Manager {
|
||||
|
||||
// Array of only the valid terrains in relation to zones able to use planetary-based chat
|
||||
private static final List<Terrain> terrains = Arrays.asList(
|
||||
Terrain.CORELLIA, Terrain.DANTOOINE, Terrain.DATHOMIR, Terrain.ENDOR, Terrain.KASHYYYK, Terrain.LOK,
|
||||
Terrain.MUSTAFAR, Terrain.NABOO, Terrain.RORI, Terrain.TATOOINE, Terrain.TALUS, Terrain.YAVIN4
|
||||
);
|
||||
private ObjectDatabase<Mail> mails;
|
||||
private int maxMailId;
|
||||
private int maxChatRoomId;
|
||||
private Map<Integer, ChatRoom> roomMap;
|
||||
// Map to keep track of each player's recent message for a room to prevent duplicates from client
|
||||
private Map<Long, Map<Integer, Integer>> messages;
|
||||
private ChatRoomService roomService;
|
||||
|
||||
public ChatService() {
|
||||
roomMap = new HashMap<>();
|
||||
public ChatManager() {
|
||||
roomService = new ChatRoomService();
|
||||
mails = new CachedObjectDatabase<>("odb/mails.db");
|
||||
maxMailId = 1;
|
||||
maxChatRoomId = 1;
|
||||
messages = new ConcurrentHashMap<>();
|
||||
|
||||
addChildService(roomService);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,14 +99,11 @@ public class ChatService extends Service {
|
||||
registerForIntent(ServerStatusIntent.TYPE);
|
||||
registerForIntent(ChatAvatarRequestIntent.TYPE);
|
||||
registerForIntent(ZonePlayerSwapIntent.TYPE);
|
||||
registerForIntent(ChatRoomUpdateIntent.TYPE);
|
||||
|
||||
mails.load();
|
||||
mails.traverse(new Traverser<Mail>() {
|
||||
@Override
|
||||
public void process(Mail mail) {
|
||||
if (mail.getId() >= maxMailId)
|
||||
maxMailId = mail.getId() + 1;
|
||||
}
|
||||
mails.traverse(mail -> {
|
||||
if (mail.getId() >= maxMailId)
|
||||
maxMailId = mail.getId() + 1;
|
||||
});
|
||||
return super.initialize();
|
||||
}
|
||||
@@ -150,17 +140,6 @@ public class ChatService extends Service {
|
||||
if (i instanceof ChatAvatarRequestIntent)
|
||||
handleChatAvatarStatusRequestIntent((ChatAvatarRequestIntent) i);
|
||||
break;
|
||||
case ChatRoomUpdateIntent.TYPE:
|
||||
if (i instanceof ChatRoomUpdateIntent)
|
||||
handleChatRoomUpdateIntent((ChatRoomUpdateIntent) i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleChatRoomUpdateIntent(ChatRoomUpdateIntent i) {
|
||||
switch(i.getUpdateType()) {
|
||||
case CREATE: createRoom(i.getAvatar(), i.isPublic(), i.getPath(), i.getTitle());
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,35 +155,6 @@ public class ChatService extends Service {
|
||||
|
||||
private void processSwgPacket(PlayerManager pm, Player player, String galaxyName, SWGPacket p) {
|
||||
switch (p.getPacketType()) {
|
||||
/* Chat Rooms */
|
||||
case CHAT_QUERY_ROOM:
|
||||
if (p instanceof ChatQueryRoom)
|
||||
handleChatQueryRoom(player, (ChatQueryRoom) p);
|
||||
break;
|
||||
case CHAT_ENTER_ROOM_BY_ID:
|
||||
if (!(p instanceof ChatEnterRoomById))
|
||||
return;
|
||||
{
|
||||
ChatEnterRoomById enterRoomById = (ChatEnterRoomById) p;
|
||||
enterChatChannel(player, enterRoomById.getRoomId(), enterRoomById.getSequence());
|
||||
}
|
||||
break;
|
||||
case CHAT_REMOVE_AVATAR_FROM_ROOM:
|
||||
if (p instanceof ChatRemoveAvatarFromRoom)
|
||||
leaveChatChannel(player, ((ChatRemoveAvatarFromRoom) p).getPath());
|
||||
break;
|
||||
case CHAT_SEND_TO_ROOM:
|
||||
if (p instanceof ChatSendToRoom)
|
||||
handleChatSendToRoom(player, (ChatSendToRoom) p);
|
||||
break;
|
||||
case CHAT_REQUEST_ROOM_LIST:
|
||||
if (p instanceof ChatRequestRoomList)
|
||||
handleChatRoomListRequest(player);
|
||||
break;
|
||||
case CHAT_CREATE_ROOM:
|
||||
if (p instanceof ChatCreateRoom)
|
||||
handleChatCreateRoom(player, (ChatCreateRoom) p);
|
||||
break;
|
||||
/* Mails */
|
||||
case CHAT_PERSISTENT_MESSAGE_TO_SERVER:
|
||||
if (p instanceof ChatPersistentMessageToServer)
|
||||
@@ -235,12 +185,13 @@ public class ChatService extends Service {
|
||||
|
||||
switch (intent.getEvent()) {
|
||||
case PE_ZONE_IN:
|
||||
switchPlanetaryChatChannels(player);
|
||||
roomService.enterPlanetaryChatChannels(player);
|
||||
break;
|
||||
case PE_FIRST_ZONE:
|
||||
sendPersistentMessageHeaders(player, intent.getGalaxy());
|
||||
updateChatAvatarStatus(player, intent.getGalaxy(), true);
|
||||
enterJoinedChatChannels(player);
|
||||
if (player.getPlayerObject() != null)
|
||||
roomService.enterChatChannels(player, player.getPlayerObject().getJoinedChannels());
|
||||
break;
|
||||
case PE_LOGGED_OUT:
|
||||
if (player.getCreatureObject() == null)
|
||||
@@ -289,313 +240,8 @@ public class ChatService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
/* Chat Rooms */
|
||||
|
||||
private void handleChatCreateRoom(Player player, ChatCreateRoom p) {
|
||||
String path = p.getRoomName();
|
||||
String title = p.getRoomTitle();
|
||||
ChatRoom room = getRoom(path);
|
||||
|
||||
ChatResult result = ChatResult.SUCCESS;
|
||||
if (room != null)
|
||||
result = ChatResult.ROOM_ALREADY_EXISTS;
|
||||
|
||||
if (result == ChatResult.SUCCESS) {
|
||||
room = createRoom(ChatAvatar.getFromPlayer(player), p.isPublic(), path, title);
|
||||
room.setMuted(p.isModerated());
|
||||
}
|
||||
|
||||
player.sendPacket(new ChatOnCreateRoom(result.getCode(), room, p.getSequence()));
|
||||
}
|
||||
|
||||
private void handleChatSendToRoom(Player player, ChatSendToRoom p) {
|
||||
ChatResult result = ChatResult.SUCCESS;
|
||||
|
||||
ChatRoom room = getRoom(p.getRoomId());
|
||||
if (room == null)
|
||||
result = ChatResult.ROOM_INVALID_ID;
|
||||
|
||||
if (result != ChatResult.SUCCESS) {
|
||||
player.sendPacket(new ChatOnSendRoomMessage(result.getCode(), p.getSequence()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!incrementMessageCounter(player.getNetworkId(), room.getId(), p.getSequence()))
|
||||
return;
|
||||
|
||||
ChatAvatar avatar = ChatAvatar.getFromPlayer(player);
|
||||
|
||||
result = room.canSendMessage(avatar);
|
||||
|
||||
// TODO: Check length of messages -- Result 16 is used for too long message
|
||||
|
||||
player.sendPacket(new ChatOnSendRoomMessage(result.getCode(), p.getSequence()));
|
||||
|
||||
if (result == ChatResult.SUCCESS)
|
||||
room.sendMessage(avatar, p.getMessage(), p.getOutOfBandPackage(), player.getPlayerManager());
|
||||
}
|
||||
|
||||
private void handleChatQueryRoom(Player player, ChatQueryRoom p) {
|
||||
ChatRoom room = getRoom(p.getRoomPath()); // No result code is sent for queries
|
||||
if (room == null)
|
||||
return;
|
||||
|
||||
player.sendPacket(new ChatQueryRoomResults(room, p.getSequence()));
|
||||
}
|
||||
|
||||
private void handleChatRoomListRequest(Player player) {
|
||||
ChatAvatar avatar = ChatAvatar.getFromPlayer(player);
|
||||
|
||||
List<ChatRoom> rooms = new ArrayList<>();
|
||||
for (ChatRoom chatRoom : roomMap.values()) {
|
||||
if (!chatRoom.isPublic() && !chatRoom.getInvited().contains(avatar) && !chatRoom.getOwner().equals(avatar))
|
||||
continue;
|
||||
rooms.add(chatRoom);
|
||||
}
|
||||
|
||||
ChatRoomList response = new ChatRoomList(rooms);
|
||||
player.sendPacket(response);
|
||||
}
|
||||
|
||||
private void sendOnEnteredChatRoom(Player player, ChatAvatar avatar, ChatResult result, int id, int sequence) {
|
||||
ChatOnEnteredRoom onEnteredRoom = new ChatOnEnteredRoom(avatar, id, sequence);
|
||||
onEnteredRoom.setResult(result.getCode());
|
||||
player.sendPacket(onEnteredRoom);
|
||||
}
|
||||
|
||||
private void enterJoinedChatChannels(Player player) {
|
||||
PlayerObject ghost = player.getPlayerObject();
|
||||
if (ghost == null)
|
||||
return;
|
||||
|
||||
for (String s : ghost.getJoinedChannels()) {
|
||||
enterChatChannel(player, s);
|
||||
}
|
||||
}
|
||||
|
||||
private void switchPlanetaryChatChannels(Player player) {
|
||||
PlayerObject ghost = player.getPlayerObject();
|
||||
if (ghost == null)
|
||||
return;
|
||||
|
||||
// Leave old zone-only chat channels
|
||||
String planetEndPath = ".Planet";
|
||||
for (String channel : ghost.getJoinedChannels()) {
|
||||
if (channel.endsWith(planetEndPath)) {
|
||||
leaveChatChannel(player, channel);
|
||||
} else {
|
||||
// Better way of doing this?
|
||||
String[] split = channel.split("\\.");
|
||||
if (split.length == 3 && split[2].equals("system"))
|
||||
leaveChatChannel(player, channel);
|
||||
}
|
||||
}
|
||||
|
||||
Terrain terrain = player.getCreatureObject().getLocation().getTerrain();
|
||||
|
||||
// Enter the new zone-only chat channels
|
||||
if (!terrains.contains(terrain))
|
||||
return;
|
||||
|
||||
String planetPath = "SWG." + player.getGalaxyName() + "." + terrain.getNameCapitalized() + ".";
|
||||
enterChatChannel(player, planetPath + "Planet");
|
||||
enterChatChannel(player, planetPath + "system");
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to join the specified chat channel
|
||||
* @param player Player joining the chat channel
|
||||
* @param room Chat room to enter
|
||||
*/
|
||||
public void enterChatChannel(Player player, ChatRoom room, int sequence) {
|
||||
ChatAvatar avatar = ChatAvatar.getFromPlayer(player);
|
||||
|
||||
PlayerObject ghost = player.getPlayerObject();
|
||||
if (ghost == null) {
|
||||
sendOnEnteredChatRoom(player, avatar, ChatResult.NONE, room.getId(), sequence);
|
||||
return;
|
||||
}
|
||||
|
||||
ChatResult result = room.canJoinRoom(avatar);
|
||||
if (result != ChatResult.SUCCESS && player.getAccessLevel() != AccessLevel.PLAYER) {
|
||||
sendOnEnteredChatRoom(player, avatar, result, room.getId(), sequence);
|
||||
return;
|
||||
}
|
||||
// TODO: Check if player is appropriate faction for the room (Rebel and imperial chat rooms)
|
||||
|
||||
// Server-based list so we can join chat channels automatically
|
||||
ghost.addJoinedChannel(room.getPath());
|
||||
|
||||
// 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);
|
||||
|
||||
// Notify players of success, it's ChatResult.SUCCESS at this point
|
||||
player.sendPacket(new ChatOnEnteredRoom(avatar, result.getCode(), room.getId(), sequence));
|
||||
|
||||
PlayerManager manager = player.getPlayerManager();
|
||||
// Notify everyone that a player entered the room
|
||||
room.sendPacketToMembers(manager, new ChatOnEnteredRoom(avatar, result.getCode(), room.getId(), 0));
|
||||
|
||||
room.getMembers().add(avatar);
|
||||
}
|
||||
|
||||
public void enterChatChannel(Player player, int id, int sequence) {
|
||||
ChatRoom room = getRoom(id);
|
||||
if (room == null) {
|
||||
sendOnEnteredChatRoom(player, ChatAvatar.getFromPlayer(player), ChatResult.NONE, id, sequence);
|
||||
return;
|
||||
}
|
||||
enterChatChannel(player, room, sequence);
|
||||
}
|
||||
|
||||
public void enterChatChannel(Player player, String path) {
|
||||
for (ChatRoom room : roomMap.values()) {
|
||||
if (room.getPath().equals(path)) {
|
||||
enterChatChannel(player, room, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
System.err.println("Tried to join a room with a path that does not exist: " + path);
|
||||
}
|
||||
|
||||
public void leaveChatChannel(Player player, ChatRoom room, int sequence) {
|
||||
ChatAvatar avatar = ChatAvatar.getFromPlayer(player);
|
||||
|
||||
PlayerObject ghost = player.getPlayerObject();
|
||||
if (ghost == null)
|
||||
return; // ChatOnLeaveRoom doesn't do anything other than for a ChatResult.SUCCESS, so no need to send a fail
|
||||
|
||||
if (!room.getMembers().remove(avatar) && !ghost.removeJoinedChannel(room.getPath()))
|
||||
return;
|
||||
|
||||
player.sendPacket(new ChatOnLeaveRoom(avatar, ChatResult.SUCCESS.getCode(), room.getId(), sequence));
|
||||
|
||||
room.sendPacketToMembers(player.getPlayerManager(), new ChatOnLeaveRoom(avatar, ChatResult.SUCCESS.getCode(), room.getId(), 0));
|
||||
}
|
||||
|
||||
public void leaveChatChannel(Player player, String path) {
|
||||
for (ChatRoom chatRoom : roomMap.values()) {
|
||||
if (chatRoom.getPath().equals(path))
|
||||
leaveChatChannel(player, chatRoom, 0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a new, non-persistent, chat room with the specified address path.
|
||||
* @param creator Room creator who will also become the owner of this room
|
||||
* @param isPublic Determines if the room should be publicly displayed in the channel listing
|
||||
* @param path Address for the channel (Ex: SWG.serverName.Imperial)
|
||||
* @param title Descriptive name of the chat channel (Ex: Imperial chat for this galaxy)
|
||||
* @return {@link ChatRoom}
|
||||
*/
|
||||
public ChatRoom createRoom(ChatAvatar creator, boolean isPublic, String path, String title) {
|
||||
if (path.isEmpty() || path.endsWith("."))
|
||||
return null;
|
||||
|
||||
String base = "SWG." + creator.getGalaxy();
|
||||
if (!path.startsWith(base) || path.equals(base))
|
||||
return null;
|
||||
|
||||
// All paths should have parents, lets validate to make sure they exist first. Create them if they don't.
|
||||
int lastIndex = path.lastIndexOf(".");
|
||||
if (lastIndex != -1) {
|
||||
String parentPath = path.substring(0, lastIndex);
|
||||
if (getRoom(parentPath) == null) {
|
||||
createRoom(creator, isPublic, parentPath, "");
|
||||
}
|
||||
}
|
||||
|
||||
ChatRoom room = new ChatRoom();
|
||||
int id = maxChatRoomId;
|
||||
maxChatRoomId++;
|
||||
|
||||
room.setId(id);
|
||||
room.setOwner(creator);
|
||||
room.setCreator(creator);
|
||||
room.setIsPublic(isPublic);
|
||||
room.setPath(path);
|
||||
room.setTitle(title);
|
||||
|
||||
roomMap.put(id, room);
|
||||
return room;
|
||||
}
|
||||
|
||||
private void createSystemChannels(String galaxy) {
|
||||
ChatAvatar systemAvatar = ChatAvatar.getSystemAvatar(galaxy);
|
||||
// TODO: Move these to a Server Data File?
|
||||
String basePath = "SWG." + galaxy + ".";
|
||||
createRoom(systemAvatar, true, basePath + "Galaxy", "public chat for the whole galaxy, cannot create rooms here");
|
||||
createRoom(systemAvatar, true, basePath + "system", "system messages for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Chat", "public chat for this galaxy, can create rooms here");
|
||||
createRoom(systemAvatar, true, basePath + "Imperial", "Imperial chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "ImperialWarRoom", "Imperial war room chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Rebel", "Rebel chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "RebelWarRoom", "Rebel war room chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "BountyHunter", "Bounty Hunter chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Commando", "Commando chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Entertainer", "Entertainer chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "ForceSensitive", "Force Sensitive chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Medic", "Medic chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Officer", "Officer chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Pilot", "Pilot chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Politician", "Politician chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Smuggler", "Smuggler chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Spy", "Spy chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Trader", "Trader chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "BeastMastery", "Beast Mastery chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Auction", "Auction chat for this galaxy");
|
||||
createPlanetChannels(systemAvatar, basePath);
|
||||
}
|
||||
|
||||
private void createPlanetChannels(ChatAvatar systemAvatar, String basePath) {
|
||||
for (Terrain terrain : terrains) {
|
||||
String path = basePath + terrain.getNameCapitalized() + ".";
|
||||
createRoom(systemAvatar, true, path + "Planet", "public chat for this planet, cannot create rooms here");
|
||||
createRoom(systemAvatar, true, path + "system", "system messages for this planet, cannot create rooms here");
|
||||
createRoom(systemAvatar, true, path + "Chat", "public chat for this planet, can create rooms here");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean incrementMessageCounter(long networkId, int roomId, int messageId) {
|
||||
if (networkId == -1) // System ChatAvatar uses -1 for networkId
|
||||
return true;
|
||||
|
||||
Map<Integer, Integer> messageHistory = messages.get(networkId);
|
||||
if (messageHistory != null) {
|
||||
if (messageHistory.containsKey(roomId) && messageHistory.get(roomId) == messageId)
|
||||
return false;
|
||||
} else {
|
||||
messageHistory = new HashMap<>();
|
||||
messages.put(networkId, messageHistory);
|
||||
}
|
||||
messageHistory.put(roomId, messageId);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void initializeGalaxyChannels(Galaxy galaxy) {
|
||||
createSystemChannels(galaxy.getName());
|
||||
// TODO: Load up persistent channels
|
||||
/** Channel Notes
|
||||
* Group channels: created by System
|
||||
* - SWG.serverName.group.GroupObjectId.GroupChat title = GroupId
|
||||
* Guild channels: created by System
|
||||
* - SWG.serverName.guild.GuildId.GuildChat title = GuildId
|
||||
* City channels: created by System
|
||||
* - SWG.serverName.city.CityId.CityChat title = CityId
|
||||
*/
|
||||
}
|
||||
|
||||
public ChatRoom getRoom(String path) {
|
||||
for (ChatRoom room : roomMap.values()) {
|
||||
if (room.getPath().equals(path))
|
||||
return room;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ChatRoom getRoom(int roomId) {
|
||||
return roomMap.get(roomId);
|
||||
roomService.createSystemChannels(galaxy.getName());
|
||||
}
|
||||
|
||||
/* Friends List */
|
||||
@@ -0,0 +1,458 @@
|
||||
/*******************************************************************************
|
||||
* 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 <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
|
||||
package services.chat;
|
||||
|
||||
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.ChatEnterRoomById;
|
||||
import network.packets.swg.zone.chat.ChatOnCreateRoom;
|
||||
import network.packets.swg.zone.chat.ChatOnEnteredRoom;
|
||||
import network.packets.swg.zone.chat.ChatOnLeaveRoom;
|
||||
import network.packets.swg.zone.chat.ChatOnSendRoomMessage;
|
||||
import network.packets.swg.zone.chat.ChatQueryRoom;
|
||||
import network.packets.swg.zone.chat.ChatQueryRoomResults;
|
||||
import network.packets.swg.zone.chat.ChatRemoveAvatarFromRoom;
|
||||
import network.packets.swg.zone.chat.ChatRequestRoomList;
|
||||
import network.packets.swg.zone.chat.ChatSendToRoom;
|
||||
import network.packets.swg.zone.insertion.ChatRoomList;
|
||||
import resources.Terrain;
|
||||
import resources.chat.ChatAvatar;
|
||||
import resources.chat.ChatResult;
|
||||
import resources.chat.ChatRoom;
|
||||
import resources.control.Intent;
|
||||
import resources.control.Service;
|
||||
import resources.objects.player.PlayerObject;
|
||||
import resources.player.AccessLevel;
|
||||
import resources.player.Player;
|
||||
import services.player.PlayerManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author Waverunner
|
||||
*/
|
||||
public class ChatRoomService extends Service {
|
||||
// Array of only the valid terrains in relation to zones able to use planetary-based chat
|
||||
private static final List<Terrain> terrains = Arrays.asList(
|
||||
Terrain.CORELLIA, Terrain.DANTOOINE, Terrain.DATHOMIR, Terrain.ENDOR, Terrain.KASHYYYK, Terrain.LOK,
|
||||
Terrain.MUSTAFAR, Terrain.NABOO, Terrain.RORI, Terrain.TATOOINE, Terrain.TALUS, Terrain.YAVIN4
|
||||
);
|
||||
private int maxChatRoomId;
|
||||
private Map<Integer, ChatRoom> roomMap;
|
||||
// Map to keep track of each player's recent message for a room to prevent duplicates from client
|
||||
private Map<Long, Map<Integer, Integer>> messages;
|
||||
|
||||
public ChatRoomService() {
|
||||
roomMap = new ConcurrentHashMap<>();
|
||||
messages = new ConcurrentHashMap<>();
|
||||
maxChatRoomId = 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initialize() {
|
||||
// TODO: Load up persistent channels
|
||||
registerForIntent(ChatRoomUpdateIntent.TYPE);
|
||||
registerForIntent(GalacticPacketIntent.TYPE);
|
||||
|
||||
return super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIntentReceived(Intent i) {
|
||||
switch(i.getType()) {
|
||||
case ChatRoomUpdateIntent.TYPE:
|
||||
processChatRoomUpdateIntent((ChatRoomUpdateIntent) i);
|
||||
break;
|
||||
case GalacticPacketIntent.TYPE:
|
||||
processPacket((GalacticPacketIntent) i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void processPacket(GalacticPacketIntent intent) {
|
||||
Player player = intent.getPlayerManager().getPlayerFromNetworkId(intent.getNetworkId());
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
Packet p = intent.getPacket();
|
||||
if (p instanceof SWGPacket)
|
||||
processSwgPacket(player, (SWGPacket) p);
|
||||
}
|
||||
|
||||
private void processSwgPacket(Player player, SWGPacket p) {
|
||||
switch (p.getPacketType()) {
|
||||
case CHAT_QUERY_ROOM:
|
||||
if (p instanceof ChatQueryRoom) handleChatQueryRoom(player, (ChatQueryRoom) p);
|
||||
break;
|
||||
case CHAT_ENTER_ROOM_BY_ID: {
|
||||
if (!(p instanceof ChatEnterRoomById)) return;
|
||||
ChatEnterRoomById enterRoomById = (ChatEnterRoomById) p;
|
||||
enterChatChannel(player, enterRoomById.getRoomId(), enterRoomById.getSequence());
|
||||
break; }
|
||||
case CHAT_REMOVE_AVATAR_FROM_ROOM:
|
||||
if (p instanceof ChatRemoveAvatarFromRoom)
|
||||
leaveChatChannel(player, ((ChatRemoveAvatarFromRoom) p).getPath());
|
||||
break;
|
||||
case CHAT_SEND_TO_ROOM:
|
||||
if (p instanceof ChatSendToRoom) handleChatSendToRoom(player, (ChatSendToRoom) p);
|
||||
break;
|
||||
case CHAT_REQUEST_ROOM_LIST:
|
||||
if (p instanceof ChatRequestRoomList)
|
||||
handleChatRoomListRequest(player);
|
||||
break;
|
||||
case CHAT_CREATE_ROOM:
|
||||
if (p instanceof ChatCreateRoom) handleChatCreateRoom(player, (ChatCreateRoom) p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void processChatRoomUpdateIntent(ChatRoomUpdateIntent i) {
|
||||
switch(i.getUpdateType()) {
|
||||
case CREATE: createRoom(i.getAvatar(), i.isPublic(), i.getPath(), i.getTitle()); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Chat Rooms */
|
||||
|
||||
private void handleChatCreateRoom(Player player, ChatCreateRoom p) {
|
||||
String path = p.getRoomName();
|
||||
String title = p.getRoomTitle();
|
||||
ChatRoom room = getRoom(path);
|
||||
|
||||
ChatResult result = ChatResult.SUCCESS;
|
||||
if (room != null)
|
||||
result = ChatResult.ROOM_ALREADY_EXISTS;
|
||||
|
||||
if (result == ChatResult.SUCCESS) {
|
||||
room = createRoom(ChatAvatar.getFromPlayer(player), p.isPublic(), path, title);
|
||||
room.setMuted(p.isModerated());
|
||||
}
|
||||
|
||||
player.sendPacket(new ChatOnCreateRoom(result.getCode(), room, p.getSequence()));
|
||||
}
|
||||
|
||||
private void handleChatSendToRoom(Player player, ChatSendToRoom p) {
|
||||
ChatResult result = ChatResult.SUCCESS;
|
||||
|
||||
ChatRoom room = getRoom(p.getRoomId());
|
||||
if (room == null)
|
||||
result = ChatResult.ROOM_INVALID_ID;
|
||||
|
||||
if (result != ChatResult.SUCCESS) {
|
||||
player.sendPacket(new ChatOnSendRoomMessage(result.getCode(), p.getSequence()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!incrementMessageCounter(player.getNetworkId(), room.getId(), p.getSequence()))
|
||||
return;
|
||||
|
||||
ChatAvatar avatar = ChatAvatar.getFromPlayer(player);
|
||||
|
||||
result = room.canSendMessage(avatar);
|
||||
|
||||
// TODO: Check length of messages -- Result 16 is used for too long message
|
||||
|
||||
player.sendPacket(new ChatOnSendRoomMessage(result.getCode(), p.getSequence()));
|
||||
|
||||
if (result == ChatResult.SUCCESS)
|
||||
room.sendMessage(avatar, p.getMessage(), p.getOutOfBandPackage(), player.getPlayerManager());
|
||||
}
|
||||
|
||||
private void handleChatQueryRoom(Player player, ChatQueryRoom p) {
|
||||
ChatRoom room = getRoom(p.getRoomPath()); // No result code is sent for queries
|
||||
if (room == null)
|
||||
return;
|
||||
|
||||
player.sendPacket(new ChatQueryRoomResults(room, p.getSequence()));
|
||||
}
|
||||
|
||||
private void handleChatRoomListRequest(Player player) {
|
||||
ChatAvatar avatar = ChatAvatar.getFromPlayer(player);
|
||||
|
||||
List<ChatRoom> rooms = new ArrayList<>();
|
||||
for (ChatRoom chatRoom : roomMap.values()) {
|
||||
if (!chatRoom.isPublic() && !chatRoom.getInvited().contains(avatar) && !chatRoom.getOwner().equals(avatar))
|
||||
continue;
|
||||
rooms.add(chatRoom);
|
||||
}
|
||||
|
||||
ChatRoomList response = new ChatRoomList(rooms);
|
||||
player.sendPacket(response);
|
||||
}
|
||||
|
||||
private void sendOnEnteredChatRoom(Player player, ChatAvatar avatar, ChatResult result, int id, int sequence) {
|
||||
ChatOnEnteredRoom onEnteredRoom = new ChatOnEnteredRoom(avatar, id, sequence);
|
||||
onEnteredRoom.setResult(result.getCode());
|
||||
player.sendPacket(onEnteredRoom);
|
||||
}
|
||||
|
||||
public void enterChatChannels(Player player, List<String> channels) {
|
||||
for (String s : channels) {
|
||||
enterChatChannel(player, s);
|
||||
}
|
||||
}
|
||||
|
||||
public void enterPlanetaryChatChannels(Player player) {
|
||||
PlayerObject ghost = player.getPlayerObject();
|
||||
if (ghost == null)
|
||||
return;
|
||||
|
||||
// Leave old zone-only chat channels
|
||||
String planetEndPath = ".Planet";
|
||||
for (String channel : ghost.getJoinedChannels()) {
|
||||
if (channel.endsWith(planetEndPath)) {
|
||||
leaveChatChannel(player, channel);
|
||||
} else {
|
||||
// Better way of doing this?
|
||||
String[] split = channel.split("\\.");
|
||||
if (split.length == 3 && split[2].equals("system"))
|
||||
leaveChatChannel(player, channel);
|
||||
}
|
||||
}
|
||||
|
||||
Terrain terrain = player.getCreatureObject().getLocation().getTerrain();
|
||||
|
||||
// Enter the new zone-only chat channels
|
||||
if (!terrains.contains(terrain))
|
||||
return;
|
||||
|
||||
String planetPath = "SWG." + player.getGalaxyName() + "." + terrain.getNameCapitalized() + ".";
|
||||
enterChatChannel(player, planetPath + "Planet");
|
||||
enterChatChannel(player, planetPath + "system");
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to join the specified chat channel
|
||||
* @param player Player joining the chat channel
|
||||
* @param room Chat room to enter
|
||||
*/
|
||||
public void enterChatChannel(Player player, ChatRoom room, int sequence) {
|
||||
ChatAvatar avatar = ChatAvatar.getFromPlayer(player);
|
||||
|
||||
PlayerObject ghost = player.getPlayerObject();
|
||||
if (ghost == null) {
|
||||
sendOnEnteredChatRoom(player, avatar, ChatResult.NONE, room.getId(), sequence);
|
||||
return;
|
||||
}
|
||||
|
||||
ChatResult result = room.canJoinRoom(avatar);
|
||||
if (result != ChatResult.SUCCESS && player.getAccessLevel() != AccessLevel.PLAYER) {
|
||||
sendOnEnteredChatRoom(player, avatar, result, room.getId(), sequence);
|
||||
return;
|
||||
}
|
||||
// TODO: Check if player is appropriate faction for the room (Rebel and imperial chat rooms)
|
||||
|
||||
// Server-based list so we can join chat channels automatically
|
||||
ghost.addJoinedChannel(room.getPath());
|
||||
|
||||
// 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);
|
||||
|
||||
// Notify players of success, it's ChatResult.SUCCESS at this point
|
||||
player.sendPacket(new ChatOnEnteredRoom(avatar, result.getCode(), room.getId(), sequence));
|
||||
|
||||
PlayerManager manager = player.getPlayerManager();
|
||||
// Notify everyone that a player entered the room
|
||||
room.sendPacketToMembers(manager, new ChatOnEnteredRoom(avatar, result.getCode(), room.getId(), 0));
|
||||
|
||||
room.getMembers().add(avatar);
|
||||
}
|
||||
|
||||
public void enterChatChannel(Player player, int id, int sequence) {
|
||||
ChatRoom room = getRoom(id);
|
||||
if (room == null) {
|
||||
sendOnEnteredChatRoom(player, ChatAvatar.getFromPlayer(player), ChatResult.NONE, id, sequence);
|
||||
return;
|
||||
}
|
||||
enterChatChannel(player, room, sequence);
|
||||
}
|
||||
|
||||
public void enterChatChannel(Player player, String path) {
|
||||
for (ChatRoom room : roomMap.values()) {
|
||||
if (room.getPath().equals(path)) {
|
||||
enterChatChannel(player, room, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
System.err.println("Tried to join a room with a path that does not exist: " + path);
|
||||
}
|
||||
|
||||
public void leaveChatChannel(Player player, ChatRoom room, int sequence) {
|
||||
ChatAvatar avatar = ChatAvatar.getFromPlayer(player);
|
||||
|
||||
PlayerObject ghost = player.getPlayerObject();
|
||||
if (ghost == null)
|
||||
return; // ChatOnLeaveRoom doesn't do anything other than for a ChatResult.SUCCESS, so no need to send a fail
|
||||
|
||||
if (!room.getMembers().remove(avatar) && !ghost.removeJoinedChannel(room.getPath()))
|
||||
return;
|
||||
|
||||
player.sendPacket(new ChatOnLeaveRoom(avatar, ChatResult.SUCCESS.getCode(), room.getId(), sequence));
|
||||
|
||||
room.sendPacketToMembers(player.getPlayerManager(), new ChatOnLeaveRoom(avatar, ChatResult.SUCCESS.getCode(), room.getId(), 0));
|
||||
}
|
||||
|
||||
public void leaveChatChannel(Player player, String path) {
|
||||
for (ChatRoom chatRoom : roomMap.values()) {
|
||||
if (chatRoom.getPath().equals(path))
|
||||
leaveChatChannel(player, chatRoom, 0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a new, non-persistent, chat room with the specified address path.
|
||||
* @param creator Room creator who will also become the owner of this room
|
||||
* @param isPublic Determines if the room should be publicly displayed in the channel listing
|
||||
* @param path Address for the channel (Ex: SWG.serverName.Imperial)
|
||||
* @param title Descriptive name of the chat channel (Ex: Imperial chat for this galaxy)
|
||||
* @return {@link ChatRoom}
|
||||
*/
|
||||
public ChatRoom createRoom(ChatAvatar creator, boolean isPublic, String path, String title) {
|
||||
if (path.isEmpty() || path.endsWith("."))
|
||||
return null;
|
||||
|
||||
String base = "SWG." + creator.getGalaxy();
|
||||
if (!path.startsWith(base) || path.equals(base))
|
||||
return null;
|
||||
|
||||
// All paths should have parents, lets validate to make sure they exist first. Create them if they don't.
|
||||
int lastIndex = path.lastIndexOf(".");
|
||||
if (lastIndex != -1) {
|
||||
String parentPath = path.substring(0, lastIndex);
|
||||
if (getRoom(parentPath) == null) {
|
||||
createRoom(creator, isPublic, parentPath, "");
|
||||
}
|
||||
}
|
||||
|
||||
ChatRoom room = new ChatRoom();
|
||||
int id = maxChatRoomId;
|
||||
maxChatRoomId++;
|
||||
|
||||
room.setId(id);
|
||||
room.setOwner(creator);
|
||||
room.setCreator(creator);
|
||||
room.setIsPublic(isPublic);
|
||||
room.setPath(path);
|
||||
room.setTitle(title);
|
||||
|
||||
roomMap.put(id, room);
|
||||
return room;
|
||||
}
|
||||
|
||||
public boolean destroyRoom(ChatRoom room) {
|
||||
// Remove existing, online, members from the room
|
||||
// Remove room from map and database
|
||||
// Remove roompath from joinedChannels list if player tried to join an invalid room
|
||||
return false;
|
||||
}
|
||||
|
||||
public void createSystemChannels(String galaxy) {
|
||||
/** Channel Notes
|
||||
* Group channels: created by System
|
||||
* - SWG.serverName.group.GroupObjectId.GroupChat title = GroupId
|
||||
* Guild channels: created by System
|
||||
* - SWG.serverName.guild.GuildId.GuildChat title = GuildId
|
||||
* City channels: created by System
|
||||
* - SWG.serverName.city.CityId.CityChat title = CityId
|
||||
*/
|
||||
|
||||
ChatAvatar systemAvatar = ChatAvatar.getSystemAvatar(galaxy);
|
||||
// TODO: Move to server datatable file (SDF): Room (s) | Title (s) | Private (b)
|
||||
String basePath = "SWG." + galaxy + ".";
|
||||
createRoom(systemAvatar, true, basePath + "Galaxy", "public chat for the whole galaxy, cannot create rooms here");
|
||||
createRoom(systemAvatar, true, basePath + "system", "system messages for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Chat", "public chat for this galaxy, can create rooms here");
|
||||
createRoom(systemAvatar, true, basePath + "Imperial", "Imperial chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "ImperialWarRoom", "Imperial war room chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Rebel", "Rebel chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "RebelWarRoom", "Rebel war room chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "BountyHunter", "Bounty Hunter chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Commando", "Commando chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Entertainer", "Entertainer chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "ForceSensitive", "Force Sensitive chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Medic", "Medic chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Officer", "Officer chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Pilot", "Pilot chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Politician", "Politician chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Smuggler", "Smuggler chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Spy", "Spy chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Trader", "Trader chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "BeastMastery", "Beast Mastery chat for this galaxy");
|
||||
createRoom(systemAvatar, true, basePath + "Auction", "Auction chat for this galaxy");
|
||||
createPlanetChannels(systemAvatar, basePath);
|
||||
}
|
||||
|
||||
private void createPlanetChannels(ChatAvatar systemAvatar, String basePath) {
|
||||
// TODO: Move planets to a server datatable file (SDF): Planet (s)
|
||||
for (Terrain terrain : terrains) {
|
||||
String path = basePath + terrain.getNameCapitalized() + ".";
|
||||
createRoom(systemAvatar, true, path + "Planet", "public chat for this planet, cannot create rooms here");
|
||||
createRoom(systemAvatar, true, path + "system", "system messages for this planet, cannot create rooms here");
|
||||
createRoom(systemAvatar, true, path + "Chat", "public chat for this planet, can create rooms here");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean incrementMessageCounter(long networkId, int roomId, int messageId) {
|
||||
if (networkId == -1) // System ChatAvatar uses -1 for networkId
|
||||
return true;
|
||||
|
||||
Map<Integer, Integer> messageHistory = messages.get(networkId);
|
||||
if (messageHistory != null) {
|
||||
if (messageHistory.containsKey(roomId) && messageHistory.get(roomId) == messageId)
|
||||
return false;
|
||||
} else {
|
||||
messageHistory = new HashMap<>();
|
||||
messages.put(networkId, messageHistory);
|
||||
}
|
||||
messageHistory.put(roomId, messageId);
|
||||
return true;
|
||||
}
|
||||
|
||||
public ChatRoom getRoom(String path) {
|
||||
for (ChatRoom room : roomMap.values()) {
|
||||
if (room.getPath().equals(path))
|
||||
return room;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ChatRoom getRoom(int roomId) {
|
||||
return roomMap.get(roomId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,7 +33,7 @@ import intents.network.InboundPacketIntent;
|
||||
import resources.Galaxy;
|
||||
import resources.control.Intent;
|
||||
import resources.control.Manager;
|
||||
import services.chat.ChatService;
|
||||
import services.chat.ChatManager;
|
||||
import services.objects.ObjectManager;
|
||||
import services.player.PlayerManager;
|
||||
|
||||
@@ -44,7 +44,7 @@ public class GalacticManager extends Manager {
|
||||
private ObjectManager objectManager;
|
||||
private PlayerManager playerManager;
|
||||
private GameManager gameManager;
|
||||
private ChatService chatService;
|
||||
private ChatManager chatManager;
|
||||
private Intent prevPacketIntent;
|
||||
private Galaxy galaxy;
|
||||
|
||||
@@ -53,19 +53,19 @@ public class GalacticManager extends Manager {
|
||||
objectManager = new ObjectManager();
|
||||
playerManager = new PlayerManager();
|
||||
gameManager = new GameManager();
|
||||
chatService = new ChatService();
|
||||
chatManager = new ChatManager();
|
||||
prevPacketIntent = null;
|
||||
|
||||
addChildService(objectManager);
|
||||
addChildService(playerManager);
|
||||
addChildService(gameManager);
|
||||
addChildService(chatService);
|
||||
addChildService(chatManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initialize() {
|
||||
registerForIntent(InboundPacketIntent.TYPE);
|
||||
chatService.initializeGalaxyChannels(galaxy);
|
||||
chatManager.initializeGalaxyChannels(galaxy);
|
||||
return super.initialize();
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
package services.galaxy;
|
||||
|
||||
import resources.control.Manager;
|
||||
import services.chat.ChatService;
|
||||
import services.commands.CommandService;
|
||||
import services.sui.SuiService;
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -149,7 +150,61 @@ public class PlayerManager extends Manager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void notifyPlayers(NotifyPlayersPacketIntent.ConditionalNotify conditional, Packet... packets) {
|
||||
if (conditional == null) {
|
||||
notifyPlayers(packets);
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (players) {
|
||||
for (Player player : players.values()) {
|
||||
if (conditional.meetsCondition(player)) {
|
||||
player.sendPacket(packets);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyPlayers(List<Long> networkIds, NotifyPlayersPacketIntent.ConditionalNotify conditionalNotify, Packet... packets) {
|
||||
if (conditionalNotify == null) {
|
||||
notifyPlayers(networkIds, packets);
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (players) {
|
||||
networkIds.forEach(id -> {
|
||||
Player p = players.get(id);
|
||||
if (p != null && p.getCreatureObject() != null && conditionalNotify.meetsCondition(p))
|
||||
p.sendPacket(packets);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyPlayers(List<Long> networkIds, Packet... packets) {
|
||||
synchronized (players) {
|
||||
networkIds.forEach(id -> {
|
||||
Player p = players.get(id);
|
||||
if (p != null && p.getCreatureObject() != null)
|
||||
p.sendPacket(packets);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyPlayersAtPlanet(NotifyPlayersPacketIntent.ConditionalNotify conditional, Terrain terrain, Packet... packets) {
|
||||
if (conditional == null) {
|
||||
notifyPlayersAtPlanet(terrain, packets);
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized(players) {
|
||||
for (Player p : players.values()) {
|
||||
if (p != null && p.getCreatureObject() != null && p.getCreatureObject().getLocation().getTerrain() == terrain && conditional.meetsCondition(p))
|
||||
p.sendPacket(packets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyPlayersAtPlanet(Terrain terrain, Packet... packets) {
|
||||
synchronized(players) {
|
||||
for (Player p : players.values()) {
|
||||
@@ -159,13 +214,28 @@ public class PlayerManager extends Manager {
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyPlayersWithCondition(NotifyPlayersPacketIntent.ConditionalNotify conditional, Packet... packets) {
|
||||
synchronized (players) {
|
||||
for (Player player : players.values()) {
|
||||
if (conditional.meetsCondition(player)) {
|
||||
player.sendPacket(packets);
|
||||
}
|
||||
}
|
||||
public void notifyPlayersAtPlanet(List<Long> networkIds, NotifyPlayersPacketIntent.ConditionalNotify conditional, Terrain terrain, Packet... packets) {
|
||||
if(conditional == null) {
|
||||
notifyPlayersAtPlanet(networkIds, terrain, packets);
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized(players) {
|
||||
networkIds.forEach(id -> {
|
||||
Player p = players.get(id);
|
||||
if (p != null && p.getCreatureObject() != null && p.getCreatureObject().getLocation().getTerrain() == terrain && conditional.meetsCondition(p))
|
||||
p.sendPacket(packets);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyPlayersAtPlanet(List<Long> networkIds, Terrain terrain, Packet... packets) {
|
||||
synchronized(players) {
|
||||
networkIds.forEach(id -> {
|
||||
Player p = players.get(id);
|
||||
if (p != null && p.getCreatureObject() != null && p.getCreatureObject().getLocation().getTerrain() == terrain)
|
||||
p.sendPacket(packets);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,12 +330,12 @@ public class PlayerManager extends Manager {
|
||||
}
|
||||
|
||||
private void onNotifyPlayersPacketIntent(NotifyPlayersPacketIntent nppi) {
|
||||
if (nppi.getCondition() != null) {
|
||||
notifyPlayersWithCondition(nppi.getCondition(), nppi.getPacket());
|
||||
} else if (nppi.getTerrain() != null) {
|
||||
notifyPlayersAtPlanet(nppi.getTerrain(), nppi.getPacket());
|
||||
if (nppi.getNetworkIds() != null) {
|
||||
if (nppi.getTerrain() != null) notifyPlayersAtPlanet(nppi.getNetworkIds(), nppi.getCondition(), nppi.getTerrain(), nppi.getPacket());
|
||||
else notifyPlayers(nppi.getNetworkIds(), nppi.getCondition(), nppi.getPacket());
|
||||
} else {
|
||||
notifyPlayers(nppi.getPacket());
|
||||
if (nppi.getTerrain() != null) notifyPlayersAtPlanet(nppi.getCondition(), nppi.getTerrain(), nppi.getPacket());
|
||||
else notifyPlayers(nppi.getCondition(), nppi.getPacket());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user