diff --git a/.gitignore b/.gitignore index ddb52186..35b64af6 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ odb/doids/je.info.* odb/guild/je.info.* odb/mails/je.info.* odb/oids/je.info.* +odb/chatRooms/je.info.* # PSWG Configs options.cfg diff --git a/odb/creature/je.info.0.1 b/odb/chatRooms/placeholder.txt similarity index 100% rename from odb/creature/je.info.0.1 rename to odb/chatRooms/placeholder.txt diff --git a/scripts/commands/gc.py b/scripts/commands/gc.py new file mode 100644 index 00000000..b3559b3b --- /dev/null +++ b/scripts/commands/gc.py @@ -0,0 +1,13 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + group = core.objectService.getObject(actor.getGroupId()) + + if group is None: + return + + core.chatService.sendChatRoomMessage(actor, group.getChatRoomId(), commandString) + return \ No newline at end of file diff --git a/scripts/commands/sitserver.py b/scripts/commands/sitserver.py index f1089afd..a8167409 100644 --- a/scripts/commands/sitserver.py +++ b/scripts/commands/sitserver.py @@ -22,11 +22,11 @@ def run(core, actor, target, commandString): actor.setPosture(8) actor.setStateBitmask(32768) actor.setTurnRadius(0) - # These 3 were outside of the return statement. Not sure why.. - Waverunner - #actor.setPosture(8) - actor.setSpeedMultiplierBase(0) - actor.setTurnRadius(0) actor.setChairCellId(cellId) return + # sit w/o chair + actor.setPosture(8) + actor.setSpeedMultiplierBase(0) + actor.setTurnRadius(0) return \ No newline at end of file diff --git a/src/main/NGECore.java b/src/main/NGECore.java index 678fee1b..ff5def03 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -185,6 +185,7 @@ public class NGECore { private ObjectDatabase guildODB; private ObjectDatabase objectIdODB; private ObjectDatabase duplicateIdODB; + private ObjectDatabase chatRoomODB; private BusConfiguration eventBusConfig = BusConfiguration.Default(1, new ThreadPoolExecutor(1, 4, 1, TimeUnit.MINUTES, new LinkedBlockingQueue())); @@ -235,7 +236,8 @@ public class NGECore { guildODB = new ObjectDatabase("guild", true, false, true); objectIdODB = new ObjectDatabase("oids", true, false, false); duplicateIdODB = new ObjectDatabase("doids", true, false, true); - + chatRoomODB = new ObjectDatabase("chatRooms", true, false, true); + // Services loginService = new LoginService(this); retroService = new RetroService(this); @@ -528,6 +530,10 @@ public class NGECore { return duplicateIdODB; } + public ObjectDatabase getChatRoomODB() { + return chatRoomODB; + } + public int getActiveClients() { int connections = 0; for (Map.Entry c : clients.entrySet()) { diff --git a/src/protocol/swg/ChatOnCreateRoom.java b/src/protocol/swg/ChatOnCreateRoom.java new file mode 100644 index 00000000..be54a71d --- /dev/null +++ b/src/protocol/swg/ChatOnCreateRoom.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg; + +import org.apache.mina.core.buffer.IoBuffer; + +import services.chat.ChatRoom; + +public class ChatOnCreateRoom extends SWGMessage { + + private ChatRoom room; + + public ChatOnCreateRoom(ChatRoom room) { + this.room = room; + } + + @Override + public void deserialize(IoBuffer data) { + + } + + @Override + public IoBuffer serialize() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/protocol/swg/ChatOnEnteredRoom.java b/src/protocol/swg/ChatOnEnteredRoom.java new file mode 100644 index 00000000..b040c1bf --- /dev/null +++ b/src/protocol/swg/ChatOnEnteredRoom.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg; + +import java.nio.ByteOrder; + +import main.NGECore; + +import org.apache.mina.core.buffer.IoBuffer; + +import engine.resources.common.CRC; +import resources.common.Opcodes; + +public class ChatOnEnteredRoom extends SWGMessage { + + private String characterName; + private int success; + private int roomId; + private boolean join; + + public ChatOnEnteredRoom(String characterName, int success, int roomId, boolean join) { + this.characterName = characterName; + this.success = success; + this.roomId = roomId; + } + + @Override + public void deserialize(IoBuffer data) { + + } + + @Override + public IoBuffer serialize() { + String galaxy = NGECore.getInstance().getGalaxyName(); + IoBuffer buffer = IoBuffer.allocate(27 + galaxy.length() + characterName.length()).order(ByteOrder.LITTLE_ENDIAN); + buffer.putShort((short) 5); + if (join) + buffer.putInt(Opcodes.ChatOnEnteredRoom); + else + buffer.putInt(CRC.StringtoCRC("ChatOnLeaveRoom")); + buffer.put(getAsciiString("SWG")); + buffer.put(getAsciiString(galaxy)); + buffer.put(getAsciiString(characterName)); + buffer.putInt(success); + buffer.putInt(roomId); + return buffer.flip(); + } + + public static final int JOIN_SUCCESS = 0; + public static final int JOIN_FAIL_NO_INVITE = 0x10; +} diff --git a/src/protocol/swg/ChatOnSendRoomMessage.java b/src/protocol/swg/ChatOnSendRoomMessage.java new file mode 100644 index 00000000..4ab43d6c --- /dev/null +++ b/src/protocol/swg/ChatOnSendRoomMessage.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +public class ChatOnSendRoomMessage extends SWGMessage { + + private int errorCode; + + public ChatOnSendRoomMessage(int errorCode) { + this.errorCode = errorCode; + } + + @Override + public void deserialize(IoBuffer data) { + } + + @Override + public IoBuffer serialize() { + IoBuffer buffer = IoBuffer.allocate(14).order(ByteOrder.LITTLE_ENDIAN); + buffer.putShort((short) 3); + buffer.putInt(0xE7B61633); + buffer.putInt(errorCode); + buffer.putInt(1); // msg id + return buffer.flip(); + } + + public static final int SUCCESS = 0; + public static final int FAILED_MODERATOR = 9; + public static final int FAILED_LENGTH = 16; + +} diff --git a/src/protocol/swg/ChatRoomList.java b/src/protocol/swg/ChatRoomList.java new file mode 100644 index 00000000..e2bff284 --- /dev/null +++ b/src/protocol/swg/ChatRoomList.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg; + +import java.nio.ByteOrder; +import java.util.concurrent.ConcurrentHashMap; + +import main.NGECore; + +import org.apache.mina.core.buffer.IoBuffer; + +import services.chat.ChatRoom; + +public class ChatRoomList extends SWGMessage { + + private ConcurrentHashMap chatRooms; + + public ChatRoomList(ConcurrentHashMap chatRooms) { + this.chatRooms = chatRooms; + } + + @Override + public void deserialize(IoBuffer data) { + + } + + @Override + public IoBuffer serialize() { + String server = NGECore.getInstance().getGalaxyName(); + IoBuffer buffer = IoBuffer.allocate(100).order(ByteOrder.LITTLE_ENDIAN); + buffer.setAutoExpand(true); + + buffer.putShort((short) 2); + buffer.putInt(0x70DEB197); + + buffer.putInt(chatRooms.size()); + chatRooms.forEach((key, value) -> { + if (value.isVisible()) { + buffer.putInt(value.getRoomId()); + buffer.putInt((int) ((value.isPrivateRoom() ? 1 : 0))); + buffer.put((byte) ((value.isModeratorsOnly() ? 1 : 0))); + buffer.put(getAsciiString(value.getRoomAddress())); + buffer.put(getAsciiString("SWG")); + buffer.put(getAsciiString(server)); + buffer.put(getAsciiString(value.getOwner())); + buffer.put(getAsciiString("SWG")); + buffer.put(getAsciiString(server)); + buffer.put(getAsciiString(value.getCreator())); + buffer.put(getUnicodeString(value.getDescription())); + buffer.putInt(0); // moderator list (not used by client) + buffer.putInt(0); // user list (not used by client) + } + }); + return buffer.flip(); + } + +} diff --git a/src/protocol/swg/ChatRoomMessage.java b/src/protocol/swg/ChatRoomMessage.java new file mode 100644 index 00000000..209db832 --- /dev/null +++ b/src/protocol/swg/ChatRoomMessage.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg; + +import java.nio.ByteOrder; + +import main.NGECore; + +import org.apache.mina.core.buffer.IoBuffer; + +public class ChatRoomMessage extends SWGMessage { + + private String character; + private String message; + private int roomId; + + public ChatRoomMessage(int roomId, String player, String message) { + this.roomId = roomId; + this.character = player; + this.message = message; + } + + @Override + public void deserialize(IoBuffer data) { + } + + @Override + public IoBuffer serialize() { + String server = NGECore.getInstance().getGalaxyName(); + + IoBuffer buffer = IoBuffer.allocate(27 + server.length() + character.length() + (message.length() * 2)).order(ByteOrder.LITTLE_ENDIAN); + + buffer.putShort((short) 5); + buffer.putInt(0xCD4CE444); + buffer.put(getAsciiString("SWG")); + buffer.put(getAsciiString(server)); + buffer.put(getAsciiString(character)); + buffer.putInt(roomId); + buffer.put(getUnicodeString(message)); + buffer.putInt(0); // out of band package ? + return buffer.flip(); + } + +} diff --git a/src/resources/common/Opcodes.java b/src/resources/common/Opcodes.java index a97993f9..9f906000 100644 --- a/src/resources/common/Opcodes.java +++ b/src/resources/common/Opcodes.java @@ -75,6 +75,9 @@ public class Opcodes { public static int CollectionServerFirstListRequest = CRC.StringtoCRC("CollectionServerFirstListRequest"); public static int ShowHelmet = CRC.StringtoCRC("ShowHelmet"); public static int ShowBackpack = CRC.StringtoCRC("ShowBackpack"); + public static int ChatOnEnteredRoom = CRC.StringtoCRC("ChatOnEnteredRoom"); + public static int ChatCreateRoom = CRC.StringtoCRC("ChatCreateRoom"); + public static int ChatQueryRoom = 0x9CF2B192; public static int Unknown = 0x173B91C2; // packet sent to server on every character load-in } diff --git a/src/resources/objects/group/GroupObject.java b/src/resources/objects/group/GroupObject.java index b6a75e68..0cac422d 100644 --- a/src/resources/objects/group/GroupObject.java +++ b/src/resources/objects/group/GroupObject.java @@ -39,6 +39,7 @@ public class GroupObject extends UniverseObject { private short groupLevel; private int lootMode; private GroupMessageBuilder messageBuilder; + private int chatRoomId; public GroupObject(long objectId) { super(objectId, null, new Point3D(0, 0, 0), new Quaternion(1, 0, 0, 0), "object/group/shared_group_object.iff"); @@ -108,7 +109,19 @@ public class GroupObject extends UniverseObject { this.lootMode = lootMode; } } - + + public int getChatRoomId() { + synchronized(objectMutex) { + return chatRoomId; + } + } + + public void setChatRoomId(int chatRoomId) { + synchronized(objectMutex) { + this.chatRoomId = chatRoomId; + } + } + public void addMember(SWGObject member) { if(memberList.size() >= 8 || member.getClient() == null) @@ -147,5 +160,4 @@ public class GroupObject extends UniverseObject { destination.getSession().write(messageBuilder.buildBaseline6()); } - } diff --git a/src/services/GroupService.java b/src/services/GroupService.java index b6ae0b87..dc2cf39b 100644 --- a/src/services/GroupService.java +++ b/src/services/GroupService.java @@ -28,9 +28,8 @@ import java.util.Map; import resources.objects.Buff; import resources.objects.creature.CreatureObject; import resources.objects.group.GroupObject; - +import services.chat.ChatRoom; import main.NGECore; - import engine.clients.Client; import engine.resources.objects.SWGObject; import engine.resources.service.INetworkDispatch; @@ -153,6 +152,13 @@ public class GroupService implements INetworkDispatch { invited.setGroupId(group.getObjectID()); addGroupBuffsToMember(group, leader); addGroupBuffsToMember(group, invited); + + //ChatRoom groupChat = core.chatService.createChatRoom(leader.getCustomName() + group.getObjectID(), "GroupChat", leader.getCustomName(), true); + //group.setChatRoomId(groupChat.getRoomId()); + + //core.chatService.joinChatRoom(leader, groupChat.getRoomId()); + //core.chatService.joinChatRoom(invited, groupChat.getRoomId()); + return; } diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index bb495850..8337470e 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -188,6 +188,7 @@ public class SimulationService implements INetworkDispatch { core.objectService.loadServerTemplate(building); add(building, building.getPosition().x, building.getPosition().z); } + cursor.close(); } @@ -804,7 +805,7 @@ public class SimulationService implements INetworkDispatch { PlayerObject ghost = (PlayerObject) object.getSlottedObject("ghost"); core.weatherService.sendWeather(object); - + if (!object.hasSkill(ghost.getProfessionWheelPosition())) { object.showFlyText("cbt_spam", "skill_up", (float) 2.5, new RGB(154, 205, 50), 0); object.playEffectObject("clienteffect/skill_granted.cef", ""); diff --git a/src/services/chat/ChatRoom.java b/src/services/chat/ChatRoom.java new file mode 100644 index 00000000..41ee1565 --- /dev/null +++ b/src/services/chat/ChatRoom.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package services.chat; + +import java.util.List; +import java.util.Vector; + +import resources.objects.creature.CreatureObject; + +import com.sleepycat.persist.model.Entity; +import com.sleepycat.persist.model.NotPersistent; +import com.sleepycat.persist.model.PrimaryKey; +import com.sleepycat.persist.model.Relationship; +import com.sleepycat.persist.model.SecondaryKey; + +@Entity +public class ChatRoom { + private String creator; // creator of the room (first name only, lowercase) + private String description; // title + @PrimaryKey + private int roomId; + private String roomAddress; // name + + private Vector moderatorList = new Vector(); + private Vector banList = new Vector(); + @NotPersistent + private Vector userList = new Vector(); // current users + + @NotPersistent + private int requestId; // not-persistent + private boolean moderatorsOnly; + private boolean privateRoom; + private boolean visible; + private String owner; // current owner of the room (first name only lowercase) + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getRoomAddress() { + return roomAddress; + } + + public void setRoomAddress(String roomAddress) { + this.roomAddress = roomAddress; + } + + public int getRoomId() { + return roomId; + } + + public void setRoomId(int roomId) { + this.roomId = roomId; + } + + public Vector getModeratorList() { + return moderatorList; + } + + public void setModeratorList(Vector moderatorList) { + this.moderatorList = moderatorList; + } + + public Vector getUserList() { + return userList; + } + + public void setUserList(Vector userList) { + this.userList = userList; + } + + public int getRequestId() { + return requestId; + } + + public void setRequestId(int requestId) { + this.requestId = requestId; + } + + public boolean isModeratorsOnly() { + return moderatorsOnly; + } + + public void setModeratorsOnly(boolean moderatorsOnly) { + this.moderatorsOnly = moderatorsOnly; + } + + public boolean isPrivateRoom() { + return privateRoom; + } + + public void setPrivateRoom(boolean privateRoom) { + this.privateRoom = privateRoom; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public Vector getBanList() { + return banList; + } + + public void setBanList(Vector banList) { + this.banList = banList; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } +} diff --git a/src/services/chat/ChatService.java b/src/services/chat/ChatService.java index eb7c5a15..c5b5bb5e 100644 --- a/src/services/chat/ChatService.java +++ b/src/services/chat/ChatService.java @@ -26,6 +26,7 @@ import java.util.Date; import java.util.HashSet; import java.util.Map; import java.util.Random; +import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import org.apache.mina.core.buffer.IoBuffer; @@ -33,6 +34,8 @@ import org.apache.mina.core.session.IoSession; import com.sleepycat.je.Transaction; import com.sleepycat.persist.EntityCursor; +import com.sleepycat.persist.PrimaryIndex; +import com.sleepycat.persist.SecondaryIndex; import engine.clients.Client; import engine.resources.config.Config; @@ -52,11 +55,15 @@ import protocol.swg.ChatFriendsListUpdate; import protocol.swg.ChatInstantMessageToCharacter; import protocol.swg.ChatInstantMessagetoClient; import protocol.swg.ChatOnAddFriend; +import protocol.swg.ChatOnEnteredRoom; import protocol.swg.ChatOnSendInstantMessage; import protocol.swg.ChatOnSendPersistentMessage; +import protocol.swg.ChatOnSendRoomMessage; import protocol.swg.ChatPersistentMessageToClient; import protocol.swg.ChatPersistentMessageToServer; import protocol.swg.ChatRequestPersistentMessage; +import protocol.swg.ChatRoomList; +import protocol.swg.ChatRoomMessage; import protocol.swg.ChatSystemMessage; import protocol.swg.ObjControllerMessage; import protocol.swg.objectControllerObjects.PlayerEmote; @@ -67,7 +74,9 @@ public class ChatService implements INetworkDispatch { private NGECore core; private ObjectDatabase mailODB; - + private ObjectDatabase chatRoomsODB; + private ConcurrentHashMap chatRooms = new ConcurrentHashMap(); + public ChatService(NGECore core) { this.core = core; core.commandService.registerCommand("spatialchatinternal"); @@ -77,7 +86,12 @@ public class ChatService implements INetworkDispatch { core.commandService.registerCommand("findfriend"); core.commandService.registerCommand("addfriend"); core.commandService.registerCommand("removefriend"); + //core.commandService.registerCommand("gc"); + //core.commandService.registerAlias("g", "gc"); mailODB = core.getMailODB(); + chatRoomsODB = core.getChatRoomODB(); + + loadChatRooms(); } public void handleSpatialChat(SWGObject speaker, SWGObject target, String chatMessage, short chatType, short moodId) { @@ -335,11 +349,28 @@ public class ChatService implements INetworkDispatch { @Override public void handlePacket(IoSession session, IoBuffer data) throws Exception { - //ChatRoomList + Client client = core.getClient(session); + + if(client == null) + return; + + SWGObject obj = client.getParent(); + + if (obj == null) + return; + + ChatRoomList listMessage = new ChatRoomList(chatRooms); + + client.getSession().write(listMessage.serialize()); } }); + swgOpcodes.put(Opcodes.ChatCreateRoom, (session, data) -> { + }); + + swgOpcodes.put(Opcodes.ChatQueryRoom, (session, data) -> { + }); } public void playerStatusChange(String name, byte status) { @@ -539,11 +570,11 @@ public class ChatService implements INetworkDispatch { for(Mail mail : cursor) { - if(mail.getRecieverId() == obj.getObjectID()) + if(mail.getRecieverId() == obj.getObjectID()) { sendPersistentMessageHeader(client, mail); - + } } - + cursor.close(); } @Override @@ -588,8 +619,123 @@ public class ChatService implements INetworkDispatch { } + public ChatRoom getChatRoom(int roomId) { + return chatRooms.get(roomId); + } + + public int generateChatRoomId() { + Random rand = new Random(); + int id = rand.nextInt(); + + if (chatRoomsODB.contains(new Integer(id), Integer.class, ChatRoom.class)) + return generateChatRoomId(); + else + return id; + } + public void broadcastGalaxy(String message) { core.simulationService.notifyAllClients(new ChatSystemMessage(message, (byte) 0).serialize()); } + + private void loadChatRooms() { + ChatRoom system = createChatRoom("Waves Dungeon", "ProjectSWGTest.Dungeon", "Waverunner", true); + chatRooms.put(system.getRoomId(), system); + + EntityCursor cursor = chatRoomsODB.getCursor(Integer.class, ChatRoom.class); + cursor.forEach(room -> { + chatRooms.put(room.getRoomId(), room); + }); + cursor.close(); + } + + public ChatRoom createChatRoom(String roomName, String address, String creator, boolean showInList) { + return createChatRoom(roomName, address, creator, showInList, false); + } + public ChatRoom createChatRoom(String roomName, String address, String creator, boolean showInList, boolean store) { + if (creator.contains(" ")) + creator = creator.split(" ")[0]; + + ChatRoom room = new ChatRoom(); + room.setDescription(roomName); + room.setRoomAddress("SWG." + core.getGalaxyName() + "." + address); + room.setCreator(creator); + room.setOwner(creator); + room.setVisible(showInList); + room.setRoomId(generateChatRoomId()); + + chatRooms.put(room.getRoomId(), room); + + if(store){ + Transaction txn = chatRoomsODB.getEnvironment().beginTransaction(null, null); + chatRoomsODB.put(room, Integer.class, ChatRoom.class, txn); + txn.commitSync(); + } + + return room; + } + + public void joinChatRoom(CreatureObject player, int roomId) { + + String playerName = player.getCustomName().toLowerCase(); + + if (playerName.contains(" ")) + playerName = playerName.split(" ")[0]; + + ChatRoom room = getChatRoom(roomId); + if (room == null) + return; + + ChatOnEnteredRoom enterRoom = new ChatOnEnteredRoom(playerName, 0, roomId, true); + player.getClient().getSession().write(enterRoom.serialize()); + + if (!room.getUserList().contains(player)) + room.getUserList().add(player); + } + + public void leaveChatRoom(CreatureObject player, int roomId) { + + String playerName = player.getCustomName().toLowerCase(); + + if (playerName.contains(" ")) + playerName = playerName.split(" ")[0]; + + ChatRoom room = getChatRoom(roomId); + if (room == null) + return; + + ChatOnEnteredRoom enterRoom = new ChatOnEnteredRoom(playerName, 0, roomId, false); + player.getClient().getSession().write(enterRoom.serialize()); + + if (room.getUserList().contains(player)) + room.getUserList().remove(player); + } + + public void sendChatRoomMessage(CreatureObject sender, int roomId, String message) { + String senderName = sender.getCustomName().toLowerCase(); + + if (senderName.contains(" ")) + senderName = senderName.split(" ")[0]; + + ChatRoom room = getChatRoom(roomId); + if (room == null) + return; + + ChatOnSendRoomMessage onSend = new ChatOnSendRoomMessage(ChatOnSendRoomMessage.SUCCESS); + sender.getClient().getSession().write(onSend.serialize()); + + ChatRoomMessage roomMessage = new ChatRoomMessage(roomId, senderName, message); + Vector users = room.getUserList(); + + for (CreatureObject user : users) { + if (user == sender) + continue; + + user.getClient().getSession().write(roomMessage.serialize()); + } + } + + public ConcurrentHashMap getChatRooms() { + return chatRooms; + } } diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index ea6ead9c..b49e0fe7 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -61,6 +61,7 @@ import com.sleepycat.persist.model.PrimaryKey; import protocol.swg.ChatFriendsListUpdate; import protocol.swg.ChatOnChangeFriendStatus; import protocol.swg.ChatOnGetFriendsList; +import protocol.swg.ChatRoomList; import protocol.swg.CmdSceneReady; import protocol.swg.CmdStartScene; import protocol.swg.HeartBeatMessage; @@ -168,9 +169,9 @@ public class ObjectService implements INetworkDispatch { object.getContainerInfo(object.getTemplate()); } - }); + }); } - + cursor.close(); } public void loadServerTemplates() { @@ -661,6 +662,8 @@ public class ObjectService implements INetworkDispatch { core.simulationService.handleZoneIn(client); creature.makeAware(creature); + ChatRoomList chatRooms = new ChatRoomList(core.chatService.getChatRooms()); + creature.getClient().getSession().write(chatRooms.serialize()); //ChatOnGetFriendsList friendsListMessage = new ChatOnGetFriendsList(ghost); //client.getSession().write(friendsListMessage.serialize());