diff --git a/scripts/commands/auction.py b/scripts/commands/auction.py index dc63c8bc..fe744e57 100644 --- a/scripts/commands/auction.py +++ b/scripts/commands/auction.py @@ -1,10 +1,11 @@ -from main import NGECore import sys def setup(): return def run(core, actor, target, commandString): - room = core.chatService.getChatRoomByAddress('SWG.' + NGECore.getInstance().getGalaxyName() + '.' + 'Auction') - core.chatService.sendChatRoomMessage(actor, room.getRoomId(), 0, commandString) + room = core.chatService.getChatRoomByAddress('SWG.' + core.getGalaxyName() + '.' + 'Auction') + + if actor.getSlottedObject('ghost').isMemberOfChannel(room.getRoomId()): + core.chatService.sendChatRoomMessage(actor, room.getRoomId(), 0, commandString) return \ No newline at end of file diff --git a/src/protocol/swg/chat/ChatEnterRoomById.java b/src/protocol/swg/chat/ChatEnterRoomById.java index b6715b09..2e2ec8e5 100644 --- a/src/protocol/swg/chat/ChatEnterRoomById.java +++ b/src/protocol/swg/chat/ChatEnterRoomById.java @@ -29,6 +29,7 @@ public class ChatEnterRoomById extends SWGMessage { private int roomId; private int requestId; + private String roomName; public ChatEnterRoomById() { } @@ -39,7 +40,7 @@ public class ChatEnterRoomById extends SWGMessage { this.requestId = data.getInt(); this.roomId = data.getInt(); - // getAsciiString(data); // name of the room but don't need it since we have id. + this.roomName = getAsciiString(data); } @Override @@ -54,5 +55,8 @@ public class ChatEnterRoomById extends SWGMessage { public int getRoomId() { return roomId; } - + + public String getRoomname() { + return roomName; + } } diff --git a/src/protocol/swg/chat/ChatOnLeaveRoom.java b/src/protocol/swg/chat/ChatOnLeaveRoom.java new file mode 100644 index 00000000..1fecfe5f --- /dev/null +++ b/src/protocol/swg/chat/ChatOnLeaveRoom.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * 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.chat; + +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.SWGMessage; +import resources.common.StringUtilities; + +public class ChatOnLeaveRoom extends SWGMessage { + + private String server; + private String character; + private String channelAddress; + private int errorId; + private int channelId; + private int requestId; + + public ChatOnLeaveRoom() { } + + public ChatOnLeaveRoom(String server, String character) { + this.server = server; + this.character = character; + this.errorId = 0; + this.requestId = 0; + } + + @Override + public void deserialize(IoBuffer data) { + data.getShort(); + data.getInt(); + getAsciiString(data); + getAsciiString(data); + character = getAsciiString(data); + channelAddress = getAsciiString(data); + } + + @Override + public IoBuffer serialize() { + IoBuffer buffer = IoBuffer.allocate(28 + server.length() + character.length()).order(ByteOrder.LITTLE_ENDIAN); + + buffer.putShort((short) 5); + buffer.putInt(0x60B5098B); + + buffer.put(getAsciiString("SWG")); + buffer.put(getAsciiString(server)); + buffer.put(getAsciiString(character)); + + buffer.putInt(errorId); + buffer.putInt(channelId); + buffer.putInt(requestId); + + return buffer.flip(); + } + + public String getServer() { + return server; + } + + public void setServer(String server) { + this.server = server; + } + + public String getCharacter() { + return character; + } + + public void setCharacter(String character) { + this.character = character; + } + + public String getChannelAddress() { + return channelAddress; + } + + public void setChannelAddress(String channelAddress) { + this.channelAddress = channelAddress; + } + + public int getErrorId() { + return errorId; + } + + public void setErrorId(int errorId) { + this.errorId = errorId; + } + + public int getChannelId() { + return channelId; + } + + public void setChannelId(int channelId) { + this.channelId = channelId; + } + + public int getRequestId() { + return requestId; + } + + public void setRequestId(int requestId) { + this.requestId = requestId; + } + +} diff --git a/src/protocol/swg/chat/ChatQueryRoomResults.java b/src/protocol/swg/chat/ChatQueryRoom.java similarity index 82% rename from src/protocol/swg/chat/ChatQueryRoomResults.java rename to src/protocol/swg/chat/ChatQueryRoom.java index 530438ca..25e94d27 100644 --- a/src/protocol/swg/chat/ChatQueryRoomResults.java +++ b/src/protocol/swg/chat/ChatQueryRoom.java @@ -31,25 +31,32 @@ import org.apache.mina.core.buffer.IoBuffer; import protocol.swg.SWGMessage; import services.chat.ChatRoom; -public class ChatQueryRoomResults extends SWGMessage { +public class ChatQueryRoom extends SWGMessage { private ChatRoom room; + private String roomAddress; private int requestId; - public ChatQueryRoomResults(ChatRoom room, int requestId) { + public ChatQueryRoom() { } + public ChatQueryRoom(ChatRoom room, int requestId) { this.room = room; this.requestId = requestId; } @Override public void deserialize(IoBuffer data) { + data.getShort(); + data.getInt(); + requestId = data.getInt(); + roomAddress = getAsciiString(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) 7); buffer.putInt(0xC4DE864E); @@ -108,5 +115,16 @@ public class ChatQueryRoomResults extends SWGMessage { buffer.putInt(0); // user list return buffer.flip(); } - + public String getRoomAddress() { + return roomAddress; + } + public void setRoomAddress(String roomAddress) { + this.roomAddress = roomAddress; + } + public int getRequestId() { + return requestId; + } + public void setRequestId(int requestId) { + this.requestId = requestId; + } } diff --git a/src/resources/common/Opcodes.java b/src/resources/common/Opcodes.java index 1d0ec6d5..8a8cc6d8 100644 --- a/src/resources/common/Opcodes.java +++ b/src/resources/common/Opcodes.java @@ -27,6 +27,7 @@ public class Opcodes { public static int AuctionQueryHeadersMessage = CRC.StringtoCRC("AuctionQueryHeadersMessage"); public static int CreateImmediateAuctionMessage = CRC.StringtoCRC("CreateImmediateAuctionMessage"); + public static int ChatLeaveRoom = 0x493E3FFA; public static int ChatEnterRoomById = CRC.StringtoCRC("ChatEnterRoomById"); public static int ChatSendToRoom = CRC.StringtoCRC("ChatSendToRoom"); public static int ChatDeletePersistentMessage = 0x8F251641; diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java index 853e1d9a..a24ca702 100644 --- a/src/resources/objects/player/PlayerObject.java +++ b/src/resources/objects/player/PlayerObject.java @@ -879,6 +879,11 @@ public class PlayerObject extends IntangibleObject { } public boolean isMemberOfChannel(int roomId) { - return chatChannels.contains(roomId); + if (chatChannels.contains(roomId)) { + System.out.println("Member of the channel!"); + return true; + } + System.out.println("Not a Member of the channel!"); + return false; } } diff --git a/src/services/ConnectionService.java b/src/services/ConnectionService.java index fd2d475a..ff79d72c 100644 --- a/src/services/ConnectionService.java +++ b/src/services/ConnectionService.java @@ -57,6 +57,7 @@ import resources.common.collidables.AbstractCollidable; import resources.datatables.PlayerFlags; import resources.objects.creature.CreatureObject; import resources.objects.player.PlayerObject; +import services.chat.ChatRoom; @SuppressWarnings("unused") @@ -239,6 +240,14 @@ public class ConnectionService implements INetworkDispatch { } core.chatService.playerStatusChange(objectShortName, (byte) 0); + + for (Integer roomId : ghost.getJoinedChatChannels()) { + ChatRoom room = core.chatService.getChatRoom(roomId.intValue()); + + if (room != null) { core.chatService.leaveChatRoom(object, roomId.intValue()); } + // work-around for any channels that may have been deleted, or only spawn on server startup, that were added to the joined channels + else { ghost.removeChannel(roomId); } + } } long parentId = object.getParentId(); @@ -260,6 +269,7 @@ public class ConnectionService implements INetworkDispatch { observerClient.getParent().makeUnaware(object); } }*/ + ghost.toggleFlag(PlayerFlags.LD); object.setPerformanceListenee(null); diff --git a/src/services/chat/ChatService.java b/src/services/chat/ChatService.java index 32606e64..fbdf4cf6 100644 --- a/src/services/chat/ChatService.java +++ b/src/services/chat/ChatService.java @@ -60,11 +60,13 @@ import protocol.swg.chat.ChatInstantMessagetoClient; import protocol.swg.chat.ChatOnAddFriend; import protocol.swg.chat.ChatOnChangeFriendStatus; import protocol.swg.chat.ChatOnEnteredRoom; +import protocol.swg.chat.ChatOnLeaveRoom; import protocol.swg.chat.ChatOnSendInstantMessage; import protocol.swg.chat.ChatOnSendPersistentMessage; import protocol.swg.chat.ChatOnSendRoomMessage; import protocol.swg.chat.ChatPersistentMessageToClient; import protocol.swg.chat.ChatPersistentMessageToServer; +import protocol.swg.chat.ChatQueryRoom; import protocol.swg.chat.ChatRequestPersistentMessage; import protocol.swg.chat.ChatRoomList; import protocol.swg.chat.ChatRoomMessage; @@ -411,8 +413,6 @@ public class ChatService implements INetworkDispatch { }); swgOpcodes.put(Opcodes.ChatQueryRoom, (session, data) -> { - /*data.order(ByteOrder.LITTLE_ENDIAN); - //StringUtilities.printBytes(data.array()); Client client = core.getClient(session); if(client == null) @@ -421,7 +421,20 @@ public class ChatService implements INetworkDispatch { SWGObject obj = client.getParent(); if (obj == null) - return;*/ + return; + + data.order(ByteOrder.LITTLE_ENDIAN); + data.position(0); + ChatQueryRoom request = new ChatQueryRoom(); + request.deserialize(data); + + ChatRoom room = getChatRoomByAddress(request.getRoomAddress()); + + if (room == null) + return; + + ChatQueryRoom response = new ChatQueryRoom(room, request.getRequestId()); + obj.getClient().getSession().write(response.serialize()); }); swgOpcodes.put(Opcodes.ChatSendToRoom, (session, data) -> { @@ -440,8 +453,9 @@ public class ChatService implements INetworkDispatch { data.position(0); ChatSendToRoom sentPacket = new ChatSendToRoom(); sentPacket.deserialize(data); - - sendChatRoomMessage((CreatureObject) obj, sentPacket.getRoomId(), sentPacket.getMsgId(), sentPacket.getMessage()); + + if (((PlayerObject) obj.getSlottedObject("ghost")).isMemberOfChannel(sentPacket.getRoomId())) + sendChatRoomMessage((CreatureObject) obj, sentPacket.getRoomId(), sentPacket.getMsgId(), sentPacket.getMessage()); }); @@ -461,7 +475,34 @@ public class ChatService implements INetworkDispatch { ChatEnterRoomById sentPacket = new ChatEnterRoomById(); sentPacket.deserialize(data); - joinChatRoom(obj.getCustomName(), sentPacket.getRoomId()); + if(joinChatRoom(obj.getCustomName(), sentPacket.getRoomId()) && !sentPacket.getRoomname().equals("SWG." + core.getGalaxyName() + "." + obj.getPlanet().name + ".Planet")) { + PlayerObject player = (PlayerObject) obj.getSlottedObject("ghost"); + + if (player != null) + player.addChannel(sentPacket.getRoomId()); + } + }); + + swgOpcodes.put(Opcodes.ChatLeaveRoom, (session, data) -> { + Client client = core.getClient(session); + + if(client == null) + return; + + SWGObject obj = client.getParent(); + + if (obj == null) + return; + + data.order(ByteOrder.LITTLE_ENDIAN); + data.position(0); + + ChatOnLeaveRoom sentPacket = new ChatOnLeaveRoom(); + sentPacket.deserialize(data); + + ChatRoom room = getChatRoomByAddress(sentPacket.getChannelAddress()); + + leaveChatRoom((CreatureObject) obj, room.getRoomId()); }); } @@ -758,7 +799,7 @@ public class ChatService implements INetworkDispatch { createChatRoom("", "group", "system", false); createChatRoom("", "guild", "system", false); - createChatRoom("", "Auction", "system", true); + createChatRoom("Auction chat for this galaxy", "Auction", "system", true); createChatRoom("public chat for the whole galaxy, cannot create rooms here", "Galaxy", "system", true); createChatRoom("Bounty Hunter chat for this galaxy", "BountyHunter", "system", true); @@ -871,8 +912,7 @@ public class ChatService implements INetworkDispatch { if (room == null) return false; if (!room.hasUser(user.toLowerCase())) { - room.addUser(user.toLowerCase()); - + if (!room.isVisible() || resendList) { CreatureObject creo = (CreatureObject) getObjectByFirstName(user); if (creo != null) { @@ -887,6 +927,15 @@ public class ChatService implements INetworkDispatch { return false; player.getClient().getSession().write(enter.serialize()); + + for (String roomUser : room.getUserList()) { + SWGObject roomPlayer = getObjectByFirstName(roomUser); + + if (roomPlayer != null && roomPlayer.getClient() != null && roomPlayer.getClient().getSession() != null) + roomPlayer.getClient().getSession().write(enter.serialize()); + } + + room.addUser(user.toLowerCase()); return true; } return false; @@ -909,15 +958,15 @@ public class ChatService implements INetworkDispatch { ChatOnEnteredRoom leaveRoom = new ChatOnEnteredRoom(playerName, 0, roomId, false); player.getClient().getSession().write(leaveRoom.serialize()); - - if (room.getUserList().contains(player)) - room.getUserList().remove(player); + + room.getUserList().remove(playerName); room.getUserList().forEach(user -> { SWGObject roomPlayer = getObjectByFirstName(user); - if (roomPlayer != null && roomPlayer.getClient() != null && roomPlayer.getClient().getSession() != null) + if (roomPlayer != null && roomPlayer.getClient() != null && roomPlayer.getClient().getSession() != null) { roomPlayer.getClient().getSession().write(leaveRoom.serialize()); + } }); } diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 52e9f6c5..77314980 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -122,6 +122,7 @@ import resources.objects.tool.SurveyTool; import resources.objects.waypoint.WaypointObject; import resources.objects.weapon.WeaponObject; import services.bazaar.AuctionItem; +import services.chat.ChatRoom; @SuppressWarnings("unused") @@ -923,6 +924,14 @@ public class ObjectService implements INetworkDispatch { } } } + + for (Integer roomId : ghost.getJoinedChatChannels()) { + ChatRoom room = core.chatService.getChatRoom(roomId); + + if (room != null) { core.chatService.joinChatRoom(objectShortName, roomId); } + // work-around for any channels that may have been deleted, or only spawn on server startup, that were added to the joined channels + else { ghost.removeChannel(roomId); } + } } if(!core.getConfig().getString("MOTD").equals(""))